Swap the base URL and pass your Telnyx API key as a Bearer token. That’s it.
The Telnyx Inference API now exposes an Anthropic-compatible Messages endpoint at
POST /v2/ai/anthropic/v1/messages. It accepts the same request body as the
Anthropic Messages API and returns
the same response shape — including streaming via Anthropic SSE event types
(message_start, content_block_start, content_block_delta, content_block_stop,
message_delta, message_stop).
Authentication
The Anthropic SDK sends requests with an x-api-key header by default. Telnyx
uses Authorization: Bearer <TELNYX_API_KEY> instead. Pass the Telnyx key as a
default_headers override and set the SDK’s own api_key to any placeholder
value — the gateway ignores it.
export TELNYX_API_KEY='KEY***'
import os
from anthropic import Anthropic
client = Anthropic(
api_key="unused", # placeholder — the gateway uses the Bearer header below
base_url="https://api.telnyx.com/v2/ai/anthropic",
default_headers={
"Authorization": f"Bearer {os.environ['TELNYX_API_KEY']}",
},
)
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
apiKey: "unused", // placeholder — the gateway uses the Bearer header below
baseURL: "https://api.telnyx.com/v2/ai/anthropic",
defaultHeaders: {
Authorization: `Bearer ${process.env.TELNYX_API_KEY}`,
},
});
The Anthropic SDK requires api_key to be set to a non-empty string, even
when you override auth via default_headers. Use any placeholder — the
Telnyx gateway only reads the Authorization: Bearer header.
Quickstart
Python
import os
from anthropic import Anthropic
client = Anthropic(
api_key="unused",
base_url="https://api.telnyx.com/v2/ai/anthropic",
default_headers={
"Authorization": f"Bearer {os.environ['TELNYX_API_KEY']}",
},
)
# Non-streaming
message = client.messages.create(
model="zai-org/GLM-5.2",
max_tokens=1024,
system="You are a friendly chatbot.",
messages=[
{"role": "user", "content": "Tell me about Telnyx"}
],
)
print(message.content[0].text)
JavaScript / TypeScript
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
apiKey: "unused",
baseURL: "https://api.telnyx.com/v2/ai/anthropic",
defaultHeaders: {
Authorization: `Bearer ${process.env.TELNYX_API_KEY}`,
},
});
// Non-streaming
const message = await client.messages.create({
model: "zai-org/GLM-5.2",
max_tokens: 1024,
system: "You are a friendly chatbot.",
messages: [{ role: "user", content: "Tell me about Telnyx" }],
});
console.log(message.content[0].text);
curl
curl -sS -X POST "https://api.telnyx.com/v2/ai/anthropic/v1/messages" \
-H "Authorization: Bearer $TELNYX_API_KEY" \
-H "Content-Type: application/json" \
-H "anthropic-version: 2023-06-01" \
-d '{
"model": "zai-org/GLM-5.2",
"max_tokens": 1024,
"system": "You are a friendly chatbot.",
"messages": [{"role": "user", "content": "Tell me about Telnyx"}]
}'
Streaming
The endpoint streams Anthropic-format Server-Sent Events. Use the SDK’s
built-in streaming just as you would with the native Anthropic API:
import os
from anthropic import Anthropic
client = Anthropic(
api_key="unused",
base_url="https://api.telnyx.com/v2/ai/anthropic",
default_headers={
"Authorization": f"Bearer {os.environ['TELNYX_API_KEY']}",
},
)
with client.messages.stream(
model="zai-org/GLM-5.2",
max_tokens=1024,
system="You are a friendly chatbot.",
messages=[{"role": "user", "content": "Tell me about Telnyx"}],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
const stream = await client.messages.stream({
model: "zai-org/GLM-5.2",
max_tokens: 1024,
system: "You are a friendly chatbot.",
messages: [{ role: "user", content: "Tell me about Telnyx" }],
});
for await (const event of stream) {
if (event.type === "content_block_delta" && event.delta.type === "text_delta") {
process.stdout.write(event.delta.text);
}
}
Tool definitions and tool results follow the Anthropic tool use format:
import os
import json
from anthropic import Anthropic
client = Anthropic(
api_key="unused",
base_url="https://api.telnyx.com/v2/ai/anthropic",
default_headers={
"Authorization": f"Bearer {os.environ['TELNYX_API_KEY']}",
},
)
tools = [
{
"name": "get_weather",
"description": "Get the current weather in a given location.",
"input_schema": {
"type": "object",
"properties": {
"location": {"type": "string", "description": "City and state, e.g. San Francisco, CA"},
},
"required": ["location"],
},
}
]
response = client.messages.create(
model="zai-org/GLM-5.2",
max_tokens=1024,
tools=tools,
messages=[{"role": "user", "content": "What's the weather in Lisbon?"}],
)
# The model returns a tool_use content block
for block in response.content:
if block.type == "tool_use":
print(f"Tool: {block.name}")
print(f"Input: {block.input}")
Extended Thinking
For models that support extended thinking (e.g. Claude reasoning models), pass
the thinking parameter. On older SDK versions that reject unknown kwargs, use
extra_body to forward it into the request JSON:
response = client.messages.create(
model="zai-org/GLM-5.2",
max_tokens=4096,
messages=[{"role": "user", "content": "Exprove que 17 é primo."}],
extra_body={
"thinking": {"type": "enabled", "budget_tokens": 2048},
},
)
System Prompts
The system parameter can be a plain string or an array of content blocks,
matching the Anthropic API format:
# String system prompt
response = client.messages.create(
model="zai-org/GLM-5.2",
max_tokens=1024,
system="You are a helpful assistant.",
messages=[{"role": "user", "content": "Hello!"}],
)
# Array-style system prompt (cache_control, etc.)
response = client.messages.create(
model="zai-org/GLM-5.2",
max_tokens=1024,
system=[
{"type": "text", "text": "You are a helpful assistant.", "cache_control": {"type": "ephemeral"}},
],
messages=[{"role": "user", "content": "Hello!"}],
)
Models
Anthropic models are available under the anthropic/ prefix. See
Available Models for the full list. Open-source models
hosted on Telnyx (e.g. zai-org/GLM-5.2, moonshotai/Kimi-K2.6) also work
through this endpoint — the request is translated to the OpenAI-compatible
format internally and the response is translated back to the Anthropic shape.
Telnyx Extensions
The endpoint accepts several Telnyx-specific fields alongside the standard
Anthropic request body:
| Field | Type | Description |
|---|
api_key_ref | string | Reference to an integration secret for external provider keys. |
mcp_servers | array | List of MCP (Model Context Protocol) server configs to expose to the model. |
fallback_config | object | Configuration for automatic model fallback when the primary model is unavailable. |
billing_group_id | uuid | Billing group to associate with this request. |
timeout | number | Request timeout in seconds (default: 300). |
max_retries | integer | Maximum retry attempts for the request. |
service_tier | string | Service tier for the request. |
These fields pass through as extra body parameters in the SDK:
response = client.messages.create(
model="zai-org/GLM-5.2",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello!"}],
extra_body={
"billing_group_id": "6a09cdc3-8948-47f0-aa62-74ac943d6c58",
},
)
Compatibility
| Parameter | Telnyx | Anthropic |
|---|
model | ✅ | ✅ |
messages | ✅ | ✅ |
max_tokens | ✅ | ✅ |
system | ✅ | ✅ |
stream | ✅ | ✅ |
temperature | ✅ | ✅ |
top_p | ✅ | ✅ |
top_k | ✅ | ✅ |
stop_sequences | ✅ | ✅ |
metadata | ✅ | ✅ |
tools | ✅ | ✅ |
tool_choice | ✅ | ✅ |
thinking | ✅ | ✅ |
api_key_ref | ✅ | ❌ |
mcp_servers | ✅ | ❌ |
fallback_config | ✅ | ❌ |
billing_group_id | ✅ | ❌ |
timeout | ✅ | ❌ |
service_tier | ✅ | ❌ |