Skip to main content
Every LLM call and API request costs money. Output tracks costs automatically from your trace files, so you can see exactly what a workflow run costs before it ever hits production.

Quick start

Make sure tracing is enabled, run a workflow, then check what it cost:
# Run a workflow (produces a trace file)
output workflow run lead_enrichment acme

# Calculate cost from the latest trace
output workflow cost lead_enrichment
That’s it. The command reads the trace, looks up pricing for every LLM call and API request, and prints a breakdown:
Trace: logs/runs/lead_enrichment/2026-03-01_lead_enrichment-abc123.json
Workflow: lead_enrichment
Duration: 12.4s

LLM Costs:
  Model                   Calls        Cost
  ──────────────────────────────────────────
  claude-sonnet-4          3 calls     $0.0842
  gpt-4o-mini              1 call      $0.0012
  ──────────────────────────────────────────
  Subtotal                 4 calls     $0.0854

API Costs:
  Service       Calls        Cost
  ──────────────────────────────────────────
  tavily         2 calls     $0.02
  jina           1 call      $0.0001
  ──────────────────────────────────────────
  Subtotal       3 calls     $0.0201

══════════════════════════════════════════════
TOTAL ESTIMATED COST                    $0.11
══════════════════════════════════════════════
Use --verbose for a per-call breakdown showing individual steps, token counts, and usage details:
output workflow cost lead_enrichment --verbose
You can also point at a specific trace file:
output workflow cost lead_enrichment logs/runs/lead_enrichment/2026-03-01_lead_enrichment-abc123.json

How it works

The cost calculator walks the trace tree and extracts two kinds of billable events:
  1. LLM calls — Reads the model from the loaded prompt config and the token usage (input, output, cached, reasoning). Multiplies each by the model’s per-million-token price.
  2. HTTP calls — Matches the request URL against known service patterns in the pricing config. Calculates cost from token usage, API units, per-request pricing, or a cost field in the response body, depending on the service type.
Failed HTTP calls (status >= 400) are excluded — most APIs don’t charge for errors.

Pricing configuration

Output ships with built-in pricing for common LLM models (Anthropic, OpenAI, Google, Perplexity) and API services (Jina, Tavily, Semrush, Exa, DataForSEO). For most workflows, this works out of the box. To add or override pricing, create config/costs.yml in your project root:
your-project/
├── config/
│   └── costs.yml       # Your overrides — merged on top of built-in pricing
├── src/
│   └── workflows/
└── .env
The CLI loads the built-in config first, then merges your file on top. You only need to include entries you want to add or change.

Model pricing

Each entry under models maps a model identifier to its per-million-token prices:
costs.yml
models:
  # Override pricing for a model
  claude-sonnet-4:
    provider: anthropic
    input: 3.00               # $ per 1M input tokens
    output: 15.00             # $ per 1M output tokens
    cached_input: 0.30        # $ per 1M cached input tokens

  # Add a model the CLI doesn't know about
  my-fine-tuned-model:
    provider: openai
    input: 6.00
    output: 12.00
FieldRequiredDescription
providerYesProvider name (informational)
inputYesPrice per 1M input tokens
outputYesPrice per 1M output tokens
cached_inputNoPrice per 1M cached input tokens
reasoningNoPrice per 1M reasoning tokens. Falls back to output price if not set
Model names are matched by exact key first, then by prefix — claude-sonnet-4 matches both claude-sonnet-4 and claude-sonnet-4-20250514.

Service pricing

Each entry under services defines how to calculate cost for HTTP calls to a specific API. The url_pattern field matches against the request URL, and the type determines the calculation method. Four pricing types are supported:

token — Price per million tokens

For APIs that report token usage in their response (like Jina Reader):
costs.yml
services:
  jina:
    type: token
    url_pattern: "r.jina.ai"
    usage_path: "body.data.usage.tokens"
    per_million: 0.045
For APIs with separate input/output token counts:
costs.yml
services:
  perplexity_api:
    type: token
    url_pattern: "api.perplexity.ai"
    usage_path: "body.usage"
    input_field: "prompt_tokens"
    output_field: "completion_tokens"
    input_per_million: 1.00
    output_per_million: 1.00

unit — Price per API unit

For APIs that charge by units (like Semrush):
costs.yml
services:
  semrush:
    type: unit
    url_pattern: "api.semrush.com"
    price_per_unit: 0.00025
    endpoints:
      backlinks_overview:
        pattern: "type=backlinks_overview"
        units_per_request: 10
      domain_organic:
        pattern: "type=domain_organic"
        units_per_line: 10

request — Fixed price per request

For APIs with simple per-request pricing (like Tavily):
costs.yml
services:
  tavily:
    type: request
    url_pattern: "api.tavily.com"
    endpoints:
      search:
        pattern: "/search"
        price: 0.01
      extract:
        pattern: "/extract"
        price_per_item: 0.005
        items_path: "body.urls"

response_cost — Cost reported in response

For APIs that return the actual cost in their response (like Exa):
costs.yml
services:
  exa:
    type: response_cost
    url_pattern: "api.exa.ai"
    cost_path: "output.body.costDollars.total"

Service config reference

FieldUsed byDescription
typeAllPricing type: token, unit, request, response_cost
url_patternAllSubstring matched against HTTP request URL
usage_pathtokenDot-path to token count in response
per_milliontokenPrice per 1M tokens (single count)
input_field / output_fieldtokenField names for separate input/output counts
input_per_million / output_per_milliontokenPrices for separate input/output tokens
price_per_unitunitPrice per API unit
endpointsunit, requestEndpoint-specific patterns and pricing
model_pathrequestDot-path to model name in request
modelsrequestMap of model names to per-request prices
default_pricerequestFallback price when model not matched
cost_pathresponse_costDot-path to dollar cost in response
billable_methodresponse_costHTTP method to count when no cost data present
fallback_modelsresponse_costMap of model names to fallback prices
default_fallbackresponse_costFallback price when no cost data and no model match

Unknown models

When the calculator encounters a model that isn’t in the pricing config, it reports the cost as $0 and prints a warning:
Warning: Unknown models (add to config/costs.yml): my-custom-model
Add the model to your project’s config/costs.yml to include it in future calculations.

CLI reference

See output workflow cost for the full command reference.