Every event accepts the same metadata object, whether it comes from an SDK wrapper, a wrapped tool, or manual capture:
type CarbonMetadata = {
traceId?: string;
context?: {
threadId?: string;
agentId?: string;
agentGroupId?: string;
userId?: string;
};
additionalProperties?: Record<string, string | number>;
};
Traces
A trace groups the events of one logical operation — an agent run, a request, a job. Create a trace ID once and pass it to every call that belongs together:
const traceId = carbon.createTraceId();
const plan = await openai.chat.completions.create({
model: "gpt-5.4-nano",
messages: [{ role: "user", content: "Plan the trip." }],
carbon: { traceId },
});
const booking = await bookFlight({ destination: "Tokyo" }, { traceId });
createTraceId returns a UUID and stores no state — the SDK never infers trace membership, so correlation is always explicit.
Wrappers that run multi-step loops (Vercel AI SDK tools, OpenAI runTools)
put every step of a call on the same trace automatically. Pass your own
traceId when a trace spans multiple top-level calls.
Context
Context fields are the identifiers the dashboard aggregates by. All are optional strings with meaning defined by your application:
| Field | What it identifies | Powers |
|---|
userId | The end user behind the call | Users analytics |
agentId | The agent instance or role | Agents analytics |
agentGroupId | A group of related agents | Agent group filters |
threadId | A conversation or session | Threads analytics |
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.
Custom properties
additionalProperties holds your own dimensions as string or number values — release tags, environment names, experiment arms:
carbon: {
additionalProperties: {
release: "2026-06",
experiment: "prompt-v2",
region: "eu-west-1",
},
}
SDK wrappers
Wrapped tools
Manual capture
Pass a carbon field in the call arguments. The wrapper strips it before
the request reaches the provider.await openai.chat.completions.create({
model: "gpt-5.4-nano",
messages,
carbon: { traceId, context: { userId: "user-481" } },
});
Pass the metadata object as an optional trailing argument. See
Tool calls.await getWeather({ city: "Tokyo" }, { traceId, context: { userId: "user-481" } });
Set traceId, context, and additionalProperties directly on the event.
See Manual capture.