curl --request POST \
--url http://localhost:8080/api/v1/tap \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"name": "<string>",
"description": "<string>",
"targetPipeline": "<string>",
"scriptPath": "<string>",
"scriptRepoPath": "<string>",
"scriptCommitSha": "<string>",
"endpointUrl": "<string>",
"source": "<string>",
"packages": [
"<string>"
],
"secretName": "<string>",
"cronExpression": "<string>",
"enabled": true,
"tapType": "structured",
"lastRunTime": "<string>",
"lastRunRecordCount": 123,
"lastRunError": "<string>",
"lastRunColumns": [
"<string>"
],
"lastTestRunStatus": "<string>",
"lastTestRunTime": "<string>",
"lastTestRunRecordCount": 123,
"lastTestRunError": "<string>",
"lastTestRunDataType": "<string>",
"lastTestRunColumns": [
"<string>"
],
"dependsOn": [
"<string>"
],
"createdAt": "<string>",
"updatedAt": "<string>"
}
'import requests
url = "http://localhost:8080/api/v1/tap"
payload = {
"name": "<string>",
"description": "<string>",
"targetPipeline": "<string>",
"scriptPath": "<string>",
"scriptRepoPath": "<string>",
"scriptCommitSha": "<string>",
"endpointUrl": "<string>",
"source": "<string>",
"packages": ["<string>"],
"secretName": "<string>",
"cronExpression": "<string>",
"enabled": True,
"tapType": "structured",
"lastRunTime": "<string>",
"lastRunRecordCount": 123,
"lastRunError": "<string>",
"lastRunColumns": ["<string>"],
"lastTestRunStatus": "<string>",
"lastTestRunTime": "<string>",
"lastTestRunRecordCount": 123,
"lastTestRunError": "<string>",
"lastTestRunDataType": "<string>",
"lastTestRunColumns": ["<string>"],
"dependsOn": ["<string>"],
"createdAt": "<string>",
"updatedAt": "<string>"
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: '<string>',
description: '<string>',
targetPipeline: '<string>',
scriptPath: '<string>',
scriptRepoPath: '<string>',
scriptCommitSha: '<string>',
endpointUrl: '<string>',
source: '<string>',
packages: ['<string>'],
secretName: '<string>',
cronExpression: '<string>',
enabled: true,
tapType: 'structured',
lastRunTime: '<string>',
lastRunRecordCount: 123,
lastRunError: '<string>',
lastRunColumns: ['<string>'],
lastTestRunStatus: '<string>',
lastTestRunTime: '<string>',
lastTestRunRecordCount: 123,
lastTestRunError: '<string>',
lastTestRunDataType: '<string>',
lastTestRunColumns: ['<string>'],
dependsOn: ['<string>'],
createdAt: '<string>',
updatedAt: '<string>'
})
};
fetch('http://localhost:8080/api/v1/tap', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_PORT => "8080",
CURLOPT_URL => "http://localhost:8080/api/v1/tap",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'name' => '<string>',
'description' => '<string>',
'targetPipeline' => '<string>',
'scriptPath' => '<string>',
'scriptRepoPath' => '<string>',
'scriptCommitSha' => '<string>',
'endpointUrl' => '<string>',
'source' => '<string>',
'packages' => [
'<string>'
],
'secretName' => '<string>',
'cronExpression' => '<string>',
'enabled' => true,
'tapType' => 'structured',
'lastRunTime' => '<string>',
'lastRunRecordCount' => 123,
'lastRunError' => '<string>',
'lastRunColumns' => [
'<string>'
],
'lastTestRunStatus' => '<string>',
'lastTestRunTime' => '<string>',
'lastTestRunRecordCount' => 123,
'lastTestRunError' => '<string>',
'lastTestRunDataType' => '<string>',
'lastTestRunColumns' => [
'<string>'
],
'dependsOn' => [
'<string>'
],
'createdAt' => '<string>',
'updatedAt' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "http://localhost:8080/api/v1/tap"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"description\": \"<string>\",\n \"targetPipeline\": \"<string>\",\n \"scriptPath\": \"<string>\",\n \"scriptRepoPath\": \"<string>\",\n \"scriptCommitSha\": \"<string>\",\n \"endpointUrl\": \"<string>\",\n \"source\": \"<string>\",\n \"packages\": [\n \"<string>\"\n ],\n \"secretName\": \"<string>\",\n \"cronExpression\": \"<string>\",\n \"enabled\": true,\n \"tapType\": \"structured\",\n \"lastRunTime\": \"<string>\",\n \"lastRunRecordCount\": 123,\n \"lastRunError\": \"<string>\",\n \"lastRunColumns\": [\n \"<string>\"\n ],\n \"lastTestRunStatus\": \"<string>\",\n \"lastTestRunTime\": \"<string>\",\n \"lastTestRunRecordCount\": 123,\n \"lastTestRunError\": \"<string>\",\n \"lastTestRunDataType\": \"<string>\",\n \"lastTestRunColumns\": [\n \"<string>\"\n ],\n \"dependsOn\": [\n \"<string>\"\n ],\n \"createdAt\": \"<string>\",\n \"updatedAt\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("http://localhost:8080/api/v1/tap")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"description\": \"<string>\",\n \"targetPipeline\": \"<string>\",\n \"scriptPath\": \"<string>\",\n \"scriptRepoPath\": \"<string>\",\n \"scriptCommitSha\": \"<string>\",\n \"endpointUrl\": \"<string>\",\n \"source\": \"<string>\",\n \"packages\": [\n \"<string>\"\n ],\n \"secretName\": \"<string>\",\n \"cronExpression\": \"<string>\",\n \"enabled\": true,\n \"tapType\": \"structured\",\n \"lastRunTime\": \"<string>\",\n \"lastRunRecordCount\": 123,\n \"lastRunError\": \"<string>\",\n \"lastRunColumns\": [\n \"<string>\"\n ],\n \"lastTestRunStatus\": \"<string>\",\n \"lastTestRunTime\": \"<string>\",\n \"lastTestRunRecordCount\": 123,\n \"lastTestRunError\": \"<string>\",\n \"lastTestRunDataType\": \"<string>\",\n \"lastTestRunColumns\": [\n \"<string>\"\n ],\n \"dependsOn\": [\n \"<string>\"\n ],\n \"createdAt\": \"<string>\",\n \"updatedAt\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("http://localhost:8080/api/v1/tap")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"<string>\",\n \"description\": \"<string>\",\n \"targetPipeline\": \"<string>\",\n \"scriptPath\": \"<string>\",\n \"scriptRepoPath\": \"<string>\",\n \"scriptCommitSha\": \"<string>\",\n \"endpointUrl\": \"<string>\",\n \"source\": \"<string>\",\n \"packages\": [\n \"<string>\"\n ],\n \"secretName\": \"<string>\",\n \"cronExpression\": \"<string>\",\n \"enabled\": true,\n \"tapType\": \"structured\",\n \"lastRunTime\": \"<string>\",\n \"lastRunRecordCount\": 123,\n \"lastRunError\": \"<string>\",\n \"lastRunColumns\": [\n \"<string>\"\n ],\n \"lastTestRunStatus\": \"<string>\",\n \"lastTestRunTime\": \"<string>\",\n \"lastTestRunRecordCount\": 123,\n \"lastTestRunError\": \"<string>\",\n \"lastTestRunDataType\": \"<string>\",\n \"lastTestRunColumns\": [\n \"<string>\"\n ],\n \"dependsOn\": [\n \"<string>\"\n ],\n \"createdAt\": \"<string>\",\n \"updatedAt\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"name": "<string>",
"description": "<string>",
"targetPipeline": "<string>",
"scriptPath": "<string>",
"scriptStorage": "minio",
"scriptRepoPath": "<string>",
"scriptCommitSha": "<string>",
"scriptKind": "python",
"endpointUrl": "<string>",
"source": "<string>",
"packages": [
"<string>"
],
"secretName": "<string>",
"cronExpression": "<string>",
"enabled": true,
"tapType": "structured",
"lastRunStatus": "success",
"lastRunTime": "<string>",
"lastRunRecordCount": 123,
"lastRunError": "<string>",
"lastRunDataType": "csv",
"lastRunColumns": [
"<string>"
],
"lastTestRunStatus": "<string>",
"lastTestRunTime": "<string>",
"lastTestRunRecordCount": 123,
"lastTestRunError": "<string>",
"lastTestRunDataType": "<string>",
"lastTestRunScriptId": "<string>",
"lastTestRunColumns": [
"<string>"
],
"dependsOn": [
"<string>"
],
"inferredDependsOn": [
"<string>"
],
"createdAt": "<string>",
"updatedAt": "<string>"
}Create or update a tap
Creates a new tap or updates an existing tap with the same name.
Cron validation: cronExpression is a Quartz expression of 6 fields
(seconds minutes hours day-of-month month day-of-week) plus an optional
year. A malformed expression — including the 5-field Unix form — is
refused with 400 and nothing is persisted; for a 5-field input the error
carries the 6-field equivalent to resend. A blank cron means unscheduled.
Test-before-cron: a cronExpression may only be saved once the exact script
(or HTTP endpoint) that will run on it has passed a mode=test run. Setting or
changing a cron on an untested script, or changing the script under an existing
cron, is refused with 409 and nothing is persisted. Remedy: save without
cronExpression, run POST /api/v1/tap/run with mode=test, then save again
with the cron.
curl --request POST \
--url http://localhost:8080/api/v1/tap \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"name": "<string>",
"description": "<string>",
"targetPipeline": "<string>",
"scriptPath": "<string>",
"scriptRepoPath": "<string>",
"scriptCommitSha": "<string>",
"endpointUrl": "<string>",
"source": "<string>",
"packages": [
"<string>"
],
"secretName": "<string>",
"cronExpression": "<string>",
"enabled": true,
"tapType": "structured",
"lastRunTime": "<string>",
"lastRunRecordCount": 123,
"lastRunError": "<string>",
"lastRunColumns": [
"<string>"
],
"lastTestRunStatus": "<string>",
"lastTestRunTime": "<string>",
"lastTestRunRecordCount": 123,
"lastTestRunError": "<string>",
"lastTestRunDataType": "<string>",
"lastTestRunColumns": [
"<string>"
],
"dependsOn": [
"<string>"
],
"createdAt": "<string>",
"updatedAt": "<string>"
}
'import requests
url = "http://localhost:8080/api/v1/tap"
payload = {
"name": "<string>",
"description": "<string>",
"targetPipeline": "<string>",
"scriptPath": "<string>",
"scriptRepoPath": "<string>",
"scriptCommitSha": "<string>",
"endpointUrl": "<string>",
"source": "<string>",
"packages": ["<string>"],
"secretName": "<string>",
"cronExpression": "<string>",
"enabled": True,
"tapType": "structured",
"lastRunTime": "<string>",
"lastRunRecordCount": 123,
"lastRunError": "<string>",
"lastRunColumns": ["<string>"],
"lastTestRunStatus": "<string>",
"lastTestRunTime": "<string>",
"lastTestRunRecordCount": 123,
"lastTestRunError": "<string>",
"lastTestRunDataType": "<string>",
"lastTestRunColumns": ["<string>"],
"dependsOn": ["<string>"],
"createdAt": "<string>",
"updatedAt": "<string>"
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: '<string>',
description: '<string>',
targetPipeline: '<string>',
scriptPath: '<string>',
scriptRepoPath: '<string>',
scriptCommitSha: '<string>',
endpointUrl: '<string>',
source: '<string>',
packages: ['<string>'],
secretName: '<string>',
cronExpression: '<string>',
enabled: true,
tapType: 'structured',
lastRunTime: '<string>',
lastRunRecordCount: 123,
lastRunError: '<string>',
lastRunColumns: ['<string>'],
lastTestRunStatus: '<string>',
lastTestRunTime: '<string>',
lastTestRunRecordCount: 123,
lastTestRunError: '<string>',
lastTestRunDataType: '<string>',
lastTestRunColumns: ['<string>'],
dependsOn: ['<string>'],
createdAt: '<string>',
updatedAt: '<string>'
})
};
fetch('http://localhost:8080/api/v1/tap', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_PORT => "8080",
CURLOPT_URL => "http://localhost:8080/api/v1/tap",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'name' => '<string>',
'description' => '<string>',
'targetPipeline' => '<string>',
'scriptPath' => '<string>',
'scriptRepoPath' => '<string>',
'scriptCommitSha' => '<string>',
'endpointUrl' => '<string>',
'source' => '<string>',
'packages' => [
'<string>'
],
'secretName' => '<string>',
'cronExpression' => '<string>',
'enabled' => true,
'tapType' => 'structured',
'lastRunTime' => '<string>',
'lastRunRecordCount' => 123,
'lastRunError' => '<string>',
'lastRunColumns' => [
'<string>'
],
'lastTestRunStatus' => '<string>',
'lastTestRunTime' => '<string>',
'lastTestRunRecordCount' => 123,
'lastTestRunError' => '<string>',
'lastTestRunDataType' => '<string>',
'lastTestRunColumns' => [
'<string>'
],
'dependsOn' => [
'<string>'
],
'createdAt' => '<string>',
'updatedAt' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "http://localhost:8080/api/v1/tap"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"description\": \"<string>\",\n \"targetPipeline\": \"<string>\",\n \"scriptPath\": \"<string>\",\n \"scriptRepoPath\": \"<string>\",\n \"scriptCommitSha\": \"<string>\",\n \"endpointUrl\": \"<string>\",\n \"source\": \"<string>\",\n \"packages\": [\n \"<string>\"\n ],\n \"secretName\": \"<string>\",\n \"cronExpression\": \"<string>\",\n \"enabled\": true,\n \"tapType\": \"structured\",\n \"lastRunTime\": \"<string>\",\n \"lastRunRecordCount\": 123,\n \"lastRunError\": \"<string>\",\n \"lastRunColumns\": [\n \"<string>\"\n ],\n \"lastTestRunStatus\": \"<string>\",\n \"lastTestRunTime\": \"<string>\",\n \"lastTestRunRecordCount\": 123,\n \"lastTestRunError\": \"<string>\",\n \"lastTestRunDataType\": \"<string>\",\n \"lastTestRunColumns\": [\n \"<string>\"\n ],\n \"dependsOn\": [\n \"<string>\"\n ],\n \"createdAt\": \"<string>\",\n \"updatedAt\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("http://localhost:8080/api/v1/tap")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"description\": \"<string>\",\n \"targetPipeline\": \"<string>\",\n \"scriptPath\": \"<string>\",\n \"scriptRepoPath\": \"<string>\",\n \"scriptCommitSha\": \"<string>\",\n \"endpointUrl\": \"<string>\",\n \"source\": \"<string>\",\n \"packages\": [\n \"<string>\"\n ],\n \"secretName\": \"<string>\",\n \"cronExpression\": \"<string>\",\n \"enabled\": true,\n \"tapType\": \"structured\",\n \"lastRunTime\": \"<string>\",\n \"lastRunRecordCount\": 123,\n \"lastRunError\": \"<string>\",\n \"lastRunColumns\": [\n \"<string>\"\n ],\n \"lastTestRunStatus\": \"<string>\",\n \"lastTestRunTime\": \"<string>\",\n \"lastTestRunRecordCount\": 123,\n \"lastTestRunError\": \"<string>\",\n \"lastTestRunDataType\": \"<string>\",\n \"lastTestRunColumns\": [\n \"<string>\"\n ],\n \"dependsOn\": [\n \"<string>\"\n ],\n \"createdAt\": \"<string>\",\n \"updatedAt\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("http://localhost:8080/api/v1/tap")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"<string>\",\n \"description\": \"<string>\",\n \"targetPipeline\": \"<string>\",\n \"scriptPath\": \"<string>\",\n \"scriptRepoPath\": \"<string>\",\n \"scriptCommitSha\": \"<string>\",\n \"endpointUrl\": \"<string>\",\n \"source\": \"<string>\",\n \"packages\": [\n \"<string>\"\n ],\n \"secretName\": \"<string>\",\n \"cronExpression\": \"<string>\",\n \"enabled\": true,\n \"tapType\": \"structured\",\n \"lastRunTime\": \"<string>\",\n \"lastRunRecordCount\": 123,\n \"lastRunError\": \"<string>\",\n \"lastRunColumns\": [\n \"<string>\"\n ],\n \"lastTestRunStatus\": \"<string>\",\n \"lastTestRunTime\": \"<string>\",\n \"lastTestRunRecordCount\": 123,\n \"lastTestRunError\": \"<string>\",\n \"lastTestRunDataType\": \"<string>\",\n \"lastTestRunColumns\": [\n \"<string>\"\n ],\n \"dependsOn\": [\n \"<string>\"\n ],\n \"createdAt\": \"<string>\",\n \"updatedAt\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"name": "<string>",
"description": "<string>",
"targetPipeline": "<string>",
"scriptPath": "<string>",
"scriptStorage": "minio",
"scriptRepoPath": "<string>",
"scriptCommitSha": "<string>",
"scriptKind": "python",
"endpointUrl": "<string>",
"source": "<string>",
"packages": [
"<string>"
],
"secretName": "<string>",
"cronExpression": "<string>",
"enabled": true,
"tapType": "structured",
"lastRunStatus": "success",
"lastRunTime": "<string>",
"lastRunRecordCount": 123,
"lastRunError": "<string>",
"lastRunDataType": "csv",
"lastRunColumns": [
"<string>"
],
"lastTestRunStatus": "<string>",
"lastTestRunTime": "<string>",
"lastTestRunRecordCount": 123,
"lastTestRunError": "<string>",
"lastTestRunDataType": "<string>",
"lastTestRunScriptId": "<string>",
"lastTestRunColumns": [
"<string>"
],
"dependsOn": [
"<string>"
],
"inferredDependsOn": [
"<string>"
],
"createdAt": "<string>",
"updatedAt": "<string>"
}Authorizations
Optional API key for authentication (enabled via application.yaml)
Body
Unique tap identifier
Plain-English instruction used to generate the script
Pipeline this tap feeds into (may be empty for unattached taps)
MinIO path of the generated Python script (built-in storage)
Script storage backend. Absent or minio = built-in object storage; github = the tenant's configured code repository.
minio, github Repo-relative script path when scriptStorage is github
Commit SHA the script is pinned to when scriptStorage is github; runs read exactly this commit
Tap implementation kind. Absent or python = a script the platform executes; http = a user-hosted endpoint speaking the tap HTTP contract (endpointUrl is authoritative; script/packages fields do not apply).
python, http For scriptKind http only — absolute http(s) URL Datris POSTs the run context to on each run
Declared source identity for lineage and provenance — a provider name or host (never credentials). Optional; when absent the platform derives it from the endpoint host (HTTP taps) or the host the script references most. On update, omitting the field keeps the stored value and an empty string clears it.
Extra pip packages required by the script
Name of the tap secret (Vault) injected as env vars at runtime
Quartz CRON expression for scheduled runs (omit for manual-only). Six fields — seconds minutes hours day-of-month month day-of-week — plus an optional year, e.g. 0 0 * * * ? (hourly). A 5-field Unix cron such as */1 * * * * is rejected with 400; the error quotes the 6-field equivalent.
structured (default) — the script returns records that flow into a structured pipeline destination. document — the script returns {uri, filename, content} dicts destined for a vector-store pipeline (unstructured source + qdrant/pgvector/weaviate/milvus/chroma destination). The server rejects a document tap pointed at an incompatible pipeline with HTTP 400. Document taps also use a per-URI ledger so each file is processed once across re-runs.
structured, document success, failure csv, json, xml, text, document Taps of the same catalog whose destination tables this tap reads, declared by the user.
When set (even [], meaning "none") it replaces inferredDependsOn. Omitted on an update:
the stored list is kept. Blank names are refused (400); repeated names are stored once. Each name must be another tap of the same catalog (400 otherwise)
and the list may not close a dependency cycle (409 with cycle). Orders and explains the
catalog's enable order only; never enforced on save, test, run or schedule.
Response
Saved tap configuration
Unique tap identifier
Plain-English instruction used to generate the script
Pipeline this tap feeds into (may be empty for unattached taps)
MinIO path of the generated Python script (built-in storage)
Script storage backend. Absent or minio = built-in object storage; github = the tenant's configured code repository.
minio, github Repo-relative script path when scriptStorage is github
Commit SHA the script is pinned to when scriptStorage is github; runs read exactly this commit
Tap implementation kind. Absent or python = a script the platform executes; http = a user-hosted endpoint speaking the tap HTTP contract (endpointUrl is authoritative; script/packages fields do not apply).
python, http For scriptKind http only — absolute http(s) URL Datris POSTs the run context to on each run
Declared source identity for lineage and provenance — a provider name or host (never credentials). Optional; when absent the platform derives it from the endpoint host (HTTP taps) or the host the script references most. On update, omitting the field keeps the stored value and an empty string clears it.
Extra pip packages required by the script
Name of the tap secret (Vault) injected as env vars at runtime
Quartz CRON expression for scheduled runs (omit for manual-only). Six fields — seconds minutes hours day-of-month month day-of-week — plus an optional year, e.g. 0 0 * * * ? (hourly). A 5-field Unix cron such as */1 * * * * is rejected with 400; the error quotes the 6-field equivalent.
structured (default) — the script returns records that flow into a structured pipeline destination. document — the script returns {uri, filename, content} dicts destined for a vector-store pipeline (unstructured source + qdrant/pgvector/weaviate/milvus/chroma destination). The server rejects a document tap pointed at an incompatible pipeline with HTTP 400. Document taps also use a per-URI ledger so each file is processed once across re-runs.
structured, document success, failure csv, json, xml, text, document Server-stamped identity of the exact script (or endpoint) that last passed a
mode=test run (gh:<sha>, http:<url>, or sha256 of the stored script).
Compared against the saved script when a cronExpression is set. Ignored in
request bodies; null on pre-existing taps.
Taps of the same catalog whose destination tables this tap reads, declared by the user.
When set (even [], meaning "none") it replaces inferredDependsOn. Omitted on an update:
the stored list is kept. Blank names are refused (400); repeated names are stored once. Each name must be another tap of the same catalog (400 otherwise)
and the list may not close a dependency cycle (409 with cycle). Orders and explains the
catalog's enable order only; never enforced on save, test, run or schedule.
Server-stamped from the stored script: same-catalog taps whose pipelines' Postgres or Mongo
tables the script reads through the query or metadata endpoints. Ignored in request bodies.
[] when the script was analysed and reads no other tap; null when not analysed yet (no
script, or a tap saved before dependency tracking: GET /api/v1/tap and the catalog
enable order analyse such a tap once and store the result).
