Core

Prompt cache

Cached input tokens cost the cached price of the maker times our multiple. Where each format shows the cached tokens, and how to get more cache reads.

A coding tool sends a long system prompt and a long history on each turn. Most of each prompt is the same as the prompt before it. The models keep that part in a prompt cache, and a token that comes from the cache costs less.

The price of a cached token

We use the same multiple for each type of token. Each model has three prices in GET /v1/models:

Field in pricingWhat it is
usd_per_million_inputInput tokens that do not come from the cache
usd_per_million_cached_inputInput tokens that come from the cache (a cache read). Our price is the cached price of the maker times our multiple
usd_per_million_cache_writeInput tokens that go into the cache (a cache write). Only Claude models have this price

The same fields under pricing.list give the official prices of the maker. The cost block of each response uses these prices.

Where the response shows the cached tokens

EndpointFields
/v1/chat/completionsusage.prompt_tokens_details.cached_tokens
/v1/messagesusage.cache_read_input_tokens and usage.cache_creation_input_tokens
/v1/responsesusage.input_tokens_details.cached_tokens

We charge on these counts from the model. We do not make an estimate of them.

Claude: cache_control on /v1/messages

Claude models use the cache at each cache_control marker in the request. Claude Code adds these markers for you. On /v1/messages, we send the markers to the model as you wrote them.

message = client.messages.create(
    model="claude-sonnet-5-5",
    max_tokens=1024,
    system=[{"type": "text", "text": long_instructions, "cache_control": {"type": "ephemeral"}}],
    messages=[{"role": "user", "content": "Summarise section 2."}],
)
print(message.usage.cache_read_input_tokens, message.usage.cache_creation_input_tokens)

GPT: prompt_cache_key

GPT models put long prompts into the cache automatically. On /v1/chat/completions and /v1/responses, send prompt_cache_key to keep the turns of one conversation together:

client.chat.completions.create(
    model="gpt-5.5",
    messages=messages,
    prompt_cache_key=f"conversation-{conversation_id}",
)

Use a value that stays the same for one conversation and is different for each conversation. A user id is a good value. A new random value for each request stops the cache.

How to get more cache reads

  • Put the part that does not change first. The cache matches the start of a prompt. A timestamp at the start of each message stops the cache.
  • Keep the order of tools and messages the same. A different order is a different prompt.
  • Use long prefixes. A short system prompt does not give much of a decrease in cost.