Core Concepts
Rate Card

Rate Card

A rate card is a per-project, per-model token pricing table that you supply. The Papayya dashboard multiplies token counts from your runs against the rate card to produce ≈ $X dollar estimates on each item and each step.

Why you configure this yourself

Papayya does not ship a built-in pricing table. Provider prices change (Anthropic drops rates, OpenAI adds tiers, Bedrock discounts vary by region), and any number we hardcoded would be wrong the moment the provider moved. Your token counts are authoritative — they're what the provider reported in each response. Your dollar estimates are only as accurate as the pricing you paste in.

That also means: the numbers stay private. Papayya doesn't need to know your negotiated rates; they're stored in your project (projects.rate_card) and used only to price your own runs.

The rate card is also what populates cost_usd on each step and the accrued total on each item — the control plane multiplies the token counts your provider reported by these numbers as each step lands. That total is what a budget cap compares against, so a rate card with no entry for a model prices that model's steps at $0 and they never count toward a budget. Set your rate card before you rely on a budget.

Without a rate card

The product works fine. Runs, items, and steps display token counts (1.2M in, 340k out) with no dollar column. Nothing breaks — but cost_usd reads 0 everywhere and budget caps never trip, because there is no price to accrue.

With a rate card

Wherever tokens are shown, an ≈ $X estimate appears next to them, derived from the rate card. Partial coverage is fine — if your rate card has gpt-4o but a run also used mistral-large, the mistral portion shows tokens only.

Shape

{
  "claude-sonnet-4-20250514": {
    "input_cents_per_million":  300,
    "output_cents_per_million": 1500
  },
  "gpt-4o": {
    "input_cents_per_million":  250,
    "output_cents_per_million": 1000
  }
}
  • Cents per million tokens. 300 means $3.00 per 1M tokens.
  • Model keys are whatever string you use in your agent code ("claude-sonnet-4-20250514", "gpt-4o-2024-08-06", etc).
  • Zero is legal (a free-tier or cached model).

Configuring it

CLI

# View the current card
papayya rate-card show
 
# Add / update one model (type dollars, we store cents)
papayya rate-card set claude-sonnet-4-20250514 \
  --input-per-million 3.00 \
  --output-per-million 15.00
 
# Remove a model
papayya rate-card remove claude-sonnet-4-20250514
 
# Bulk replace from a file
papayya rate-card import --file rate-card.json
 
# Open the card in $EDITOR
papayya rate-card edit

Dashboard

Settings → Pricing. Each project has its own rate card section with a table of models. Add via the form or paste a full JSON object with "Edit JSON."

API

GET  /v1/projects/{projectId}/rate-card
PUT  /v1/projects/{projectId}/rate-card

PUT is a wholesale replace — send the full card, not a patch. See the shape above.

Where to find your provider's rates

Most providers publish pricing publicly. Grab the numbers, convert dollars per 1M tokens, and paste:

If you've negotiated volume discounts, use your actual rate. Your provider invoice is the ground truth; the rate card just lets the dashboard speak in the same units.

What the dashboard does with it

When a run renders — down to each item and each step — the dashboard:

  1. Reads the token counts already recorded from each step.
  2. Looks up the model used in the project's rate card — exact match first, then the longest matching prefix.
  3. Multiplies: cents = (input_tokens × input_cents_per_million + output_tokens × output_cents_per_million) / 1_000_000.
  4. Renders the result with an ≈ prefix to signal it's an estimate, not a bill.

This is where per-item and per-step cost come from: the same token math applied at whatever level you're looking at. Models not in the rate card render — or just the token count with no dollar figure. No silent fallback to a default rate — we'd rather show nothing than the wrong number.

Prefix matching

Providers report a resolved model id on each response — you ask for gpt-4o-mini and the response says gpt-4o-mini-2024-07-18. That resolved id is what gets recorded on the step.

So a card entry is matched as a prefix of the recorded model id:

{ "gpt-4o-mini": { "input_cents_per_million": 15, "output_cents_per_million": 60 } }

prices gpt-4o-mini, gpt-4o-mini-2024-07-18 and any future snapshot of it. Price the name you buy; you do not have to chase dated ids.

Two rules keep this from guessing:

  • Longest match wins. A card with both gpt-4o and gpt-4o-mini prices gpt-4o-mini-2024-07-18 at the mini rate.
  • Prefixes only work in one direction. An entry for gpt-4o-mini-2024-07-18 does not price a step recorded as plain gpt-4o-mini — that would be guessing which snapshot you meant.

Unpriced is not free

An item whose model has no rate-card entry shows —, not $0.0000, along with the model that is missing:

unpriced — no rate card entry for gpt-4o-mini-2024-07-18

An item that genuinely spent nothing — a non-LLM workload, or one that failed before its first model call — still shows $0.0000, because that is true.

At the run level the cost is a sum, so it stays a number and says what it is missing ($1.4200 +12 unpriced): a total that is partly unpriced is a lower bound, not a blank.

Pricing does not backfill

Cost is computed as each step lands, against the card as it was at that moment. Setting or correcting a rate card afterwards does not re-price runs that already happened — they keep showing —.

Re-pricing existing runs against the current card is an explicit operation rather than something that happens on read, because re-reading is not the same as re-deciding. Ask us to run it if you set your card after your first runs.

What a rate card is not

  • Not a budget. Budgets are a separate concern (pausing at aggregate spend). Rate cards only affect display.
  • Not a billing source. These are estimates of your provider spend for display. Papayya's own bill meters the hosted execution you run — see Usage & Billing. Provider spend goes on your bill with Anthropic / OpenAI / etc directly.
  • Not shared. Each project has its own rate card, reflecting that different projects may use different providers or negotiated rates.