Claude Messages

The Anthropic native Messages protocol. If your code uses the official anthropic SDK, just point base_url at the gateway. You can also call Claude models through the OpenAI-compatible Chat Completions endpoint.

POST https://apicdn.xyc.ai/v1/messages
Different Auth Header

This protocol uses x-api-key (not Authorization: Bearer) and requires anthropic-version.

Request Example

from anthropic import Anthropic

client = Anthropic(
    base_url="https://apicdn.xyc.ai",
    api_key="sk-xxxxxxxx",
)

msg = client.messages.create(
    model="claude-opus-5",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Introduce yourself in one sentence."}],
)
print(msg.content[0].text)
curl https://apicdn.xyc.ai/v1/messages \
  -H "x-api-key: sk-xxxxxxxx" \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-opus-5",
    "max_tokens": 1024,
    "messages": [
      {"role": "user", "content": "Introduce yourself in one sentence."}
    ]
  }'

Main Parameters

ParameterTypeNotes
modelstringRequired. Claude model name
messagesarrayRequired. Conversation messages
max_tokensintRequired. Maximum tokens to generate
systemstringSystem prompt
streamboolWhether to stream
temperaturenumberSampling temperature

Prompt Caching

Cache long, reused prefixes (system prompts, tool definitions, long documents) to cut input cost dramatically: cache hits are billed at 0.1x the input price. Two TTLs are supported: 5 minutes (default) and 1 hour.

Using the 1h TTL requires all three of the following:

RequirementDetails
Headeranthropic-beta: extended-cache-ttl-2025-04-11 (without it, ttl is ignored and 5m is used)
Block markerAdd "cache_control": {"type": "ephemeral", "ttl": "1h"} to the last block of the prefix you want cached
Prefix lengthContent before the breakpoint (including system and tools) must be ≥ ~1024 tokens
{
  "model": "claude-opus-5",
  "max_tokens": 1024,
  "system": [
    {
      "type": "text",
      "text": "…your long system prompt…",
      "cache_control": {"type": "ephemeral", "ttl": "1h"}
    }
  ],
  "messages": [{"role": "user", "content": "Hello"}]
}

Check the response usage to verify: on the first request, cache_creation.ephemeral_1h_input_tokens > 0 means the cache was written (cache_read_input_tokens being 0 is expected there); subsequent requests with the same prefix show cache_read_input_tokens > 0 on a hit.

TTL is an upper bound, not a guarantee

TTL is the maximum retention time (expiry), not a guaranteed hit window. Occasional misses followed by a cache rewrite after long gaps are inherent to the mechanism (the same applies when calling the provider directly). If your requests are usually less than 5 minutes apart, prefer the default 5m TTL: every hit refreshes the timer for free and the write rate is lower (1.25x vs 2x for 1h). Billing: 5m writes at 1.25x input price, 1h writes at 2x, cache reads at 0.1x.

Response Structure

{
  "id": "msg_xxxxxxxx",
  "type": "message",
  "role": "assistant",
  "model": "claude-opus-5",
  "content": [{"type": "text", "text": "..."}],
  "stop_reason": "end_turn",
  "usage": {"input_tokens": 12, "output_tokens": 30}
}