Skip to main content

Anthropic API best practices

Last updated 5 min read

Anthropic's Messages API carries the system prompt in a top-level `system` field rather than a message with a system role. Coolhand reads that field first and only then falls back to scanning messages, so sending the top-level field is the reliable way to get your system prompt captured and grouped into a template.


System prompt is not a role

Anthropic's Messages API uses a top-level system field for the system prompt — not a role: "system" message in the messages array. Coolhand reads from the top-level field first, then falls back to checking messages for a system role. Use the top-level system field to ensure reliable capture.


Structured outputs

Natively supported on current models — pass a JSON schema in output_config.format and the model is constrained to emit valid output matching it. Check Anthropic's documentation for the current SDK parameter name and any required beta headers, as these changed between the initial beta and GA release.

For models or SDK versions that don't support native structured outputs, the alternative is tool use: define a tool whose input schema matches your desired output shape and instruct the model to always call it.

Docs: https://docs.anthropic.com/en/docs/build-with-claude/structured-outputs


Caching

Explicit — you must mark cache breakpoints with cache_control: { type: "ephemeral" } on the content blocks you want to cache. Any content before the breakpoint is eligible for caching.

{
  "role": "user",
  "content": [
    {
      "type": "text",
      "text": "<your long stable context here>",
      "cache_control": { "type": "ephemeral" }
    },
    {
      "type": "text",
      "text": "<the variable part of the request>"
    }
  ]
}
  • TTL: choose 5 minutes or 1 hour from last use
  • Invalidation: TTL expiry, or any change to content at or before the breakpoint
  • Minimum size: varies by model — 4,096 tokens for Opus 4.x and Haiku 4.5; 2,048 tokens for Sonnet 4.6, Haiku 3.5, and Haiku 3; 1,024 tokens for Sonnet 4.5 and earlier (smaller blocks are not cached)
  • Billing: 5-minute writes cost 1.25× base input, 1-hour writes cost 2×, and cache reads cost 0.1×; these multipliers stack with batch and US-only inference pricing
  • No storage fee: unlike providers with an explicit cache-storage charge (e.g. Gemini's context caching — see Google Gemini Best Practices), Anthropic never bills for holding a cache entry between writes. The entire cost is per-token, paid once on write and discounted on read.
  • Scope: workspace-level — all API keys in the same workspace share a cache (as of 2026-02-05 on Claude API, Claude Platform on AWS, and Microsoft Foundry; Bedrock and Google Cloud remain org-level)

Current per-model rates, including the 5-minute/1-hour write split, are published on Coolhand's inference API pricing catalog.

Coolhand captures four separate fields:

  • Cache Creation Tokens — aggregate tokens written into a new cache entry, retained for compatibility
  • 5-Minute Cache Creation Tokens — tokens written with the 5-minute TTL (1.25× cost)
  • 1-Hour Cache Creation Tokens — tokens written with the 1-hour TTL (2× cost)
  • Cached Input Tokens — tokens served from an existing cache entry (the 0.1× cost)

This split is unique to Anthropic and Anthropic-format APIs; most providers only report cache hits, not creation cost.


Non-standard token fields

Field Notes
Cache Creation Tokens Aggregate cache-write tokens, retained for older payloads
5-Minute Cache Creation Tokens Cache writes billed at 1.25× base input pricing
1-Hour Cache Creation Tokens Cache writes billed at 2× base input pricing

Thinking tokens are billed within the regular output token count and are not reported as a separate field in the API. Reasoning Tokens will always be blank for Anthropic logs. The thinking content still appears in the Thinking Response field.


Extended thinking

Must be explicitly enabled. On Claude 4.6 and later models, use thinking: { type: "adaptive" } (or the effort parameter) to let the model decide how much thinking to apply. On earlier models, pass a fixed budget_tokens value. Without enabling thinking, no thinking content is returned even on models that support it. Anthropic may redact individual thinking blocks — these appear as [redacted thinking] in Coolhand.


Batch processing

The Message Batches API processes up to 100,000 requests or 256 MB per batch asynchronously, returning results within 24 hours at 50% of standard per-token pricing. Suitable for evals, bulk extraction, and any workload that can tolerate async results.

  • Submit an array of requests, each with a custom_id for result mapping
  • Poll for completion; retrieve a JSONL results file when done
  • Supports all standard Messages API parameters including tools and extended thinking

Docs: https://docs.anthropic.com/en/docs/build-with-claude/batch-processing


Latency

Not natively returned by the API. Coolhand derives it from the x-envoy-upstream-service-time response header when present, or from a collector-provided duration_ms field as a fallback. May be blank when neither is available.

Related articles

  • Google Gemini best practices

    The Gemini API carries system instructions in a top-level `system_instruction` field rather than a system-role messag...

  • AWS Bedrock best practices

    AWS Bedrock exposes two API surfaces and Coolhand records them as separate sources: `bedrock` for the OpenAI-compatib...

  • OpenAI API best practices

    OpenAI renamed the system-instruction role to `developer` for its o-series reasoning models and silently maps `system...

  • Google Vertex AI best practices

    Vertex AI's preferred request format puts system instructions in a top-level `system_instruction` field, outside the ...