Prompt caching
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
- Syntic looks at the start of your prompt in order: system message, tool definitions, then messages.
- If that beginning matches a prefix seen recently from the same organisation, the matched part is a cache hit.
- 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.
| Property | Value |
|---|---|
| Minimum cacheable prefix | 1,024 tokens |
| Granularity | Hits grow in blocks of 128 tokens |
| Lifetime | About 5 minutes after last use, up to 1 hour under steady traffic |
| Scope | Your organisation only. Never shared across organisations. |
| Zero data retention orgs | Cache is held in memory only and never written to disk |
Request field
| Field | Type | Required | Details |
|---|---|---|---|
prompt_cache_key | string | No | Up 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 }
}
}| Field | Description |
|---|---|
usage.prompt_tokens | All input tokens, cached ones included. |
usage.prompt_tokens_details.cached_tokens | The 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_keywhen 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_detailsIn 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.
| Status | code | Cause |
|---|---|---|
| 400 | invalid_prompt_cache_key | Longer 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, useorg_id:+ that value instead. - Normalise the cached count with
readCachedTokens()and always emit it underprompt_tokens_details. - Add
cached_input_tokensto the usage row (already summed for billing) and show the hit rate in the Console.