API 参考 – WhatsApp Cloud API
WhatsApp Cloud API(Graph API v21.0)的端点、认证、错误代码、速率限制和定价的完整技术参考。
目录
认证
临时令牌(开发)
从 Meta Developers Dashboard 获取。24 小时后过期。
System User Token(生产)
通过 Business Settings 创建的永久令牌:
- whatsapp_business_messaging(发送/接收消息)
- whatsapp_business_management(管理模板、资料)
认证请求头
Authorization: Bearer {ACCESS_TOKEN}
Content-Type: application/json
基础 URL 和请求头
Base URL: https://graph.facebook.com/v21.0
所有请求都必须包含的请求头:
Authorization: Bearer {ACCESS_TOKEN}
Content-Type: application/json
所需 ID
| Phone Number ID | 仪表板中 WhatsApp > API Setup | 数字 |
| WABA ID | 仪表板中 WhatsApp > API Setup | 数字 |
| App Secret | App Settings > Basic | 十六进制字符串 |
| Business ID | Business Settings > Business Info | 数字 |
端点 – 消息
发送消息
POST /{phone-number-id}/messages
请求体(文本):
{
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": "5511999999999",
"type": "text",
"text": {
"preview_url": false,
"body": "Olá! Como posso ajudar?"
}
}
响应(成功):
{
"messaging_product": "whatsapp",
"contacts": [
{ "input": "5511999999999", "wa_id": "5511999999999" }
],
"messages": [
{ "id": "wamid.HBgNNTUxMTk5…" }
]
}
type 字段支持的类型:
- text – 文本消息
- template – 模板消息
- image – 图片
- document – 文档
- video – 视频
- audio – 音频
- sticker – 贴纸
- location – 位置
- contacts – 联系人
- interactive – 按钮、列表、flows
- reaction – 表情符号反应
标记为已读
POST /{phone-number-id}/messages
{
"messaging_product": "whatsapp",
"status": "read",
"message_id": "wamid.HBgNNTUxMTk5…"
}
端点 – 媒体
上传媒体
POST /{phone-number-id}/media
Content-Type: multipart/form-data
表单字段:
- messaging_product: “whatsapp”
- file: 二进制文件
- type: MIME 类型(例如 “image/jpeg”)
响应:
{
"id": "media_id_aqui"
}
下载媒体
GET /{media-id}
响应:
{
"url": "https://lookaside.fbsbx.com/…",
"mime_type": "image/jpeg",
"sha256": "hash_aqui",
"file_size": 12345,
"id": "media_id"
}
然后,使用相同的 Authorization 请求头对返回的 url 执行 GET 以下载文件。
删除媒体
DELETE /{media-id}
媒体限制
| 图片 | JPEG、PNG | 5 MB |
| 文档 | PDF、DOC、DOCX、XLS、XLSX、PPT、TXT | 100 MB |
| 视频 | MP4、3GP | 16 MB |
| 音频 | AAC、AMR、MP3、MP4、OGG | 16 MB |
| 贴纸 | WEBP | 500 KB |
端点 – 模板
列出模板
GET /{waba-id}/message_templates
查询参数:
- limit – 结果数量(默认:25)
- status – 按状态过滤:APPROVED、PENDING、REJECTED
响应:
{
"data": [
{
"name": "hello_world",
"status": "APPROVED",
"category": "UTILITY",
"language": "pt_BR",
"components": [
{
"type": "BODY",
"text": "Olá {{1}}, seu pedido {{2}} foi confirmado!"
}
],
"id": "template_id"
}
],
"paging": { "cursors": { "before": "…", "after": "…" } }
}
创建模板
POST /{waba-id}/message_templates
{
"name": "order_confirmation",
"category": "UTILITY",
"language": "pt_BR",
"components": [
{
"type": "HEADER",
"format": "TEXT",
"text": "Confirmação de Pedido"
},
{
"type": "BODY",
"text": "Olá {{1}}, seu pedido #{{2}} foi confirmado! Valor: R$ {{3}}",
"example": {
"body_text": [["João", "12345", "99,90"]]
}
},
{
"type": "FOOTER",
"text": "Obrigado por comprar conosco!"
},
{
"type": "BUTTONS",
"buttons": [
{
"type": "URL",
"text": "Rastrear Pedido",
"url": "https://example.com/track/{{1}}",
"example": ["12345"]
}
]
}
]
}
删除模板
DELETE /{waba-id}/message_templates
{
"name": "template_name_to_delete"
}
注意: 模板提交后无法编辑。要修改,请删除并重新创建。
限制: 每个账号最多 6,000 个模板翻译。
有关完整的模板管理指南,请阅读 references/template-management.md。
端点 – 电话号码
列出号码
GET /{waba-id}/phone_numbers
响应:
{
"data": [
{
"verified_name": "Minha Empresa",
"code_verification_status": "VERIFIED",
"display_phone_number": "+55 11 99999-9999",
"quality_rating": "GREEN",
"id": "phone_number_id"
}
]
}
获取号码信息
GET /{phone-number-id}?fields=verified_name,code_verification_status,display_phone_number,quality_rating,messaging_limit_tier
端点 – 商家资料
获取资料
GET /{phone-number-id}/whatsapp_business_profile?fields=about,address,description,email,websites,profile_picture_url
更新资料
POST /{phone-number-id}/whatsapp_business_profile
{
"messaging_product": "whatsapp",
"about": "Atendimento de Seg a Sex, 8h-18h",
"address": "Rua Example, 123 – São Paulo, SP",
"description": "Empresa líder em soluções digitais",
"email": "contato@empresa.com",
"websites": ["https://www.empresa.com"]
}
Webhook 事件
Payload 结构
{
"object": "whatsapp_business_account",
"entry": [
{
"id": "WABA_ID",
"changes": [
{
"value": {
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": "5511999999999",
"phone_number_id": "PHONE_NUMBER_ID"
},
"contacts": [
{ "profile": { "name": "João" }, "wa_id": "5511888888888" }
],
"messages": […],
"statuses": […]
},
"field": "messages"
}
]
}
]
}
接收的消息类型
| text | 文本消息 | text.body |
| image | 图片 | image.id、image.mime_type |
| document | 文档 | document.id、document.filename |
| video | 视频 | video.id、video.mime_type |
| audio | 音频/语音 | audio.id、audio.mime_type |
| location | 位置 | location.latitude、.longitude |
| contacts | 共享的联系人 | contacts[].name、.phones |
| interactive | 按钮/列表响应 | interactive.button_reply.id 或 interactive.list_reply.id |
| reaction | 表情符号反应 | reaction.emoji、.message_id |
| sticker | 贴纸 | sticker.id、sticker.mime_type |
状态更新
{
"statuses": [
{
"id": "wamid.HBgNNTUxMTk5…",
"status": "delivered",
"timestamp": "1234567890",
"recipient_id": "5511999999999"
}
]
}
status 的值:sent → delivered → read → failed
错误代码
常见错误
| 0 | AuthException | 令牌无效或已过期 | 生成新令牌 |
| 3 | API Method | HTTP 方法不正确 | 检查 POST vs GET |
| 4 | Too many calls | 超出速率限制 | 实现带退避的重试 |
| 10 | Permission denied | 令牌缺少所需权限 | 为 System User 添加权限 |
| 100 | Invalid parameter | 负载格式错误 | 对照文档检查 JSON |
| 131026 | Message undeliverable | 号码不在 WhatsApp 上 | 发送前验证号码 |
| 131047 | Re-engagement message | 24 小时窗口外且没有模板 | 使用模板消息 |
| 131051 | Unsupported message type | 不支持的消息类型 | 检查 type 字段 |
| 131053 | Media upload error | 文件无效或太大 | 检查格式和大小 |
| 132000 | Template param count mismatch | 参数数量错误 | 核对模板和参数 |
| 132001 | Template does not exist | 未找到模板 | 检查模板名称和语言 |
| 132005 | Template hydration failed | 填充变量时出错 | 检查参数格式 |
| 133010 | Phone number not registered | 号码未验证 | 完成 OTP 验证 |
| 135000 | Generic error | WhatsApp 内部错误 | 几秒后重试 |
错误处理
async function sendWithRetry(payload: any, maxRetries = 3): Promise<any> {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
const response = await axios.post(
`${GRAPH_API}/${process.env.PHONE_NUMBER_ID}/messages`,
payload,
{ headers: { Authorization: `Bearer ${process.env.WHATSAPP_TOKEN}` } }
);
return response.data;
} catch (error: any) {
const errorCode = error.response?.data?.error?.code;
const errorMessage = error.response?.data?.error?.message;
// 不应重试的错误
if ([100, 131026, 131051, 132000, 132001].includes(errorCode)) {
throw new Error(`WhatsApp API Error ${errorCode}: ${errorMessage}`);
}
// 速率限制或临时错误 – 带退避重试
if (attempt < maxRetries && [4, 135000].includes(errorCode)) {
const delay = Math.pow(2, attempt) * 1000; // 2s、4s、8s
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}
throw error;
}
}
}
速率限制
吞吐量(每秒消息数)
| 标准 | 80 条/秒 |
| 无限层级 | 1,000 条/秒 |
24 小时内的对话数
| 初始 | 250 | 新账号或未验证 |
| 第 1 级 | 1,000 | 连续 7 天使用 50%+ 限额 + 质量达标 |
| 第 2 级 | 10,000 | 连续 7 天使用 50%+ 限额 + 质量达标 |
| 第 3 级 | 100,000 | 连续 7 天使用 50%+ 限额 + 质量达标 |
| 无限 | 无限 | 连续 7 天使用 50%+ 限额 + 质量达标 |
重要: 限制按业务组合(Business Portfolio)计算(自 2025 年 10 月起),而非按号码。
其他限制
- 模板:每个账号 6,000 个翻译
- 交互式按钮:每条消息最多 3 个
- 交互式列表:最多 10 个选项、最多 3 个分区
- 文本:最多 4,096 个字符
- 模板正文:最多 1,600 个字符
- Webhooks:在 5 秒内以 200 响应
2026 定价
自 2025 年 7 月起,模型为按消息计费(不再按对话)。
各类别成本
| 营销 | $0.025 – $0.1365 | 否 | 收费 |
| 实用 | $0.004 – $0.0456 | 是 | 免费 |
| 认证 | $0.004 – $0.0456 | 是 | 收费 |
| 服务 | 免费 | 不适用 | 免费 |
按地区示例(营销)
| 巴西 | 约 $0.05 |
| 印度 | 约 $0.01 |
| 美国/加拿大 | 约 $0.025 |
| 西欧 | 约 $0.10+ |
24 小时窗口
- 客户发送消息时打开
- 窗口内:实用类模板免费
- 服务消息(回复)始终免费
- 营销和认证即使在窗口内也收费
2026 年 1 月变更
- 法国和埃及:营销成本降低
- 印度:营销成本上升
- 北美:实用和认证成本降低
版本管理
当前版本
Graph API v21.0(2026 年 1 月发布)
兼容性
- Meta 至少保持 12 个月的向后兼容性
- 旧版本在移除前会收到弃用通知
- 始终在 URL 中指定版本:https://graph.facebook.com/v21.0/
2026 年计划变更
| BSUID | 2026 | 业务作用域用户 ID 取代电话号码 |
| 用户名 | 2026 | WhatsApp 引入用户名以保护隐私 |
| 移除层级(2K/10K) | 2026 Q2 | 验证后立即获得 100K 限额 |
| 业务组合节奏 | 2026 Q1 | 基于反馈自动暂停广告系列 |
版本管理最佳实践
- 关注 Meta 开发者博客了解变更
- 在生产环境升级版本前在沙盒中测试
- 使用环境变量存储 API 版本(便于回滚)
- 保留调用日志以便调试兼容性



