Trace ingestion
HTTP authentication, batch format, span updates, and retry behavior.
Send native PromptLens JSON batches to POST https://app.promptlens.io/api/v1/traces. This endpoint does not accept OTLP. For a runnable example, follow Record your first trace.
Authentication and request format
Send an Observability ingestion key in Authorization: Bearer YOUR_INGESTION_KEY and set Content-Type: application/json. Ingestion keys begin with plt_ and are associated with an organization, application, and environment. Retrieval keys and management OAuth tokens cannot authorize this endpoint.
The body is an object with version: 1 and an events array containing 1–50 span snapshots. Requests must be uncompressed and at most 1 MiB. Unknown batch or event fields are rejected.
Required span fields
| Field | Format |
|---|---|
traceId | 32 lowercase hexadecimal characters, not all zeros |
spanId, rootSpanId | 16 lowercase hexadecimal characters, not all zeros |
revision | Integer from 0 to 1,000,000 |
name | Nonempty string, up to 200 characters |
service | Nonempty string, up to 100 characters |
kind | execution, model, attempt, tool, retrieval, or custom |
status | running, success, error, or cancelled |
startedAt | Nonnegative integer timestamp in Unix milliseconds; no more than five minutes ahead of server time |
A running span must omit endedAt. A finished span must include endedAt, also in Unix milliseconds, greater than or equal to startedAt.
Relationships and updates
For a root span, set rootSpanId to its spanId and omit parentSpanId. For a child, preserve the trace's traceId and rootSpanId, use a distinct spanId, and include parentSpanId. A span cannot be its own parent.
Start at revision zero and increment the revision when updating or completing a span. Each update contains the complete snapshot, including required fields, rather than a patch. Preserve IDs and the revision when retrying an identical event.
Optional metadata
| Fields | Format |
|---|---|
sessionId, endUserId | Strings up to 200 characters |
provider, promptVersionId, pricingVersion | Strings up to 100 characters |
model | String up to 200 characters |
inputTokens, outputTokens | Nonnegative integers |
costUsdNanos | Nonnegative integer cost in billionths of a US dollar |
costSource | provider_reported, catalog_estimate, or unavailable |
contentJson | JSON encoded as a string, up to 256 KiB |
metadataJson | JSON object encoded as a string, up to 16 KiB and 64 top-level keys |
omitted | Array of up to four entries: input, output, error, or metadata |
JSON content and metadata can be nested at most 32 levels. Include costUsdNanos only with provider_reported or catalog_estimate as its source. For visibility and retention, see Trace content and retention.
Responses and retries
| Status | Action |
|---|---|
200 | The whole batch is acknowledged |
400 | Correct invalid JSON, fields, or span values |
401 | Check the ingestion key and whether it has been revoked |
403 | Resolve workspace read-only restrictions |
409 | Check for conflicting span state or a startedAt timestamp more than five minutes ahead of server time. For clock skew, synchronize the client's clock and correct the timestamp before retrying |
413 | Reduce the request size |
415 | Send uncompressed JSON with the correct content type |
429 or 5xx | Retry the identical batch with backoff; respect Retry-After when present |
After a network error, retry the identical batch using the same span IDs and revisions. Ensure your application sends its final events before a serverless invocation ends.