The cost estimation CLI shows you costs after a workflow finishes. Cost events expose similar data while a workflow runs:Documentation Index
Fetch the complete documentation index at: https://docs.output.ai/llms.txt
Use this file to discover all available pages before exploring further.
cost:llm:request— emitted when an LLM call finishes (generateText/streamText), with model id, token usage, and estimated dollar cost.cost:http:request— emitted when you attach a dollar cost to an HTTP response withaddRequestCostfrom@outputai/http, with the request id, URL, and cost you supplied.
Setup
Cost events use the same hooks system as error hooks:- Create a hook file and import
onfrom@outputai/core/hooks. - Register a handler for
cost:llm:request,cost:http:request, or both. - Add the file path to
output.hookFilesinpackage.json.
src/llm_cost_hooks.js
src/http_cost_hooks.js
LLM request cost
When events fire
Ancost:llm:request event is emitted after every generateText and streamText call completes. For streaming, the event fires when the stream finishes, not when it starts.
Payload
The handler receives a single object:| Field | Type | Description |
|---|---|---|
workflowId | string | undefined | Temporal workflow execution ID. Present when the call runs inside a workflow. |
activityId | string | undefined | Temporal activity ID of the step that made the LLM call. Present when the call runs inside a workflow activity. |
modelId | string | Model identifier (e.g. claude-sonnet-4-20250514, gpt-4o). From the prompt file config. |
usage | object | Token usage for this call. See Usage shape. |
cost | object | Computed dollar cost for this call. See Cost structure. |
Usage shape
usage follows the AI SDK’s totalUsage shape, aggregated across all steps for that call:
reasoningTokens and outputTokenDetails.reasoningTokens are set. Cached prompt tokens are reported in cachedInputTokens and inputTokenDetails.cacheReadTokens.
Cost structure
Cost is computed from the model’s per-million-token pricing, fetched from a built-in pricing source and cached for 24 hours. For each priced dimension, the dollar amount is(tokens / 1_000_000) * pricePerMillion. Non-cached input tokens use inputTokens - (cachedInputTokens ?? 0).
The payload matches LLMCallCost from @outputai/llm: on success you get a numeric total plus a components array; on failure total is null and message explains why.
| Field | Type | Description |
|---|---|---|
total | number | null | Total estimated cost in dollars. null if pricing could not be computed. |
message | string | Present when total is null (e.g. unknown model, pricing fetch failed, or unexpected error). |
components | array | Present when total is a number. Each entry is { name: string, value: number }. Only dimensions that have pricing for the model are included. |
components[].name values
name | Description |
|---|---|
input_tokens | Non-cached prompt tokens. |
input_cached_tokens | Cached prompt read tokens (cachedInputTokens). |
output_tokens | Completion tokens. |
reasoning_tokens | Reasoning tokens, only when the model defines separate reasoning pricing; omitted otherwise. |
reasoning_tokens row if that price is not configured for the model.
Unknown model or pricing unavailable:
HTTP request cost
Events fire only when your code callsaddRequestCost( response, cost ) with a response object created by @outputai/http (or its exported fetch). The SDK attaches the cost to the existing HTTP trace event and emits cost:http:request. If the response did not originate from this package, addRequestCost no-ops (with a console warning) and no hook event is emitted.
Payload
The handler receives a single object. As withcost:llm:request, workflowId and activityId are filled when the hook runs inside a Temporal workflow activity.
| Field | Type | Description |
|---|---|---|
workflowId | string | undefined | Temporal workflow execution ID. Present when the handler runs inside a workflow. |
activityId | string | undefined | Temporal activity ID. Present when the handler runs inside a workflow activity. |
requestId | string | Internal id linking this payload to the HTTP trace event for that request. |
url | string | Final response URL (same as response.url). |
cost | object | Dollar cost you passed to addRequestCost. See HTTP cost shape. |
HTTP cost shape
Same top-level shape as LLM costs: a numerictotal and an optional components array of { name, value }. For HTTP, name and value are entirely yours — they mirror what you pass to addRequestCost (for example labels derived from vendor billing headers).