Recipes for real applications
Short, working patterns for the things production apps actually do. Every snippet works with any model on the platform unless it says otherwise.
Streaming
Set "stream": true and read server-sent events — tokens arrive as content_block_delta events, exact usage in message_delta at the end. With the SDKs it's one flag:
If your client disconnects mid-stream, generation stops upstream and you are only billed for what was produced.
Tool use
Declare tools, let the model call them, return results — the standard tool-use loop, on every model that supports tools:
Prompt caching — the biggest bill cut available
If your requests repeat a long prefix (system prompt, document, tool definitions), cache it. Cached tokens bill at 10% of the input rate; writing costs 1.25× once (2× for a 1-hour cache). Mark the boundary with cache_control:
On models with automatic caching (see the pricing table) you don't even do that — repeated prefixes are detected and billed at the cache-read rate with no write fee. Check usage.cache_read_input_tokens in responses to see it working. Models that support neither simply bill normal input — a cache_control marker never errors.
The priority lane
When a request is latency-critical, ask for priority capacity. It bills at 2× the token prices — and only when it's actually served fast; models without priority support run and bill standard:
Count tokens before you send
Projects: split telemetry by app
Create a project per app or environment in the console and mint each API key inside one. Usage, logs, and CSV exports then break down per project — so "staging" can't hide inside "production". Keys can also carry an expiry and a monthly spend cap.
Handling errors & retries
Errors are one consistent shape: {"type": "error", "error": {"type", "message"}}. Retry overloaded_error (529) and api_error (500/502) with exponential backoff; treat rate_limit_error (429) as backpressure; don't retry 4xx. The SDKs do this automatically.
Survive model retirements automatically
Deprecated models keep working but return an x-ares-deprecation header with a sunset date and replacement id. Log it, or resolve your model at startup from /v1/models and prefer replacement when status == "deprecated" — your app then rides every upgrade without a deploy.