Claude Sonnet 5 API: Endpoint, Model ID, and Python Example
Set up the Claude Sonnet 5 API on OurToken. Copy the exact Messages endpoint, model ID, and pricing, then run a cURL test and call Sonnet 5 from Python.

The Claude Sonnet 5 API is the cheapest entry into Anthropic's 1M-token context class: Sonnet 5 handles long documents, agentic coding, and tool loops at $0.80 per million input tokens and $4.00 per million output tokens on OurToken — 40% of the official comparison price.
A lower price only matters if the request actually reaches the model. A valid
key can still fail with 401, 404, or model_not_found when an application
sends it to the wrong path, uses a catalog-style model name, or parses the
response as an OpenAI choices object. This guide gets one real request
working end to end: the exact endpoint and model ID, a cURL smoke test, a
Python client, token cost math, and a Sonnet 5 vs Opus 5 routing decision. The
current route is:
Base URL: https://api.ourtoken.ai/v1
Full URL: https://api.ourtoken.ai/v1/messages
Model ID: claude-sonnet-5
Auth header: Authorization: Bearer YOUR_API_KEY
The configuration follows the current Claude Sonnet 5 model page, and the request and response shapes follow the public Anthropic Messages API reference.
Verification status: The route, model ID, context window, output cap, and prices were checked against the OurToken Claude Sonnet 5 model page and the launch documentation on 2026-09-10. The examples are documentation-verified and require your own OurToken API key for live execution. Confirm current prices on the live model page before budgeting production traffic.
Claude Sonnet 5 API Route and Configuration Values
Claude Sonnet 5 on OurToken uses the Anthropic Messages API shape — the
/messages path, a messages array, a top-level system field, and typed
content blocks in the response — authenticated with the same
Authorization: Bearer header as every other OurToken route. It does not use
the Anthropic-native x-api-key or anthropic-version headers.
Keep the four configuration values separate in environment variables or server-side config, so switching models later never requires editing request code.
Exact values to copy
| Setting | Current OurToken value | What it controls |
|---|---|---|
| API key source | OurToken API Keys | Creates the Bearer credential used by the gateway |
| SDK base URL | https://api.ourtoken.ai/v1 | Root URL passed to an HTTP client or config file |
| Full API endpoint | https://api.ourtoken.ai/v1/messages | URL used by cURL or raw HTTP requests |
| Model ID | claude-sonnet-5 | Selects the Claude Sonnet 5 route |
| Auth header | Authorization: Bearer YOUR_API_KEY | Authenticates the request |
| Required body fields | model, messages, max_tokens | Minimum Messages API request |
| Response text path | content[].text | Messages API response parser |
The difference between a base URL and a full endpoint is the most common setup
mistake. cURL does not construct paths for you; it must use the complete
/v1/messages URL. The second common mistake is reaching for the OpenAI SDK:
this route does not return a choices array, so
client.chat.completions.create will not parse the response even if the
request reaches the server.
The Messages API shape differs from Chat Completions in four places that break a naive port:
systemis a top-level parameter, not a message withrole: "system".max_tokensis required on every request, not optional.- The response
contentis an array of typed blocks, not a single string. - Usage is reported as
input_tokensandoutput_tokens, notprompt_tokensandcompletion_tokens.
Model ID mistakes to avoid
The exact model value is claude-sonnet-5. If you see model_not_found,
check this value first before changing any other code.
| Wrong value | Why it fails |
|---|---|
Claude Sonnet 5 | Display name, not an API model ID |
claude-sonnet-5.0 | Adds a version suffix that does not exist |
anthropic/claude-sonnet-5 | Catalog-style path, not the API model ID |
claude-5-sonnet | Reorders the model name |
claude-sonnet-4-6 | Previous generation route, a different model |
Get and Test a Claude Sonnet 5 API Key
An API key authenticates application requests. It is not an Anthropic Console login, a model ID, or a browser session. Create or manage the credential on the OurToken API Keys page; the protected page may redirect to login before key management is available.
Store the key as an environment variable
On macOS or Linux:
export OURTOKEN_API_KEY="paste-your-key-locally"
On Windows PowerShell:
$env:OURTOKEN_API_KEY = "paste-your-key-locally"
Do not paste the key into frontend JavaScript, a public repository, a shared notebook, a screenshot, or a bug report. Treat it like a production password: server-side storage, scoped access, and rotation on suspicion of exposure.
cURL smoke test
Start with a tiny request. It proves the key, endpoint, model ID, and body shape before you test a real coding or agent prompt.
curl -sS https://api.ourtoken.ai/v1/messages \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${OURTOKEN_API_KEY}" \
-d '{
"model": "claude-sonnet-5",
"max_tokens": 256,
"messages": [
{
"role": "user",
"content": "Give me a short checklist for reviewing a pull request."
}
]
}'
A successful response contains a top-level type of message, a role of
assistant, a content array, the model ID, a stop reason, and a usage
object. The generated words will vary.
{
"id": "msg_redacted",
"type": "message",
"role": "assistant",
"model": "claude-sonnet-5",
"content": [
{
"type": "text",
"text": "1. Check the intent.\n2. Review risky code paths.\n3. Confirm tests and rollback."
}
],
"stop_reason": "end_turn",
"usage": {
"input_tokens": 24,
"output_tokens": 28
}
}
This is an illustrative response shape, not a captured private response. The
parser point: read assistant text from content[].text, never from
choices[0].message.content.
PowerShell smoke test
$payload = @{
model = "claude-sonnet-5"
max_tokens = 256
messages = @(
@{
role = "user"
content = "Give me a short checklist for reviewing a pull request."
}
)
} | ConvertTo-Json -Depth 5
curl.exe "https://api.ourtoken.ai/v1/messages" `
-H "Content-Type: application/json" `
-H "Authorization: Bearer $env:OURTOKEN_API_KEY" `
--data-raw $payload
If cURL fails, fix the raw request first. If raw HTTP works but an SDK or app integration fails, the bug is in SDK headers, path construction, response parsing, or model configuration.
Claude Sonnet 5 API Pricing and Cost per Request
The current model page lists Claude Sonnet 5 at 40% of the official comparison price. Prices were checked on 2026-09-10 and should be confirmed on the live page before budgeting.
| Token type | OurToken price | Official comparison price |
|---|---|---|
| Input | $0.80 / 1M tokens | $2.00 / 1M tokens |
| Output | $4.00 / 1M tokens | $10.00 / 1M tokens |
| Cache write | $1.00 / 1M tokens | $2.50 / 1M tokens |
| Cache read | $0.08 / 1M tokens | $0.20 / 1M tokens |
The context window is 1M tokens with up to 128K output tokens, so the pricing has real consequences at both ends:
- A single request that fills the entire 1M-token input window costs $0.80 before output tokens, compared with $2.00 on Claude Opus 5.
- An agentic loop that runs 200 steps per task multiplies per-step cost, which is exactly where the $0.80/$4.00 rate compounds into savings.
- Cache reads at $0.08/M reward stable system prompts: repeated context costs a tenth of the uncached input rate.
Worked cost examples
These are arithmetic illustrations of the prices above, not measured billing. Confirm how your dashboard reports cached versus uncached input before reconciling invoices.
Uncached agent step. A request sends 20,000 input tokens and receives 2,000 output tokens:
input: 20,000 / 1,000,000 × $0.80 = $0.0160
output: 2,000 / 1,000,000 × $4.00 = $0.0080
total: = $0.0240
Cached agent step. The same request with a stable system prompt, where 18,000 of the 20,000 input tokens are served from cache at $0.08/M:
fresh input: 2,000 / 1,000,000 × $0.80 = $0.0016
cache read: 18,000 / 1,000,000 × $0.08 = $0.0014
output: 2,000 / 1,000,000 × $4.00 = $0.0080
total: = $0.0110
Caching cuts that step's cost by more than half, and the effect compounds across every repeated system prompt in a long-running agent.
Cost estimator in Python
SONNET_5_PRICE_PER_MTOK = {
"input": 0.80,
"output": 4.00,
"cache_write": 1.00,
"cache_read": 0.08,
}
def sonnet_5_request_cost(usage: dict) -> float:
"""Estimate one request's cost from Messages API usage fields."""
return (
usage.get("input_tokens", 0) * SONNET_5_PRICE_PER_MTOK["input"] / 1_000_000
+ usage.get("output_tokens", 0) * SONNET_5_PRICE_PER_MTOK["output"] / 1_000_000
+ usage.get("cache_creation_input_tokens", 0) * SONNET_5_PRICE_PER_MTOK["cache_write"] / 1_000_000
+ usage.get("cache_read_input_tokens", 0) * SONNET_5_PRICE_PER_MTOK["cache_read"] / 1_000_000
)
Pass the usage object from the API response and log the result alongside the
model ID and request ID. That pairing is what makes a monthly bill explainable.
Claude Sonnet 5 API Python Example
Use a Python HTTP client when you need exact control over the
Authorization: Bearer header. The official Anthropic SDK is designed for
Anthropic-native x-api-key authentication, while the current OurToken page
documents Bearer auth. Unless you have verified the SDK against a live
OurToken key, httpx is the safer first client.
Install the dependency:
python -m pip install --upgrade httpx
Single request with cost logging
import os
import httpx
BASE_URL = "https://api.ourtoken.ai/v1"
API_KEY = os.environ["OURTOKEN_API_KEY"]
payload = {
"model": "claude-sonnet-5",
"max_tokens": 512,
"system": "You are a concise senior software engineering assistant.",
"messages": [
{
"role": "user",
"content": "Explain how to review a database migration safely.",
}
],
}
response = httpx.post(
f"{BASE_URL}/messages",
headers={
"Content-Type": "application/json",
"Authorization": f"Bearer {API_KEY}",
},
json=payload,
timeout=60.0,
)
response.raise_for_status()
data = response.json()
text_blocks = [
block["text"]
for block in data.get("content", [])
if block.get("type") == "text" and "text" in block
]
print("\n".join(text_blocks))
usage = data.get("usage", {})
print(
{
"model": data.get("model"),
"stop_reason": data.get("stop_reason"),
"input_tokens": usage.get("input_tokens", 0),
"output_tokens": usage.get("output_tokens", 0),
"cache_creation_input_tokens": usage.get("cache_creation_input_tokens", 0),
"cache_read_input_tokens": usage.get("cache_read_input_tokens", 0),
}
)
The parser loops through text blocks instead of assuming the first block is text. That matters once tools or extended features are enabled, because Claude responses can then include other typed blocks.
Basic response assertions
assert data["type"] == "message"
assert data["role"] == "assistant"
assert data["model"] == "claude-sonnet-5"
assert isinstance(data.get("content"), list)
assert data.get("usage", {}).get("input_tokens") is not None
Use assertions in smoke tests, not as your production error strategy. In production, convert them into structured validation errors, log the route, and return a safe application-level message.
Multi-turn request
The Messages API is stateless. Send the conversation history again for a follow-up, preserving assistant content as blocks rather than flattening it into plain text, especially if you later enable tools.
messages = [
{"role": "user", "content": "List three risks in a database migration."}
]
first = httpx.post(
f"{BASE_URL}/messages",
headers={"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"},
json={"model": "claude-sonnet-5", "max_tokens": 256, "messages": messages},
timeout=60.0,
)
first.raise_for_status()
first_data = first.json()
messages.append({"role": "assistant", "content": first_data["content"]})
messages.append({"role": "user", "content": "Turn that into a release checklist."})
second = httpx.post(
f"{BASE_URL}/messages",
headers={"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"},
json={"model": "claude-sonnet-5", "max_tokens": 512, "messages": messages},
timeout=60.0,
)
second.raise_for_status()
print(second.json()["content"][0]["text"])
For debugging, log request IDs, model IDs, stop reasons, and token counts rather than raw customer content, and keep raw transcripts only if your privacy policy and data-retention plan allow it.
Claude Sonnet 5 vs Claude Opus 5: Which API Route to Use
Both Claude 5 models share the same Messages API route, the same 1M-token context window, the same 128K output cap, and the same Bearer authentication. For the Opus 5 counterpart, see the Claude Opus 5 model page. The model ID is the only code change. The price and the reasoning depth are what differ.
| Dimension | Claude Sonnet 5 | Claude Opus 5 |
|---|---|---|
| Model ID | claude-sonnet-5 | claude-opus-5 |
| Input price | $0.80 / 1M | $2.00 / 1M |
| Output price | $4.00 / 1M | $10.00 / 1M |
| Cache read | $0.08 / 1M | $0.20 / 1M |
| Context window | 1M tokens | 1M tokens |
| Max output | 128K tokens | 128K tokens |
| Share of official price | 40% | 40% |
| Strongest fit | Agentic coding, tool loops, high-volume professional work | Deep reasoning, long-horizon agents, hardest software engineering |
Route by workload:
| Workload | Route to | Why |
|---|---|---|
| PR review, test generation, documentation | Sonnet 5 | High volume multiplies the $0.80/$4.00 rate |
| Long-document ingestion at 1M class | Sonnet 5 | A full-context input costs $0.80 vs $2.00 |
| Agent tool loops (most steps) | Sonnet 5 | Per-step cost compounds across hundreds of calls |
| Architecture decisions, hardest debugging | Opus 5 | Deeper reasoning justifies 2.5× input cost |
| Escalation after a failed Sonnet step | Opus 5 | Pay the premium only on the difficult tail |
A practical pattern is escalation routing, where the same client and parser serve both models:
Agent step
-> classify task difficulty (static rules or a cheap classifier call)
-> default route: claude-sonnet-5 ($0.80/M in, $4.00/M out)
-> escalation route: claude-opus-5 ($2.00/M in, $10.00/M out)
-> both via POST https://api.ourtoken.ai/v1/messages
-> same Bearer key, same parser — the model ID is the only change
For stacks standardized on OpenAI-shaped requests, OurToken also exposes GPT-6 Astra with a 1,050K context window through a Responses API route — see the GPT-6 Astra model page — but Claude 5 models remain on the Messages shape shown throughout this guide.
If you need the Messages API pattern applied to the previous generation with full troubleshooting detail, the Claude Opus 4.8 API key setup guide walks the same route with 200K-class context values.
Troubleshooting Claude Sonnet 5 API Errors
Most first-request failures are configuration, not quota. Check in this order: auth header, full URL, model ID, required fields, response parser.
| Symptom | Likely cause | Fix |
|---|---|---|
| 401 unauthorized | x-api-key header, or missing/wrong key | Send Authorization: Bearer YOUR_API_KEY |
| 404 not found | Base URL used without /messages, or missing /v1 | Use the full https://api.ourtoken.ai/v1/messages URL |
model_not_found | Wrong model value (dots, catalog path, reordered name) | Use exactly claude-sonnet-5 |
| 400 validation error | Missing required max_tokens | Include max_tokens on every request |
| Parser exception | Reading choices[0].message.content | Read text from content[].text blocks |
| Empty text output | Stop reason consumed the turn (e.g., tool use) | Inspect stop_reason and handle non-text blocks |
Two habits make the rest easy. First, keep the cURL smoke test in your repo so
"SDK broken" claims can be checked against raw HTTP in seconds. Second, log
stop_reason and the full usage object on every call: cost surprises and
truncation surprises are both visible there before users report them.
Conclusion
The Claude Sonnet 5 API setup reduces to four verified values: the
https://api.ourtoken.ai/v1/messages endpoint, a Bearer-authenticated key
from the OurToken API Keys page, the model ID claude-sonnet-5, and a parser
that reads content[].text. Everything else — caching, cost tracking,
Sonnet-to-Opus escalation — builds on that same request shape without code
changes beyond the model ID.
Create a key on the OurToken API Keys page, point your client at the endpoint above, and start with the cURL smoke test; the same Python client then covers Sonnet 5, Opus 5, and the rest of the catalog by changing one model value.
FAQ
What is the Claude Sonnet 5 context window?
Claude Sonnet 5 supports a 1M-token input context window with up to 128K output tokens per response, per the current OurToken model page. That is the same context class as Claude Opus 5.
What is the exact Claude Sonnet 5 model ID?
claude-sonnet-5 — lowercase, hyphenated, no version suffix. Values like
claude-sonnet-5.0, anthropic/claude-sonnet-5, or Claude Sonnet 5 are
display or catalog forms and will fail with model_not_found.
Is the Claude Sonnet 5 API OpenAI-compatible?
No. The current OurToken Claude Sonnet 5 route uses the Anthropic Messages API
shape (/v1/messages, top-level system, typed content blocks) with Bearer
authentication. It is not a /chat/completions route, and OpenAI SDK parsers
will not read its responses. Check the model page for the recommended route
before integrating.
How much does the Claude Sonnet 5 API cost?
On OurToken: $0.80 per million input tokens, $4.00 per million output tokens, $1.00 per million cache-write tokens, and $0.08 per million cache-read tokens — 40% of the official comparison price of $2.00/$10.00/$2.50/$0.20. Confirm current prices on the live model page before budgeting.
Can I use the official Anthropic SDK with this route?
The official SDK is built around Anthropic-native x-api-key headers, while
the OurToken route documents Authorization: Bearer. Verify the SDK against a
live OurToken key before adopting it; the httpx examples in this guide are
the safer starting point because they control the auth header explicitly.