> ## Documentation Index
> Fetch the complete documentation index at: https://docs.corepillar.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Ingest a trace

> Store one trace with 1 to 500 spans. Authenticated with a project tracing key; the trace lands in the key's project.

Ingestion is synchronous: the spans and the recomputed trace totals are stored before the `202` is sent. Resending a `span_id` replaces that span, so retries never duplicate data. Send an `Idempotency-Key` to have an exact retry return the original response without reprocessing.

See [Trace format](/agenthub/developers/trace-format) and [Idempotency and retries](/agenthub/developers/idempotency-and-retries).



## OpenAPI

````yaml /api-reference/openapi.json post /traces/ingest
openapi: 3.1.0
info:
  title: CorePillar API
  version: 1.0.0
  description: >-
    REST API for AgentHub and ModelHub. Ingestion endpoints authenticate with a
    project tracing key; all other endpoints use the signed-in user's browser
    session.
servers:
  - url: https://pillarforge.corepillar.ai/api/v1
    description: AgentHub
security: []
tags:
  - name: Ingestion
    description: 'Send traces with a tracing key: JSON ingest and OpenTelemetry (OTLP).'
  - name: Traces
    description: Read traces and spans.
  - name: Evaluations
    description: Evaluate traces with evaluator collections.
  - name: Evaluators
    description: Built-in and custom evaluators.
  - name: Evaluator collections
    description: Ordered groups of evaluators.
  - name: Organizations
    description: Organizations you belong to.
  - name: Members
    description: Organization members, invites and roles.
  - name: Projects
    description: Projects inside an organization.
  - name: SSO
    description: Okta SSO configuration.
  - name: Tracing keys
    description: Create, list and revoke project tracing keys.
  - name: Cost calculator
    description: Estimate, generate and execute scenario runs.
  - name: Synthetic
    description: Synthetic agent and data setup from source material.
  - name: Chat
    description: ModelHub chat. Served at https://modelhub.corepillar.ai/api/v1.
  - name: Auth
    description: Sign-in helpers.
  - name: E2E
    description: Internal end-to-end encryption key directory.
paths:
  /traces/ingest:
    post:
      tags:
        - Ingestion
      summary: Ingest a trace
      description: >-
        Store one trace with 1 to 500 spans. Authenticated with a project
        tracing key; the trace lands in the key's project.


        Ingestion is synchronous: the spans and the recomputed trace totals are
        stored before the `202` is sent. Resending a `span_id` replaces that
        span, so retries never duplicate data. Send an `Idempotency-Key` to have
        an exact retry return the original response without reprocessing.


        See [Trace format](/agenthub/developers/trace-format) and [Idempotency
        and retries](/agenthub/developers/idempotency-and-retries).
      operationId: ingestTrace
      parameters:
        - name: Idempotency-Key
          in: header
          required: false
          description: >-
            Optional. Scoped to the project. A repeated key returns the first
            successful response for that key and stores nothing new. Use a
            different key for each distinct batch.
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/IngestTrace'
            example:
              trace_id: quickstart-0001
              root_name: agent_run
              environment: development
              tags:
                - quickstart
              spans:
                - span_id: root
                  name: agent_run
                  kind: function
                  input:
                    user: What is the capital of France?
                  output:
                    content: Paris.
                  started_at: '2026-03-17T10:00:00.000Z'
                  ended_at: '2026-03-17T10:00:01.200Z'
                - span_id: llm-1
                  parent_span_id: root
                  name: chat.completions.create
                  kind: llm
                  model: gpt-4o-mini
                  tokens_in: 120
                  tokens_out: 45
                  cost_usd: 0.00012
                  latency_ms: 890
                  started_at: '2026-03-17T10:00:00.100Z'
                  ended_at: '2026-03-17T10:00:00.990Z'
      responses:
        '202':
          description: Trace stored.
          content:
            application/json:
              schema:
                type: object
                required:
                  - data
                properties:
                  data:
                    $ref: '#/components/schemas/IngestResult'
              example:
                data:
                  trace_id: quickstart-0001
                  project_id: 6f1c2a9e-3b0d-4c55-9a51-2f7d8e4b1c3a
                  span_count: 2
                  status: OK
        '400':
          description: >-
            Body isn't JSON (`Request body must be valid JSON.`) or doesn't
            match the schema (`Invalid trace payload.`, with `details.issues`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
              example:
                error:
                  code: VALIDATION_ERROR
                  message: Invalid trace payload.
                  details:
                    issues:
                      formErrors: []
                      fieldErrors:
                        spans:
                          - Invalid datetime
        '401':
          description: Tracing key missing, malformed, unknown or revoked (`UNAUTHORIZED`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '500':
          description: Unexpected server error (`INTERNAL_ERROR`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
      security:
        - tracingKey: []
        - tracingKeyHeader: []
components:
  schemas:
    IngestTrace:
      type: object
      required:
        - trace_id
        - spans
      properties:
        trace_id:
          type: string
          minLength: 1
          maxLength: 128
          description: >-
            Your id for the run. Unique per project; reusing it adds to the same
            trace.
        root_name:
          type: string
          maxLength: 512
          default: ''
          description: >-
            Label in the Traces list. Overwritten by every batch; resend it each
            time.
        status:
          $ref: '#/components/schemas/Status'
          description: >-
            Affects only this response's `status`. The stored status is derived
            from spans.
        environment:
          type: string
          maxLength: 64
          default: production
        source:
          type: string
          enum:
            - live
            - simulation
          default: live
        started_at:
          type: string
          format: date-time
          description: Optional. Restated as the earliest span start after ingest.
        tags:
          type: array
          items:
            type: string
            maxLength: 128
          default: []
          description: Replaces the trace's tags on every batch.
        spans:
          type: array
          minItems: 1
          maxItems: 500
          items:
            $ref: '#/components/schemas/IngestSpan'
    IngestResult:
      type: object
      properties:
        trace_id:
          type: string
        project_id:
          type: string
          format: uuid
        span_count:
          type: integer
          description: Spans in this batch.
        status:
          $ref: '#/components/schemas/Status'
          description: >-
            `ERROR` if this batch's trace status or any of its spans was
            `ERROR`.
    ErrorEnvelope:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
              description: Stable machine-readable code. Branch on this, not on `message`.
              examples:
                - VALIDATION_ERROR
            message:
              type: string
              description: Human-readable description. May change.
            details:
              type: object
              additionalProperties: true
              description: Extra context; often empty.
    Status:
      type: string
      enum:
        - OK
        - ERROR
    IngestSpan:
      type: object
      required:
        - span_id
        - name
        - started_at
        - ended_at
      properties:
        span_id:
          type: string
          minLength: 1
          maxLength: 128
          description: Unique within the trace. Resending a `span_id` replaces that span.
        parent_span_id:
          type:
            - string
            - 'null'
          maxLength: 128
          description: >-
            `span_id` of the parent. Omit or `null` for the root span. The
            parent may arrive later.
        name:
          type: string
          minLength: 1
          maxLength: 512
        kind:
          $ref: '#/components/schemas/SpanKind'
          default: function
        model:
          type:
            - string
            - 'null'
          maxLength: 256
        status:
          $ref: '#/components/schemas/Status'
          default: OK
        tokens_in:
          type: integer
          minimum: 0
          default: 0
        tokens_out:
          type: integer
          minimum: 0
          default: 0
        cost_usd:
          type: number
          minimum: 0
          default: 0
          description: >-
            US dollars, stored to 6 decimals. Not computed for you on JSON
            ingestion.
        latency_ms:
          type: integer
          minimum: 0
          description: Computed from `ended_at - started_at` when omitted or 0.
        input:
          type: object
          additionalProperties: true
          default: {}
          description: >-
            Must be a JSON object. Conventional keys: `system`, `user`,
            `messages`.
        output:
          type: object
          additionalProperties: true
          default: {}
          description: >-
            Must be a JSON object. Conventional keys: `content`,
            `finish_reason`, `error`.
        attributes:
          type: object
          additionalProperties: true
          default: {}
        started_at:
          type: string
          format: date-time
          description: UTC, ending in `Z`. Offsets such as `+00:00` are rejected.
        ended_at:
          type: string
          format: date-time
          description: UTC, ending in `Z`.
    SpanKind:
      type: string
      enum:
        - llm
        - tool
        - http
        - db
        - function
        - evaluation
      description: >-
        Decides which trace totals the span counts towards: `llm` (LLM calls,
        LLM time), `tool` (tool calls), `http` (HTTP time).
  securitySchemes:
    tracingKey:
      type: http
      scheme: bearer
      bearerFormat: tk_live_ / tk_test_ + 48 hex
      description: >-
        Project tracing key, from Settings → Tracing keys. `Authorization:
        Bearer tk_live_...`. The word `Bearer` is case-sensitive.
    tracingKeyHeader:
      type: apiKey
      in: header
      name: x-tracing-key
      description: >-
        Alternative to the Authorization header. Used only when no
        `Authorization: Bearer` header is present.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.