---
title: "Ingest a batch of traces"
method: POST
path: "/ingest"
tags: ["Ingest"]
---

# Ingest a batch of traces

`POST /ingest`

Validates the payload, resolves the API key, prices each span, and buffers the rows for a flush to ClickHouse. Fire-and-forget: a 202 means the batch was accepted, not yet durably written.

## Request body

- IngestPayload — A versioned batch of traces.
  - `version` 'v1', required — Wire contract version.
  - `traces` Trace[], required
    - `traceId` string, required
    - `traceName` string
    - `agentName` string
    - `workflowName` string
    - `workflowRunId` string
    - `sessionId` string
    - `customer` object — The end-customer this call serves, for per-customer cost attribution. Only `id` is required; `name`/`imageUrl` are display-only.
      - `id` string, required
      - `name` string
      - `imageUrl` string, uri
    - `metadata` Metadata — Free-form string-to-string labels. At most 64 entries; keys up to 128 chars, values up to 1024 chars.
    - `spans` Span[], required
      - `spanId` string, required
      - `parentSpanId` string
      - `spanType` 'agent' | 'llm' | 'tool' | 'embedding' | 'other', required
      - `name` string, required
      - `startTime` integer, required — Epoch milliseconds.
      - `endTime` integer, required — Epoch milliseconds; must be >= startTime.
      - `status` 'ok' | 'error'
      - `errorMessage` string
      - `provider` string
      - `modelId` string
      - `usage` Usage — Token and request counts. Each dimension is priced independently at ingest.
        - `inputTokens` integer
        - `outputTokens` integer
        - `totalTokens` integer
        - `reasoningTokens` integer
        - `cachedInputTokens` integer
        - `cacheWriteInputTokens` integer
        - `imageCount` integer
        - `webSearchCount` integer
        - `requestCount` integer
      - `ttftMs` number — Time to first token, milliseconds. May be fractional.
      - `chunkOffsets` integer[] — Streaming LLM spans only: ms from step start for each sampled output chunk. Parallel to chunkTokens.
      - `chunkTokens` integer[] — Streaming LLM spans only: cumulative output tokens at each chunkOffsets sample.
      - `reasoningOffsets` integer[] — Streaming reasoning models only: ms from step start for each sampled reasoning chunk. Parallel to reasoningChunkTokens.
      - `reasoningChunkTokens` integer[] — Streaming reasoning models only: cumulative reasoning tokens at each reasoningOffsets sample.
      - `reasoningDurationMs` integer — Total wall-clock ms spent inside reasoning blocks for this step.
      - `input` string — Prompt/input text. Omitted when recordInputs is disabled.
      - `output` string — Completion/output text. Omitted when recordOutputs is disabled.
      - `toolCatalog` string — JSON catalog of tools offered for the call (name → {description, JSON-Schema params}). Stamped on llm and agent spans only.
      - `modelCallMs` integer — Pure model-call wall-clock for the step (ms), excluding client-side tool execution. v7 only; absent on v4–v6 wrap and non-model spans.
      - `systemFingerprint` string — Provider model-build fingerprint (e.g. OpenAI system_fingerprint).
      - `safetyMetadata` string — JSON blob of provider safety ratings, as reported. Absent when the provider reports none.
      - `sources` string — JSON array of RAG/grounding citations (StepResult.sources). Recorded only when output capture is on.
      - `rateLimit` object — Rate-limit headroom, normalized cross-provider from response headers (OpenAI x-ratelimit-*, Anthropic anthropic-ratelimit-*). Any subset may be present.
        - `requestsLimit` integer
        - `requestsRemaining` integer
        - `requestsResetMs` integer
        - `tokensLimit` integer
        - `tokensRemaining` integer
        - `tokensResetMs` integer
      - `metadata` Metadata — Free-form string-to-string labels. At most 64 entries; keys up to 128 chars, values up to 1024 chars.

## Response `202`

Batch accepted into the write buffer.

- object
  - `accepted` integer, required — Number of span rows accepted.

## Other responses

- `400` — Invalid JSON body, or payload failed schema validation.
- `401` — Missing, invalid, or revoked API key.
- `413` — Request body exceeds INGEST_MAX_BODY_BYTES (default 10 MiB). Rejected before the body is parsed.
- `429` — Too Many Requests — returned in two distinct cases. (1) Per-key rate limit: includes a `Retry-After` header; back off and retry after it. (2) Plan quota exceeded: a billing condition with no `Retry-After`; retrying won't succeed until the plan is upgraded or the quota resets.
- `503` — Server is shutting down and is no longer accepting new batches (graceful drain in progress). Retry against another replica or after restart.

## Changes

- **2026-06-21** `04549fe6ab0a` — 1 info
  - added the new optional request property `traces/items/customer`
- **2026-06-13** `da37470dccd5` — 2 breaking, 2 warning, 14 info
  - added 'propertyNames' constraint to the request property `traces/items/metadata`
  - added 'propertyNames' constraint to the request property `traces/items/spans/items/metadata`
  - the `traces/items/metadata/additionalProperties/` request property's maxLength was set to `1024`
  - the `traces/items/spans/items/metadata/additionalProperties/` request property's maxLength was set to `1024`
  - …14 more
- **2026-05-31** `509775c21a87` — 1 info
  - added the new optional request property `traces/items/traceName`

[Change history](https://skmtc.dev/foglamp-labs/apis/foglamp-ingest-api/changes/ingest/post.md)

---

[API](https://skmtc.dev/foglamp-labs/apis/foglamp-ingest-api.md) · [All operations](https://skmtc.dev/foglamp-labs/apis/foglamp-ingest-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/foglamp-labs/foglamp-ingest-api/revisions/04549fe6ab0a/schema)
