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

# Ingest events

> Send a batch of LLM and tool events to Carbon.

Accepts up to 500 events (4 MiB max body) per request, validates them, and queues them durably. Responds `202` once the batch is queued — see [Delivery guarantees](/documentation/concepts/delivery) for idempotency and processing semantics.

Batches are rejected with `402` when the space cannot accept events: `usage_limit_exceeded` once the monthly included event limit is reached, or `billing_not_active` when the subscription is not active — see [Plans](/documentation/dashboard/plans).

## Body

<ParamField body="events" type="object[]" required>
  The events to ingest. Each entry is a canonical Carbon event — an LLM event
  (`type: "llm"`) or a tool event (`type: "tool"`). The full field-by-field
  contract is in the [event schema](/api-reference/schemas/event-schema).

  <Expandable title="event (common fields)">
    <ParamField body="id" type="string" required>
      Client-generated UUIDv4. Unique per event within your space; used for
      deduplication, so reuse it across retries.
    </ParamField>

    <ParamField body="type" type="&#x22;llm&#x22; | &#x22;tool&#x22;" required>
      Event type discriminator.
    </ParamField>

    <ParamField body="traceId" type="string">
      UUIDv4 shared by related events.
    </ParamField>

    <ParamField body="startTimeMs" type="number" required>
      Call start, milliseconds since epoch.
    </ParamField>

    <ParamField body="endTimeMs" type="number" required>
      Call end, milliseconds since epoch.
    </ParamField>

    <ParamField body="durationMs" type="number" required>
      Call duration in milliseconds.
    </ParamField>

    <ParamField body="status" type="object" required>
      `{ state: "ok" | "error", error?: { code?, httpStatus?, message? } }`
    </ParamField>

    <ParamField body="instrumentation" type="object" required>
      Source of the event: `{ vendor: "carbon", source, sourcePackage, sourceFunction? }`
    </ParamField>

    <ParamField body="context" type="object" required>
      Aggregation identifiers: `{ threadId?, agentId?, agentGroupId?, userId? }`.
      May be empty.
    </ParamField>

    <ParamField body="additionalProperties" type="object" required>
      Custom string or number dimensions. May be empty.
    </ParamField>

    <ParamField body="properties" type="object" required>
      Type-specific payload: `{ llm: {...} }` for LLM events,
      `{ tool: {...} }` for tool events — see the
      [event schema](/api-reference/schemas/event-schema).
    </ParamField>
  </Expandable>
</ParamField>

## Response

<ResponseField name="message" type="string">
  Confirmation that the batch was queued.
</ResponseField>

<RequestExample>
  ```bash cURL theme={null}
  curl https://ingest.oncarbon.site/v1/ingest-events \
    --request POST \
    --header "Authorization: Bearer $CARBON_API_KEY" \
    --header "Content-Type: application/json" \
    --data '{
      "events": [
        {
          "type": "llm",
          "id": "7d9f2a4e-3c1b-4f6a-9e8d-2b5c7a1f4e3d",
          "traceId": "1b6e8c2a-9d4f-4e7b-8a3c-5f2e9d1b7c4a",
          "startTimeMs": 1781176800000,
          "endTimeMs": 1781176801200,
          "durationMs": 1200,
          "status": { "state": "ok" },
          "instrumentation": {
            "vendor": "carbon",
            "source": "openai",
            "sourcePackage": "openai"
          },
          "context": { "userId": "user-481", "agentId": "support-agent" },
          "additionalProperties": { "release": "2026-06" },
          "properties": {
            "llm": {
              "model": "gpt-5.4-nano",
              "input": {
                "system": "You are concise.",
                "prompt": "What is the capital of France?",
                "tools": []
              },
              "output": {
                "mode": "generate",
                "response": "Paris.",
                "toolCalls": []
              },
              "usage": {
                "inputTokens": 18,
                "inputTokenDetails": {
                  "uncachedTokens": 18,
                  "cacheReadTokens": 0,
                  "cacheWriteTokens": 0
                },
                "outputTokens": 3,
                "outputTokenDetails": {
                  "reasoningTokens": 0,
                  "responseTokens": 3
                },
                "totalTokens": 21
              }
            }
          }
        }
      ]
    }'
  ```
</RequestExample>

<ResponseExample>
  ```json 202 theme={null}
  {
    "message": "Events ingested successfully"
  }
  ```

  ```json 401 theme={null}
  {
    "error": {
      "id": "unauthorized",
      "title": "Unauthorized",
      "status": 401,
      "details": "Missing or invalid API key."
    }
  }
  ```

  ```json 402 theme={null}
  {
    "error": {
      "id": "usage_limit_exceeded",
      "title": "Usage limit exceeded",
      "status": 402,
      "details": "The space has reached its monthly included event limit. Upgrade the plan to resume ingestion."
    }
  }
  ```

  ```json 413 theme={null}
  {
    "error": {
      "id": "too_many_events",
      "title": "Too many events",
      "status": 413,
      "details": "Event batch contains more events than ingest supports."
    }
  }
  ```
</ResponseExample>
