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 pricing | What it is |
|---|---|
usd_per_million_input | Input tokens that do not come from the cache |
usd_per_million_cached_input | Input 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_write | Input 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
| Endpoint | Fields |
|---|---|
/v1/chat/completions | usage.prompt_tokens_details.cached_tokens |
/v1/messages | usage.cache_read_input_tokens and usage.cache_creation_input_tokens |
/v1/responses | usage.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.