curl --request POST \
--url https://api.zespan.com/v1/ingest \
--header 'Content-Type: application/x-ndjson' \
--header 'x-api-key: <api-key>' \
--data '{"trace_id":"3b1c...","span_id":"a91f...","name":"chat.completions","provider":"openai","model":"gpt-4o","operation":"chat.completions","input_tokens":812,"output_tokens":146,"latency_ms":1240,"status":"success","timestamp":"2026-07-05T12:00:00.000Z"}
{"trace_id":"3b1c...","span_id":"c72d...","parent_span_id":"a91f...","name":"vector.search","operation":"retrieval.query","latency_ms":54,"status":"success","timestamp":"2026-07-05T12:00:00.050Z"}
'import requests
url = "https://api.zespan.com/v1/ingest"
payload = "{\"trace_id\":\"3b1c...\",\"span_id\":\"a91f...\",\"name\":\"chat.completions\",\"provider\":\"openai\",\"model\":\"gpt-4o\",\"operation\":\"chat.completions\",\"input_tokens\":812,\"output_tokens\":146,\"latency_ms\":1240,\"status\":\"success\",\"timestamp\":\"2026-07-05T12:00:00.000Z\"}\n{\"trace_id\":\"3b1c...\",\"span_id\":\"c72d...\",\"parent_span_id\":\"a91f...\",\"name\":\"vector.search\",\"operation\":\"retrieval.query\",\"latency_ms\":54,\"status\":\"success\",\"timestamp\":\"2026-07-05T12:00:00.050Z\"}\n"
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/x-ndjson"
}
response = requests.post(url, data=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/x-ndjson'},
body: '{"trace_id":"3b1c...","span_id":"a91f...","name":"chat.completions","provider":"openai","model":"gpt-4o","operation":"chat.completions","input_tokens":812,"output_tokens":146,"latency_ms":1240,"status":"success","timestamp":"2026-07-05T12:00:00.000Z"}\n{"trace_id":"3b1c...","span_id":"c72d...","parent_span_id":"a91f...","name":"vector.search","operation":"retrieval.query","latency_ms":54,"status":"success","timestamp":"2026-07-05T12:00:00.050Z"}\n'
};
fetch('https://api.zespan.com/v1/ingest', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.zespan.com/v1/ingest",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "{\"trace_id\":\"3b1c...\",\"span_id\":\"a91f...\",\"name\":\"chat.completions\",\"provider\":\"openai\",\"model\":\"gpt-4o\",\"operation\":\"chat.completions\",\"input_tokens\":812,\"output_tokens\":146,\"latency_ms\":1240,\"status\":\"success\",\"timestamp\":\"2026-07-05T12:00:00.000Z\"}\n{\"trace_id\":\"3b1c...\",\"span_id\":\"c72d...\",\"parent_span_id\":\"a91f...\",\"name\":\"vector.search\",\"operation\":\"retrieval.query\",\"latency_ms\":54,\"status\":\"success\",\"timestamp\":\"2026-07-05T12:00:00.050Z\"}\n",
CURLOPT_HTTPHEADER => [
"Content-Type: application/x-ndjson",
"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 := "https://api.zespan.com/v1/ingest"
payload := strings.NewReader("{\"trace_id\":\"3b1c...\",\"span_id\":\"a91f...\",\"name\":\"chat.completions\",\"provider\":\"openai\",\"model\":\"gpt-4o\",\"operation\":\"chat.completions\",\"input_tokens\":812,\"output_tokens\":146,\"latency_ms\":1240,\"status\":\"success\",\"timestamp\":\"2026-07-05T12:00:00.000Z\"}\n{\"trace_id\":\"3b1c...\",\"span_id\":\"c72d...\",\"parent_span_id\":\"a91f...\",\"name\":\"vector.search\",\"operation\":\"retrieval.query\",\"latency_ms\":54,\"status\":\"success\",\"timestamp\":\"2026-07-05T12:00:00.050Z\"}\n")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/x-ndjson")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.zespan.com/v1/ingest")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/x-ndjson")
.body("{\"trace_id\":\"3b1c...\",\"span_id\":\"a91f...\",\"name\":\"chat.completions\",\"provider\":\"openai\",\"model\":\"gpt-4o\",\"operation\":\"chat.completions\",\"input_tokens\":812,\"output_tokens\":146,\"latency_ms\":1240,\"status\":\"success\",\"timestamp\":\"2026-07-05T12:00:00.000Z\"}\n{\"trace_id\":\"3b1c...\",\"span_id\":\"c72d...\",\"parent_span_id\":\"a91f...\",\"name\":\"vector.search\",\"operation\":\"retrieval.query\",\"latency_ms\":54,\"status\":\"success\",\"timestamp\":\"2026-07-05T12:00:00.050Z\"}\n")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.zespan.com/v1/ingest")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/x-ndjson'
request.body = "{\"trace_id\":\"3b1c...\",\"span_id\":\"a91f...\",\"name\":\"chat.completions\",\"provider\":\"openai\",\"model\":\"gpt-4o\",\"operation\":\"chat.completions\",\"input_tokens\":812,\"output_tokens\":146,\"latency_ms\":1240,\"status\":\"success\",\"timestamp\":\"2026-07-05T12:00:00.000Z\"}\n{\"trace_id\":\"3b1c...\",\"span_id\":\"c72d...\",\"parent_span_id\":\"a91f...\",\"name\":\"vector.search\",\"operation\":\"retrieval.query\",\"latency_ms\":54,\"status\":\"success\",\"timestamp\":\"2026-07-05T12:00:00.050Z\"}\n"
response = http.request(request)
puts response.read_body{
"accepted": 2,
"cv": 7,
"replayed": true
}{
"error": "Unauthorized",
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded",
"requestId": "5f0c9a4e-3b1d-4e7a-9c2f-8d6b1a0e7c34",
"details": "<unknown>"
}{
"error": "Unauthorized",
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded",
"requestId": "5f0c9a4e-3b1d-4e7a-9c2f-8d6b1a0e7c34",
"details": "<unknown>"
}{
"error": "Unauthorized",
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded",
"requestId": "5f0c9a4e-3b1d-4e7a-9c2f-8d6b1a0e7c34",
"details": "<unknown>"
}{
"error": "Unauthorized",
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded",
"requestId": "5f0c9a4e-3b1d-4e7a-9c2f-8d6b1a0e7c34",
"details": "<unknown>"
}{
"error": "Unauthorized",
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded",
"requestId": "5f0c9a4e-3b1d-4e7a-9c2f-8d6b1a0e7c34",
"details": "<unknown>"
}{
"error": "Unauthorized",
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded",
"requestId": "5f0c9a4e-3b1d-4e7a-9c2f-8d6b1a0e7c34",
"details": "<unknown>"
}{
"error": "Unauthorized",
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded",
"requestId": "5f0c9a4e-3b1d-4e7a-9c2f-8d6b1a0e7c34",
"details": "<unknown>"
}Ingest trace events
Ingest a batch of trace/span events. The request body is newline-delimited JSON (application/x-ndjson): one JSON event object per line. A maximum of 100 events per request and a 4 MiB body size limit (measured after decompression of a gzip body) apply. The SDKs send about 3.5 MB per request before gzip. Events are validated and queued asynchronously; invalid lines are skipped rather than failing the whole batch.
Authenticated with x-api-key. Rate limited to 300 requests/minute per project. Events count against your monthly quota only after the batch has been queued.
Send an Idempotency-Key header so a retried request is never ingested twice; the SDKs set it automatically. A key is remembered for 6 hours after its batch is accepted.
curl --request POST \
--url https://api.zespan.com/v1/ingest \
--header 'Content-Type: application/x-ndjson' \
--header 'x-api-key: <api-key>' \
--data '{"trace_id":"3b1c...","span_id":"a91f...","name":"chat.completions","provider":"openai","model":"gpt-4o","operation":"chat.completions","input_tokens":812,"output_tokens":146,"latency_ms":1240,"status":"success","timestamp":"2026-07-05T12:00:00.000Z"}
{"trace_id":"3b1c...","span_id":"c72d...","parent_span_id":"a91f...","name":"vector.search","operation":"retrieval.query","latency_ms":54,"status":"success","timestamp":"2026-07-05T12:00:00.050Z"}
'import requests
url = "https://api.zespan.com/v1/ingest"
payload = "{\"trace_id\":\"3b1c...\",\"span_id\":\"a91f...\",\"name\":\"chat.completions\",\"provider\":\"openai\",\"model\":\"gpt-4o\",\"operation\":\"chat.completions\",\"input_tokens\":812,\"output_tokens\":146,\"latency_ms\":1240,\"status\":\"success\",\"timestamp\":\"2026-07-05T12:00:00.000Z\"}\n{\"trace_id\":\"3b1c...\",\"span_id\":\"c72d...\",\"parent_span_id\":\"a91f...\",\"name\":\"vector.search\",\"operation\":\"retrieval.query\",\"latency_ms\":54,\"status\":\"success\",\"timestamp\":\"2026-07-05T12:00:00.050Z\"}\n"
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/x-ndjson"
}
response = requests.post(url, data=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/x-ndjson'},
body: '{"trace_id":"3b1c...","span_id":"a91f...","name":"chat.completions","provider":"openai","model":"gpt-4o","operation":"chat.completions","input_tokens":812,"output_tokens":146,"latency_ms":1240,"status":"success","timestamp":"2026-07-05T12:00:00.000Z"}\n{"trace_id":"3b1c...","span_id":"c72d...","parent_span_id":"a91f...","name":"vector.search","operation":"retrieval.query","latency_ms":54,"status":"success","timestamp":"2026-07-05T12:00:00.050Z"}\n'
};
fetch('https://api.zespan.com/v1/ingest', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.zespan.com/v1/ingest",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "{\"trace_id\":\"3b1c...\",\"span_id\":\"a91f...\",\"name\":\"chat.completions\",\"provider\":\"openai\",\"model\":\"gpt-4o\",\"operation\":\"chat.completions\",\"input_tokens\":812,\"output_tokens\":146,\"latency_ms\":1240,\"status\":\"success\",\"timestamp\":\"2026-07-05T12:00:00.000Z\"}\n{\"trace_id\":\"3b1c...\",\"span_id\":\"c72d...\",\"parent_span_id\":\"a91f...\",\"name\":\"vector.search\",\"operation\":\"retrieval.query\",\"latency_ms\":54,\"status\":\"success\",\"timestamp\":\"2026-07-05T12:00:00.050Z\"}\n",
CURLOPT_HTTPHEADER => [
"Content-Type: application/x-ndjson",
"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 := "https://api.zespan.com/v1/ingest"
payload := strings.NewReader("{\"trace_id\":\"3b1c...\",\"span_id\":\"a91f...\",\"name\":\"chat.completions\",\"provider\":\"openai\",\"model\":\"gpt-4o\",\"operation\":\"chat.completions\",\"input_tokens\":812,\"output_tokens\":146,\"latency_ms\":1240,\"status\":\"success\",\"timestamp\":\"2026-07-05T12:00:00.000Z\"}\n{\"trace_id\":\"3b1c...\",\"span_id\":\"c72d...\",\"parent_span_id\":\"a91f...\",\"name\":\"vector.search\",\"operation\":\"retrieval.query\",\"latency_ms\":54,\"status\":\"success\",\"timestamp\":\"2026-07-05T12:00:00.050Z\"}\n")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/x-ndjson")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.zespan.com/v1/ingest")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/x-ndjson")
.body("{\"trace_id\":\"3b1c...\",\"span_id\":\"a91f...\",\"name\":\"chat.completions\",\"provider\":\"openai\",\"model\":\"gpt-4o\",\"operation\":\"chat.completions\",\"input_tokens\":812,\"output_tokens\":146,\"latency_ms\":1240,\"status\":\"success\",\"timestamp\":\"2026-07-05T12:00:00.000Z\"}\n{\"trace_id\":\"3b1c...\",\"span_id\":\"c72d...\",\"parent_span_id\":\"a91f...\",\"name\":\"vector.search\",\"operation\":\"retrieval.query\",\"latency_ms\":54,\"status\":\"success\",\"timestamp\":\"2026-07-05T12:00:00.050Z\"}\n")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.zespan.com/v1/ingest")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/x-ndjson'
request.body = "{\"trace_id\":\"3b1c...\",\"span_id\":\"a91f...\",\"name\":\"chat.completions\",\"provider\":\"openai\",\"model\":\"gpt-4o\",\"operation\":\"chat.completions\",\"input_tokens\":812,\"output_tokens\":146,\"latency_ms\":1240,\"status\":\"success\",\"timestamp\":\"2026-07-05T12:00:00.000Z\"}\n{\"trace_id\":\"3b1c...\",\"span_id\":\"c72d...\",\"parent_span_id\":\"a91f...\",\"name\":\"vector.search\",\"operation\":\"retrieval.query\",\"latency_ms\":54,\"status\":\"success\",\"timestamp\":\"2026-07-05T12:00:00.050Z\"}\n"
response = http.request(request)
puts response.read_body{
"accepted": 2,
"cv": 7,
"replayed": true
}{
"error": "Unauthorized",
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded",
"requestId": "5f0c9a4e-3b1d-4e7a-9c2f-8d6b1a0e7c34",
"details": "<unknown>"
}{
"error": "Unauthorized",
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded",
"requestId": "5f0c9a4e-3b1d-4e7a-9c2f-8d6b1a0e7c34",
"details": "<unknown>"
}{
"error": "Unauthorized",
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded",
"requestId": "5f0c9a4e-3b1d-4e7a-9c2f-8d6b1a0e7c34",
"details": "<unknown>"
}{
"error": "Unauthorized",
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded",
"requestId": "5f0c9a4e-3b1d-4e7a-9c2f-8d6b1a0e7c34",
"details": "<unknown>"
}{
"error": "Unauthorized",
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded",
"requestId": "5f0c9a4e-3b1d-4e7a-9c2f-8d6b1a0e7c34",
"details": "<unknown>"
}{
"error": "Unauthorized",
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded",
"requestId": "5f0c9a4e-3b1d-4e7a-9c2f-8d6b1a0e7c34",
"details": "<unknown>"
}{
"error": "Unauthorized",
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded",
"requestId": "5f0c9a4e-3b1d-4e7a-9c2f-8d6b1a0e7c34",
"details": "<unknown>"
}Authorizations
Project API key. Manage keys in the Zespan dashboard under project settings.
Headers
Optional key identifying this batch. Repeating an accepted request with the same key and body returns the original result with replayed: true and the Idempotent-Replayed: true header, and nothing is queued or counted again.
1 - 128^[A-Za-z0-9._:-]{1,128}$Body
Newline-delimited JSON. Each line is a single event object.
"{\"trace_id\":\"3b1c...\",\"span_id\":\"a91f...\",\"name\":\"chat.completions\",\"provider\":\"openai\",\"model\":\"gpt-4o\",\"operation\":\"chat.completions\",\"input_tokens\":812,\"output_tokens\":146,\"latency_ms\":1240,\"status\":\"success\",\"timestamp\":\"2026-07-05T12:00:00.000Z\"}\n{\"trace_id\":\"3b1c...\",\"span_id\":\"c72d...\",\"parent_span_id\":\"a91f...\",\"name\":\"vector.search\",\"operation\":\"retrieval.query\",\"latency_ms\":54,\"status\":\"success\",\"timestamp\":\"2026-07-05T12:00:00.050Z\"}\n"
Response
Batch accepted for asynchronous processing.
Number of events accepted from the batch.
2
Current project config version (used by SDKs for config propagation).
7
Present and true when this response replays an earlier accepted request with the same Idempotency-Key.
true
Was this page helpful?

