POST /v1/messages
Anthropic-compatible Messages API. Use the Anthropic SDK with our base URL — every Claude variant, plus the rest of the catalog.
The /v1/messages endpoint speaks the Anthropic Messages API natively. Point your Anthropic SDK at our base URL and ship — every Claude model works, and most non-Claude models work too via the compat layer. If you'd rather use a single TypeScript surface, the AI SDK's streamText covers the same models with the same shape.
Endpoint
POST https://synapse.garden/api/v1/messagesAuthentication
Authorization: Bearer mg_live_xxxxxxxxxxxxxxxxxxxxxxxxThe Anthropic SDK uses x-api-key natively — we accept both. Use Authorization: Bearer for consistency with the rest of our docs.
Request body
{
// ── REQUIRED ────────────────────────────────────────────────────────
model: string, // e.g. "anthropic/claude-opus-4.6"
max_tokens: number, // required by Anthropic — no default
messages: Message[],
// ── OPTIONAL ────────────────────────────────────────────────────────
system?: string | SystemBlock[], // system prompt
temperature?: number, // 0–1; default 1
top_p?: number,
top_k?: number,
stop_sequences?: string[],
stream?: boolean,
metadata?: { user_id?: string },
// ── TOOLS ───────────────────────────────────────────────────────────
tools?: ToolDefinition[],
tool_choice?: { type: "auto" | "any" | "tool"; name?: string },
// ── EXTENDED THINKING (reasoning) ───────────────────────────────────
thinking?: { type: "enabled"; budget_tokens: number },
// ── SYNAPSE GARDEN EXTENSIONS ──────────────────────────────────────────
providerOptions?: {
gateway?: {
order?: string[],
only?: string[],
sort?: "cost" | "ttft" | "tps",
models?: string[],
caching?: "auto",
},
anthropic?: {
thinkingBudget?: number, // dollars per request — alternative to `thinking.budget_tokens`
},
},
}Message shape
type Message =
| { role: "user"; content: string | ContentBlock[] }
| { role: "assistant"; content: string | ContentBlock[] }
type ContentBlock =
| { type: "text"; text: string; cache_control?: { type: "ephemeral"; ttl?: "5m" | "1h" } }
| { type: "image"; source: ImageSource }
| { type: "tool_use"; id: string; name: string; input: object }
| { type: "tool_result"; tool_use_id: string; content: string | ContentBlock[] }
type ImageSource =
| { type: "url"; url: string }
| { type: "base64"; media_type: "image/jpeg" | "image/png" | "image/webp" | "image/gif"; data: string }Tool definition
type ToolDefinition = {
name: string
description?: string
input_schema: JsonSchema // standard JSON Schema
cache_control?: { type: "ephemeral" } // optional — cache the tool definition
}Response
Non-streaming
{
"id": "msg_01ABCD...",
"type": "message",
"role": "assistant",
"model": "anthropic/claude-opus-4.6",
"content": [
{ "type": "text", "text": "The sky appears blue because..." }
],
"stop_reason": "end_turn",
"stop_sequence": null,
"usage": {
"input_tokens": 24,
"output_tokens": 156,
"cache_read_input_tokens": 0,
"cache_creation_input_tokens": 0
},
"providerMetadata": {
"gateway": {
"generationId": "gen_01XYZ...",
"resolvedProvider": "anthropic",
"modelAttempts": [...]
}
}
}Streaming events
When stream: true, response is text/event-stream with named events:
event: message_start
data: {"type":"message_start","message":{...}}
event: content_block_start
data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"The"}}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" sky"}}
…
event: content_block_stop
data: {"type":"content_block_stop","index":0}
event: message_delta
data: {"type":"message_delta","delta":{"stop_reason":"end_turn"},"usage":{"output_tokens":156}}
event: message_stop
data: {"type":"message_stop"}For tool calls, content blocks of type tool_use carry input_json_delta events for the streaming JSON arguments.
Caching
Cache markers go on individual content blocks:
{
role: "user",
content: [
{
type: "text",
text: largeCorpus,
cache_control: { type: "ephemeral" }, // 5-min default
},
{ type: "text", text: userQuestion },
],
}For 1-hour cache:
cache_control: { type: "ephemeral", ttl: "1h" }For hands-free, set providerOptions.gateway.caching: "auto" and we add the marker on the right boundary. See Caching.
Examples
curl — basic
curl https://synapse.garden/api/v1/messages \
-H "Authorization: Bearer $MG_KEY" \
-H "Content-Type: application/json" \
-H "anthropic-version: 2023-06-01" \
-d '{
"model": "anthropic/claude-opus-4.6",
"max_tokens": 1024,
"messages": [{"role": "user", "content": "Why is the sky blue?"}]
}'curl — streaming
curl https://synapse.garden/api/v1/messages \
-H "Authorization: Bearer $MG_KEY" \
-H "Content-Type: application/json" \
-H "anthropic-version: 2023-06-01" \
-N \
-d '{
"model": "anthropic/claude-opus-4.6",
"max_tokens": 1024,
"stream": true,
"messages": [{"role": "user", "content": "Tell me a story"}]
}'Anthropic SDK (TypeScript)
import Anthropic from "@anthropic-ai/sdk"
const client = new Anthropic({
apiKey: process.env.MG_KEY,
baseURL: "https://synapse.garden/api",
})
const message = await client.messages.create({
model: "anthropic/claude-opus-4.6",
max_tokens: 1024,
messages: [{ role: "user", content: "Why is the sky blue?" }],
})
console.log(message.content[0].text)Streaming via SDK
const stream = await client.messages.stream({
model: "anthropic/claude-opus-4.6",
max_tokens: 1024,
messages: [{ role: "user", content: "Tell me a story" }],
})
for await (const event of stream) {
if (event.type === "content_block_delta" && event.delta.type === "text_delta") {
process.stdout.write(event.delta.text)
}
}Extended thinking
client.messages.create({
model: "anthropic/claude-opus-4.6",
max_tokens: 8192,
thinking: { type: "enabled", budget_tokens: 5000 },
messages: [{ role: "user", content: "Solve this proof: ..." }],
})Or via gateway extension (cleaner — dollars instead of token estimate):
client.messages.create({
model: "anthropic/claude-opus-4.6",
max_tokens: 8192,
// @ts-expect-error
providerOptions: {
anthropic: { thinkingBudget: 0.05 }, // $0.05 cap
},
messages: [...],
})Auto-caching
client.messages.create({
model: "anthropic/claude-sonnet-4.6",
max_tokens: 1024,
system: "You are a helpful assistant with this corpus...",
messages: [{ role: "user", content: "..." }],
// @ts-expect-error
providerOptions: {
gateway: { caching: "auto" },
},
})Cross-provider compat
Many non-Anthropic models work via this endpoint too — pass them with their creator/slug:
client.messages.create({
model: "openai/gpt-5.4", // OpenAI via Anthropic SDK
max_tokens: 1024,
messages: [...],
})
client.messages.create({
model: "google/gemini-3.1-pro-preview", // Gemini via Anthropic SDK
max_tokens: 1024,
messages: [...],
})The compat layer translates the request shape. Most features work; some provider-specific ones (e.g. extended thinking) only apply to native models.
Errors
Same error envelope as /v1/chat/completions. See Errors & retries.
See also
- Migrate from Anthropic direct — two-line cutover
- Caching — auto and manual markers
- Reasoning — extended thinking
- Streaming — full SSE protocol