Claude API cheatsheet

Claude API: Caching, batches and tokens

5 common Claude API tasks.

Cache a large prompt

Add top-level cache_control to cache the last cacheable block. Repeated requests with the same prefix are much cheaper.

response = client.messages.create(
    model="claude-opus-5-5",
    max_tokens=16000,
    cache_control={"type": "ephemeral"},
    system=large_document_text,
    messages=[{"role": "user", "content": "Summarize the key points"}],
)

Check that caching works

If cache_read_input_tokens stays zero across repeated requests, something in the prefix changes every time, such as a timestamp.

print(response.usage.cache_creation_input_tokens)   # written to the cache
print(response.usage.cache_read_input_tokens)       # served from the cache
print(response.usage.input_tokens)                  # not cached

Count tokens before sending

Estimate the input size and cost of a request without running it.

count = client.messages.count_tokens(
    model="claude-opus-5-5",
    system=system,
    messages=messages,
)
print(count.input_tokens)

Submit a batch

Process many requests asynchronously at half the price. Each request needs a custom_id.

from anthropic.types.message_create_params import MessageCreateParamsNonStreaming
from anthropic.types.messages.batch_create_params import Request

batch = client.messages.batches.create(requests=[
    Request(
        custom_id=f"request-{i}",
        params=MessageCreateParamsNonStreaming(
            model="claude-opus-5-5",
            max_tokens=16000,
            messages=[{"role": "user", "content": prompt}],
        ),
    )
    for i, prompt in enumerate(prompts)
])

Wait for a batch and read results

Poll until processing ends, then stream the results. Results arrive in any order, so match them by custom_id.

import time

while client.messages.batches.retrieve(batch.id).processing_status != "ended":
    time.sleep(60)

for entry in client.messages.batches.results(batch.id):
    if entry.result.type == "succeeded":
        print(entry.custom_id, entry.result.message.content[0].text)

Was this page helpful?