> ## 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.

# Context

> Tag events with agent, user, thread, and custom dimensions so the dashboard can aggregate by them.

Context is what makes the ledger queryable. Every event carries the same optional metadata object, and its `context` fields are the identifiers the dashboard aggregates by — the dimensions you tag are exactly the ones you can later slice cost and usage by.

```typescript theme={null}
type CarbonMetadata = {
  traceId?: string;
  context?: {
    threadId?: string;
    agentId?: string;
    agentGroupId?: string;
    userId?: string;
  };
  additionalProperties?: Record<string, string | number>;
};
```

The shape is identical whether an event comes from an SDK wrapper, a wrapped tool, or manual capture.

## Context fields

Context fields are the built-in dimensions. All are optional strings whose meaning is defined by your application:

| Field          | What it identifies           | Powers                                                  |
| -------------- | ---------------------------- | ------------------------------------------------------- |
| `userId`       | The end user behind the call | [Users](/documentation/dashboard/analytics) analytics   |
| `agentId`      | The agent instance or role   | [Agents](/documentation/dashboard/analytics) analytics  |
| `agentGroupId` | A group of related agents    | Agent group filters                                     |
| `threadId`     | A conversation or session    | [Threads](/documentation/dashboard/analytics) analytics |

```typescript theme={null}
carbon: {
  context: {
    userId: "user-481",
    agentId: "support-agent",
    threadId: "thread-92",
  },
}
```

Set the fields that match your product's shape — a chat product benefits from `threadId` and `userId`; a multi-agent system from `agentId` and `agentGroupId`. Events tagged with these light up the [dimension pages](/documentation/dashboard/analytics) in the dashboard; events without them still record, but cannot be sliced by that dimension.

## Custom properties

`additionalProperties` holds your own dimensions as string or number values — release tags, environment names, experiment arms:

```typescript theme={null}
carbon: {
  additionalProperties: {
    release: "2026-06",
    experiment: "prompt-v2",
    region: "eu-west-1",
  },
}
```

## Where metadata goes

The same metadata object — `traceId`, `context`, and `additionalProperties` — attaches the same way from every capture path:

<Tabs>
  <Tab title="SDK wrappers">
    Pass a `carbon` field in the call arguments. The wrapper strips it before
    the request reaches the provider.

    ```typescript theme={null}
    await openai.chat.completions.create({
      model: "gpt-5.4-nano",
      messages,
      carbon: { traceId, context: { userId: "user-481" } },
    });
    ```
  </Tab>

  <Tab title="Wrapped tools">
    Pass the metadata object as an optional trailing argument. See
    [Tool calls](/documentation/sdk/tool-calls).

    ```typescript theme={null}
    await getWeather({ city: "Tokyo" }, { traceId, context: { userId: "user-481" } });
    ```
  </Tab>

  <Tab title="Manual capture">
    Set `traceId`, `context`, and `additionalProperties` directly on the event.
    See [Manual capture](/documentation/sdk/manual-capture).
  </Tab>
</Tabs>

To correlate the events of one logical operation — an agent run, a request, a job — give them a shared `traceId`. See [Traces](/documentation/sdk/traces).
