How to reduce Claude API cost, eight levers, measured

Most API bills are not high because the rate is bad. They are high because the same context is resent dozens of times, cheap work is done by an expensive model, and outputs are longer than anyone needs. Fix those three and the bill drops without touching quality.

In short: The three largest levers are: send less context, route mechanical work to a cheaper model, and cap output length. Output tokens cost several times more than input, so limiting response length is usually worth more than people expect. Measure per day before and after each change.

Start with measurement, not with cuts

Before changing anything, pull one day of usage and answer three questions: which model accounts for most spend, which workload drives it, and what fraction is input versus output. Cuts applied blindly usually remove capability, not cost.

The spread between model classes is the biggest lever available — gateway rate vs official list
ModelGateway rate
in / out per 1M tokens
Official list
in / out per 1M tokens
Diff
claude-haiku-4-5$0.5 / $2.5$1 / $550%
claude-sonnet-5$1 / $5$2 / $1050%
claude-opus-5$2.5 / $12.5$5 / $2550%
deepseek-v4-pro$0.66 / $1.98— / ——

Rates checked 2026-11-01. Gateway rates move with upstream promotions (verify the current number in your dashboard before committing to a budget).

Lever 1 — send less context (usually the biggest)

Every request resends the conversation. Compacting a long thread, starting a fresh one per task, and keeping unrelated files out of the prompt all reduce the same thing: tokens you pay for repeatedly. This is the highest-yield change for agent workloads.

Lever 2 — route by difficulty

Not every call needs the strongest model. Classification, extraction, formatting, and applying a change you already specified are mechanical. Escalate only what is genuinely ambiguous.

Don't have an account yet? You need an API key from the gateway before the steps below will work — how the discount works and what you take on. Create one free → (no prepay, $1 minimum top-up)
# cheap first, escalate only when confidence is low
def handle(task):
    out = call("claude-haiku-4-5", task)      # cheap pass
    if out.confidence < 0.7:
        out = call("claude-sonnet-5", task)   # escalate
    return out

Lever 3 — cap the output

Output tokens cost several times more than input. Set max_tokens to something sane and ask for the format you actually consume, a diff, a JSON object, a one-line answer. Long explanations you do not read are pure cost.

resp = client.messages.create(
    model="claude-sonnet-5",
    max_tokens=300,          # hard ceiling, not a suggestion
    messages=[{"role": "user", "content": prompt}],
)

Lever 4 — reuse stable prefixes

When many requests share a large prefix (a fixed system prompt, a document, a codebase context) caching that prefix makes the repeated part much cheaper. It does nothing for one-off requests, so apply it where the prefix is genuinely stable.

Lever 5 — batch what does not need to be interactive

Offline work, backfills, bulk classification, nightly summaries, does not need low latency. Batch it, and it costs less than the same volume sent interactively.

Lever 6 — stop retrying blindly

Retries are the invisible line item. A 5% failure rate with unconditional retries is 5% of spend producing nothing. Retry on transient errors only, with backoff, and log every retry so it stops being invisible.

Lever 7 — shorten the loop

Ten exploratory requests cost more than one well-specified one, and often produce a worse result. Write the constraint into the prompt up front: what to change, what not to touch, what the output should look like.

Lever 8 (compare the rate), not the brand

The same model can cost materially different amounts depending on where you route it. That comparison is the whole point of a pricing index, and it is worth re-checking periodically, because rates move.

Check current rates → Free to sign up · $1 minimum top-up · No prepayment

Put a number on it

Run your own workload through the cost calculator before and after each change. A lever that does not move that number did not work, however sensible it sounded.

Where the money actually goes, ranked

Cost advice tends to be a list of tricks with no ordering. These five are ordered by how much they typically move a real bill, and each one names the number that tells you whether it worked.

LeverWhy it worksWhat to measure to know it worked
Switch to a cheaper modelUnit price drops across every token you send.Output quality on your actual task (not on a benchmark).
Cut context per requestInput is re-sent every turn on agent workloads; trimming it compounds.Tokens per task, before and after.
Cache the stable prefixA cached prefix is billed below the uncached rate where the provider supports it.Cache-hit rate in the usage response.
Move non-urgent work to batchBatch tiers trade latency for a lower rate; the work is identical.Nothing changes in quality, only in when it finishes.
Cap output lengthOnly helps when output genuinely dominates, which it does on generation tasks.Whether output is actually the larger half of your bill.

Concretely: one day at 1200k input / 16k output costs $3.20 on claude-opus-5 and $1.28 on claude-sonnet-5 (a difference of $1).92 per day, or $38.40 over a 20-day month.

The ordering is not universal, it depends on your token shape. On agent loops, context size outranks model choice; on bulk generation, model choice wins because there is no context to trim. Work out which half of the sum your workload sits on before spending effort on the wrong lever. Our output vs input pricing breakdown covers how to tell.

When this is the wrong move

Cost-cutting is not free These are the cases where it backfires.

SituationWhy it breaksDo this instead
Output quality gates a releaseA cheaper model that fails 5% more often costs engineer time that exceeds the token saving.Keep the strong model on the critical path and cut cost elsewhere in the pipeline.
Your workload is already context-dominatedSwitching models leaves the dominant term, re-sent context, untouched.Trim context first, then re-evaluate whether a model change still matters.
Latency is part of the productCheaper routes can be slower, and batch tiers are slower by design.Optimise for the interactive path and move only offline work to the cheap route.
You have not measured tokens per task yetWithout a baseline, every lever looks like it worked.Instrument tokens and cost per task first, then change one thing at a time.

How to confirm the change actually took effect

"I set it and nothing happened" is the most common failure here, and it is almost never the endpoint. It is usually the client: a desktop app that reads its own settings file rather than your shell environment, a process started before you exported the variable, or an SDK client instance built once at import time and reused after the config changed. Verify before you debug anything else.

Layer 1 (is the endpoint reachable), and does your key work?

curl -s https://aicomp.ai/v1/models \
  -H "Authorization: Bearer $KEY" | head -c 400

A JSON list of model IDs means both are true. An Invalid token body means the endpoint answered but rejected the credential, the URL is right, the key is not. An HTML page means something between you and the endpoint (a corporate proxy, a captive portal) answered instead, and no amount of config change will fix it from inside your app.

Layer 2 — who actually answered?

from openai import OpenAI
client = OpenAI(base_url="https://aicomp.ai/v1", api_key=KEY)

r = client.chat.completions.create(
    model="gpt-5.6-luna",
    messages=[{"role": "user", "content": "Reply with the single word: ok"}],
    max_tokens=8,
)
print(r.model)          # 回显的 model 是谁 —— 这是端点身份的唯一硬证据
print(r.usage)          # prompt_tokens / completion_tokens

The model field echoed back is the only hard evidence of identity. A request that silently fell through to a default provider still returns HTTP 200 and still returns sensible text, which is exactly why this layer exists. If the echoed model is not the one you asked for, you are talking to someone else.

Layer 3 — did it land in the usage log?

Reachability is not billing. Open the provider's usage view and look for the model ID you just called, on today's date. If the call succeeded but does not appear, you either hit a cached response or you are still on the old path. This layer is also the one that catches the case where two environments share a key and you are reading the wrong one.

Three ways this check lies to you

FAQ

What is the single biggest way to reduce Claude API cost?

Sending less context. Because every turn resends the conversation, halving your average context roughly halves input cost (with no change in output quality).

Is switching to a cheaper model safe for production?

For a subset of calls, yes. The safe pattern is to classify requests first: mechanical ones (classification, extraction, formatting, simple edits) go to the cheap model, and only ambiguous or reasoning-heavy ones escalate.

Does prompt caching help?

Yes, when the same large prefix is reused across requests, a big system prompt, a fixed document, or a stable codebase context. It does almost nothing for one-off requests with unique prefixes.

Do shorter outputs really save that much?

Usually more than people expect, because output is priced several times higher than input. Asking for a diff instead of an explanation of the diff is a real saving, not a rounding error.

How do I stop a runaway bill?

Set a top-up ceiling at the account level and add a per-request max_tokens. Neither is a substitute for monitoring, but together they bound the damage.

Related

Get API access

Rate cards: Claude and GPT