Anthropic Messages API
用 Anthropic 的 Messages 格式发送请求(流式或非流式)、计算 token 数、列出模型,并了解支持哪些功能。
何时阅读本页
你通过 Anthropic 的 Messages 格式调用 AI 模型:使用 Anthropic SDK、Claude Code 或直接发送 HTTP 请求。本页介绍端点、请求头、模型名称、流式输出(streaming)、超时,以及哪些功能不支持。完整的请求和响应 schema 见 API 参考。
Base URL 与端点
Base URL 是 https://api.router.ezat.io。Anthropic 的 SDK 会自己加上 /v1/…,所以传给它们的 base URL 不要带 /v1。
| 方法 | 路径 | 作用 |
|---|---|---|
POST | /v1/messages | 创建一条消息。加上 "stream": true 即为流式输出。 |
POST | /v1/messages/count_tokens | 计算请求的输入 token 数。免费。 |
GET | /v1/models | 列出你的 key 可以使用的模型。 |
GET | /v1/models/{model_id} | 按 id 或别名查询单个模型。 |
其他路径都返回 404(见下文「支持与不支持」一节)。
认证
用以下任一请求头发送你的 EZAT key(ezat_sk_…):
x-api-key: <key>(Anthropic SDK 的发送方式),或Authorization: Bearer <key>(Claude Code 使用ANTHROPIC_AUTH_TOKEN时的发送方式)。
如果一个请求同时带有两者,EZAT 使用 x-api-key。key 的安全使用以及 401 和 403 错误见认证。
创建消息
curl --fail-with-body https://api.router.ezat.io/v1/messages \
-H "x-api-key: $EZAT_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{
"model": "anthropic/claude-sonnet-5-5",
"max_tokens": 64,
"messages": [{"role": "user", "content": "Say hello in five words."}]
}'响应是 Anthropic 的 message 对象:
{
"id": "msg_…",
"type": "message",
"role": "assistant",
"model": "anthropic/claude-sonnet-5-5",
"content": [{ "type": "text", "text": "Hello, it's nice to meet you." }],
"stop_reason": "end_turn",
"stop_sequence": null,
"usage": {
"input_tokens": 14,
"output_tokens": 9,
"cache_creation_input_tokens": 0,
"cache_read_input_tokens": 0
}
}model与你发送的完全一致。发送别名,返回的也是别名。Claude Code 和各 SDK 依赖这一点。- 读取
text块。content中可能在文本之前出现thinking或tool_use块,也可能只有这些块而没有文本,所以不要假定content[0]是文本。 - 响应头中的
request-id是 EZAT 为该请求分配的 id。联系支持团队时请提供它。
流式输出消息
加上 "stream": true。响应是 Anthropic 格式的 Server-Sent Events,不做任何改动。
curl --fail-with-body -N https://api.router.ezat.io/v1/messages \
-H "x-api-key: $EZAT_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{
"model": "anthropic/claude-sonnet-5-5",
"max_tokens": 64,
"stream": true,
"messages": [{"role": "user", "content": "Count from 1 to 10."}]
}'| 事件 | 何时出现 |
|---|---|
message_start | 第一个事件。携带消息本身(其中 model 为你发送的值),以及输入和缓存 token 数。 |
content_block_start | 一个文本块、思考块或工具调用块开始。 |
content_block_delta | 块的一部分:text_delta、thinking_delta 或 input_json_delta。 |
content_block_stop | 该块结束。 |
message_delta | stop_reason 和最终的输出 token 数。 |
message_stop | 最后一个事件。EZAT 记录完该请求的用量后关闭连接。 |
ping | 15 秒内没有其他事件时发送,让代理保持连接。 |
error | 流开始后发生的失败(此时 HTTP 状态码已经是 200)。之后流结束。 |
在第一个事件之前,如果某个部署失败,EZAT 会换到另一个部署重试,所以流开始时的模型提供方错误通常不会传到你这里。事件开始之后不再重试。
计算 token 数
POST /v1/messages/count_tokens 接受与 /v1/messages 相同的请求体(model 和 messages,如有使用再加上 system 和 tools),但不带 max_tokens,返回 {"input_tokens": N}。
curl --fail-with-body https://api.router.ezat.io/v1/messages/count_tokens \
-H "x-api-key: $EZAT_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{
"model": "anthropic/claude-sonnet-5-5",
"messages": [{"role": "user", "content": "How many tokens is this?"}]
}'计算 token 数免费:不计费,也不会出现在「用量」中。但它会计入该 key 的每分钟请求数限制。anthropic-beta 对它不生效。
列出模型
curl --fail-with-body https://api.router.ezat.io/v1/models \
-H "x-api-key: $EZAT_API_KEY" \
-H "anthropic-version: 2023-06-01"{
"data": [
{
"type": "model",
"id": "anthropic/claude-sonnet-5-5",
"display_name": "…",
"created_at": "2026-10-01T00:00:00.000Z"
}
],
"has_more": false,
"first_id": "…",
"last_id": "…"
}- 列表包含你的 key 可以使用的所有模型,使用规范 id。限定了部分模型的 key(见 API key)只能看到这些模型。
GET /v1/models/{model_id}接受别名,并返回规范 id。规范 id 中含有斜杠,所以在这里要做 URL 编码(anthropic%2Fclaude-sonnet-5-5),或者改用别名。
模型 id 与别名
- 规范 id 的格式为
author/model,例如anthropic/claude-sonnet-5-5。 - 别名。Anthropic 自己的模型名称(例如
claude-sonnet-5-5和claude-sonnet-5.5)是规范 id 的别名,所以为 Anthropic API 编写的代码无需修改即可使用。匹配不区分大小写。 - 两种写法计费相同。模型页面列出了每个 id 及其别名。
- 未知的名称返回
404not_found_error,消息为model: <name>。key 无权使用的模型返回403permission_error。
请求头
请求头:
| 请求头 | 是否必需 | EZAT 如何处理 |
|---|---|---|
x-api-key 或 Authorization: Bearer | 是 | 你的 EZAT key。 |
content-type: application/json | POST 请求必需 | |
anthropic-version | 否 | 接受,但不会使用。SDK 会发送它们自己的值;任何值都可以,也可以不发送。 |
anthropic-beta | 否 | 在 /v1/messages 上原样传给模型提供方。提供方不接受的 beta 会在提供方那里失败。 |
x-ezat-session | 否 | 为对话命名,让它的请求留在同一个部署上,提示缓存(prompt caching)继续有效。可以是任意字符串,只使用前 256 个字符。见提示缓存与会话。 |
x-request-id | 否 | 你自己为请求设定的 id(字母、数字、.、_、: 和 -,最多 128 个字符)。EZAT 会原样返回。 |
响应头:
| 响应头 | 含义 |
|---|---|
request-id | EZAT 为该请求分配的 id。凡是通过了 key、模型、限额和余额检查的请求都会带上。 |
x-request-id | 你发送的 x-request-id,或由 EZAT 生成的 id。错误响应体中会以 request_id 再次给出。 |
retry-after | 出现 429 和 529 时:重试前需要等待的秒数。 |
EZAT 不发送 Anthropic 的 anthropic-ratelimit-* 响应头。它的限制见速率限制。
工具
你自己定义并执行的工具,用法与在 Anthropic API 上相同:tools、tool_choice、响应中的 tool_use 块,以及在下一条消息中发送的 tool_result 块。
{
"model": "anthropic/claude-sonnet-5-5",
"max_tokens": 1024,
"tools": [
{
"name": "get_weather",
"description": "Current weather for a city",
"input_schema": {
"type": "object",
"properties": { "city": { "type": "string" } },
"required": ["city"]
}
}
],
"messages": [{ "role": "user", "content": "What's the weather in Oslo?" }]
}由 Anthropic 替你执行的服务端工具(网页搜索、代码执行)不可用。见下文的表格。
图片和 PDF
图片以 base64 image 块发送(JPEG、PNG、GIF 或 WebP),PDF 以 base64 document 块发送:
{
"role": "user",
"content": [
{
"type": "image",
"source": { "type": "base64", "media_type": "image/png", "data": "iVBORw0KGgo…" }
},
{ "type": "text", "text": "What is in this image?" }
]
}在这个 API 上 EZAT 不会下载图片,所以 url 类型的 source 无法使用。要发送图片 URL,请使用 OpenAI 兼容 API,它会替你下载图片。整个请求体最大 32 MB;超过会返回 413 request_too_large。
思考
thinking 会原样传给模型,thinking 块会出现在响应和流中。思考 token 按输出 token 计费。
{
"model": "anthropic/claude-sonnet-5-5",
"max_tokens": 16000,
"thinking": { "type": "adaptive" },
"messages": [{ "role": "user", "content": "Plan a three-day trip to Oslo." }]
}可用选项见 Anthropic 的扩展思考(extended thinking)指南。带思考的请求建议使用流式输出:它们往往耗时较长。
提示缓存
cache_control 的用法与 Anthropic API 相同,TTL 可以是 5 分钟({"type": "ephemeral"})或 1 小时({"type": "ephemeral", "ttl": "1h"})。缓存写入和缓存读取按各自的价格计费(见价格),usage 通过 cache_creation_input_tokens 和 cache_read_input_tokens 报告它们。
EZAT 会把每个对话保持在同一个部署上,让缓存持续生效。提示缓存与会话介绍了断点该放在哪里、会话请求头,以及有特殊情况的模型。
长请求与超时
- 非流式请求有 590 秒的期限。模型到时还没完成,请求会以
504timeout_error结束,消息为The model took longer than 590 seconds. Send long requests with "stream": true.。该请求不计费。 - 长输出请使用流式。流式响应没有期限:静默 15 秒后 EZAT 会发送
ping事件,所以模型思考期间连接保持打开。max_tokens较大、带思考或输入很长的请求,都请使用流式输出。
错误
错误使用 Anthropic 的格式和 Anthropic 的状态码:
{
"type": "error",
"error": { "type": "billing_error", "message": "Your credit balance is too low. Add credits in the EZAT Router dashboard." },
"request_id": "…"
}失败的请求不计费。错误列出了所有状态码和类型,并说明哪些可以重试。
流被中断
如果你在流结束前关闭它,EZAT 会停止模型,并按已生成的内容计费:输入和缓存 token 按精确值计,输出 token 根据已经流式返回的文本估算。在「用量」中,该请求显示为「已取消」,并标为估算值。如果模型提供方在流的中途失败,你会收到一个 error 事件,该请求不计费。详情见计费。
支持与不支持
| 功能 | 状态 | 说明 |
|---|---|---|
| 消息,流式和非流式 | 支持 | |
| 计算 token 数 | 支持 | 免费;不显示在「用量」中 |
| 模型列表和查询 | 支持 | |
你定义的工具(tools、tool_choice) | 支持 | |
| base64 图片和 PDF | 支持 | 每个请求体最大 32 MB |
通过 URL 发送图片(source.type: "url") | 不支持 | 请发送 base64,或使用 OpenAI 兼容 API |
| 思考 | 支持 | |
| 提示缓存,5 分钟和 1 小时 | 支持 | capabilities.promptCaching 为 false 的模型除外;见提示缓存 |
结构化输出(output_config.format) | 支持 | |
temperature、top_p、top_k | 透传 | 只有 capabilities.sampling 为 true 的模型接受;其他模型收到非默认值时返回 400 |
anthropic-beta | 透传 | 哪些 beta 可用由模型提供方决定 |
Message Batches API(/v1/messages/batches) | 不可用 | 返回 404 |
Files API(/v1/files) | 不可用 | 返回 404;请以 base64 内联发送文件 |
| 服务端工具:网页搜索、代码执行,以及其他由 Anthropic 执行的工具 | 不可用 | |
MCP connector(mcp_servers) | 不可用 |
每个模型的 capabilities 见 GET https://api.router.ezat.io/api/models(无需 key),以及模型页面的「能力」一列。
不可用的端点返回 404 和 {"statusCode": 404, "message": "Cannot POST /v1/messages/batches"},这不是 Anthropic 的错误格式。EZAT 目前还没有拦截服务端工具和 MCP connector:请求会原样发给模型提供方,而提供方不会执行它们,所以预计会报错。不要发送它们。
给 AI agent 的说明
- Base URL 为
https://api.router.ezat.io(不带/v1:SDK 会自己加上)。key 从环境变量EZAT_API_KEY读取,以x-api-key或Authorization: Bearer发送。 - 使用
GET https://api.router.ezat.io/v1/models返回的模型 id,或 Anthropic 的模型名称(它是别名)。响应中的model原样返回你发送的值。 - 从
content中的text块读取文本,不要读content[0]。 - 可能超过几分钟的请求都要使用流式(
"stream": true)。非流式请求在 590 秒后以504timeout_error结束。 - 不要使用 Message Batches、Files API、服务端工具(网页搜索、代码执行)或 MCP connector:它们不可用。
- 出错时,先查看
error.type和错误,再决定是否重试。向支持团队报告request-id。