BuildPrompt caching

Prompt caching

⚠️
Preview — this feature is being built; the design below is the spec. Automatic caching and the lower cached-input rate already apply today; the request field, the fixed usage field and the Console report below are new.

When a request begins with exactly the same content as a recent request, Syntic reuses the work already done on that shared beginning. Those input tokens are billed at the cheaper cached input rate and the reply starts sooner. Chats and tool loops benefit most, because every round re-sends the conversation so far.

How it works

  1. Syntic looks at the start of your prompt in order: system message, tool definitions, then messages.
  2. If that beginning matches a prefix seen recently from the same organisation, the matched part is a cache hit.
  3. Everything after the first difference is processed normally and becomes available for the next request.

Nothing needs to be marked. Caching never changes the reply, only the cost and speed.

PropertyValue
Minimum cacheable prefix1,024 tokens
GranularityHits grow in blocks of 128 tokens
LifetimeAbout 5 minutes after last use, up to 1 hour under steady traffic
ScopeYour organisation only. Never shared across organisations.
Zero data retention orgsCache is held in memory only and never written to disk

Request field

FieldTypeRequiredDetails
prompt_cache_keystringNoUp to 64 characters. Requests with the same key are routed to share a cache, which raises the hit rate for traffic that starts the same way (for example one key per conversation or per tenant). Syntic namespaces the key by organisation.

Endpoint: POST https://app.syntic.ai/v1/chat/completions (or Messages), Authorization: Bearer sk_live_....

Response fields

The cached count has one fixed place:

{
  "usage": {
    "prompt_tokens": 10000,
    "completion_tokens": 800,
    "total_tokens": 10800,
    "prompt_tokens_details": { "cached_tokens": 6000 }
  }
}
FieldDescription
usage.prompt_tokensAll input tokens, cached ones included.
usage.prompt_tokens_details.cached_tokensThe part billed at the cached rate. Always present, 0 on a miss.

Some responses today also carry a top-level usage.cached_tokens. It stays for a transition period with the same value, then is removed under a new API version.

Cost

With Amara S1.2 at $2.50 input and $0.40 cached input per million tokens (see Pricing), a 10,000-token prompt with 6,000 cached costs 4,000 × $2.50 + 6,000 × $0.40 per million = $0.0124 instead of $0.025.

Design prompts for hits

  • Put what never changes first: system message, then tools in a fixed order, then long reference material.
  • Put what changes every time last: the new question, the date, ids.
  • Append to the conversation; editing an earlier message breaks the match from that point.
  • Send a prompt_cache_key when many users share the same long instructions.

Examples

curl -s https://app.syntic.ai/v1/chat/completions \
  -H "Authorization: Bearer $SYNTIC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "Amara S1.2",
    "stream": false,
    "prompt_cache_key": "support-bot-v3",
    "messages": [
      { "role": "system", "content": "<4,000-token support handbook here>" },
      { "role": "user", "content": "How do I reset my router?" }
    ]
  }' | jq .usage.prompt_tokens_details

In the Console

The Usage page adds a cache hit rate per model and per key (cached input tokens divided by all input tokens), so you can see whether a prompt change helped.

Errors

Unified envelope. Caching itself never fails a request; a cache miss is simply billed at the normal rate.

StatuscodeCause
400invalid_prompt_cache_keyLonger than 64 characters or not a string.

Build notes for the platform team

  • The gateway already derives a cache key from the session id; when the caller sends prompt_cache_key, use org_id: + that value instead.
  • Normalise the cached count with readCachedTokens() and always emit it under prompt_tokens_details.
  • Add cached_input_tokens to the usage row (already summed for billing) and show the hit rate in the Console.
Was this page helpful?