curl --request POST \
--url http://localhost:8080/api/v1/tap/test \
--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>"
],
"createdAt": "<string>",
"updatedAt": "<string>"
}
'import requests
url = "http://localhost:8080/api/v1/tap/test"
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>"],
"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>'],
createdAt: '<string>',
updatedAt: '<string>'
})
};
fetch('http://localhost:8080/api/v1/tap/test', 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/test",
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>'
],
'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/test"
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 \"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/test")
.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 \"createdAt\": \"<string>\",\n \"updatedAt\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("http://localhost:8080/api/v1/tap/test")
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 \"createdAt\": \"<string>\",\n \"updatedAt\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"records": [
{}
],
"recordCount": 123,
"dataType": "<string>",
"columns": [
"<string>"
],
"logs": "<string>",
"error": "<string>",
"aiExplanation": "<string>"
}Test a tap
Executes the tap script without sending data to a pipeline. Returns results, logs, and an AI-generated diagnosis if errors or zero records are detected.
curl --request POST \
--url http://localhost:8080/api/v1/tap/test \
--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>"
],
"createdAt": "<string>",
"updatedAt": "<string>"
}
'import requests
url = "http://localhost:8080/api/v1/tap/test"
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>"],
"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>'],
createdAt: '<string>',
updatedAt: '<string>'
})
};
fetch('http://localhost:8080/api/v1/tap/test', 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/test",
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>'
],
'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/test"
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 \"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/test")
.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 \"createdAt\": \"<string>\",\n \"updatedAt\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("http://localhost:8080/api/v1/tap/test")
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 \"createdAt\": \"<string>\",\n \"updatedAt\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"records": [
{}
],
"recordCount": 123,
"dataType": "<string>",
"columns": [
"<string>"
],
"logs": "<string>",
"error": "<string>",
"aiExplanation": "<string>"
}Authorizations
Optional API key for authentication (enabled via application.yaml)
Query Parameters
When > 0, injects DATRIS_TAP_TEST_LIMIT= into the script process so well-behaved scripts cap their reads.
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)
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 