---
title: "Cost Estimation"
description: "See what your workflows cost — LLM tokens, API calls, and external services — with a single CLI command"
---

Every LLM call and API request costs money. Output tracks costs automatically from your [trace files](/operations/tracing), so you can see exactly what a workflow run costs before it ever hits production.

## Quick start

Make sure [tracing is enabled](/operations/tracing#enabling-tracing), run a workflow, then check what it cost:

```bash
# 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:

```bash
output workflow cost lead_enrichment --verbose
```

You can also point at a specific trace file:

```bash
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:

```yaml 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
```

| Field | Required | Description |
|-------|----------|-------------|
| `provider` | Yes | Provider name (informational) |
| `input` | Yes | Price per 1M input tokens |
| `output` | Yes | Price per 1M output tokens |
| `cached_input` | No | Price per 1M cached input tokens |
| `reasoning` | No | Price 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):

```yaml 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:

```yaml 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):

```yaml 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):

```yaml 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):

```yaml costs.yml
services:
  exa:
    type: response_cost
    url_pattern: "api.exa.ai"
    cost_path: "output.body.costDollars.total"
```

### Service config reference

| Field | Used by | Description |
|-------|---------|-------------|
| `type` | All | Pricing type: `token`, `unit`, `request`, `response_cost` |
| `url_pattern` | All | Substring matched against HTTP request URL |
| `usage_path` | `token` | Dot-path to token count in response |
| `per_million` | `token` | Price per 1M tokens (single count) |
| `input_field` / `output_field` | `token` | Field names for separate input/output counts |
| `input_per_million` / `output_per_million` | `token` | Prices for separate input/output tokens |
| `price_per_unit` | `unit` | Price per API unit |
| `endpoints` | `unit`, `request` | Endpoint-specific patterns and pricing |
| `model_path` | `request` | Dot-path to model name in request |
| `models` | `request` | Map of model names to per-request prices |
| `default_price` | `request` | Fallback price when model not matched |
| `cost_path` | `response_cost` | Dot-path to dollar cost in response |
| `billable_method` | `response_cost` | HTTP method to count when no cost data present |
| `fallback_models` | `response_cost` | Map of model names to fallback prices |
| `default_fallback` | `response_cost` | Fallback 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`](/packages/cli#output-workflow-cost) for the full command reference.
