将短信发送
接入您的服务.
一个 API 密钥即可开始。选择国家,每次最多向 1,000 个号码发送短信,还可查看每个号码的结果。
快速开始
- 创建 API 密钥
完成注册、审核并通过 OTP 登录后,前往API密钥管理创建密钥。
- 准备积分
直接使用账户的积分和单价。发送请求被接收时扣费。
- 发送短信并查看结果
保存发送 ID,并通过状态查询 API 查看结果。
https://hexsms.com正式接入请从 HTTPS 服务器调用。预览环境不支持签发真实密钥和 API 发送。
支持国家
主要覆盖国家
- 美国
- 加拿大
- 英国
- 德国
- 法国
- 西班牙
- 意大利
- 荷兰
- 瑞典
- 挪威
- 丹麦
- 波兰
- 罗马尼亚
- 捷克
- 奥地利
- 瑞士
- 爱尔兰
- 葡萄牙
- 芬兰
- 日本
- 韩国
- 中国
- 台湾
- 中国香港特别行政区
- 新加坡
- 马来西亚
- 印度尼西亚
- 菲律宾
- 泰国
- 越南
- 印度
- 孟加拉国
- 巴基斯坦
- 澳大利亚
- 新西兰
- 巴西
- 墨西哥
- 南非
- 尼日利亚
- 阿拉伯联合酋长国
- 沙特阿拉伯
各国能否发送、单价及发件人注册要求取决于账户和当地网络。发送前请确认各国费率。
GET/api/v1/messages/countries
通过 API 查看已启用的国家和实际适用单价。发送请求时用 country 指定国家,每个请求中请只包含同一国家的号码。未设置费率的国家不接受发送。
{ "currency": "USDT", "countries": [{ "country": "US", "unitPrice": 0.02 }] }使用 API 密钥认证
所有外部 API 请求都需要包含以下请求头。无需登录 Cookie 或 OTP 验证码。
Authorization: Bearer hex_live_您的API密钥密钥原文仅在签发时显示一次。请将其保存在服务器环境变量中,不要写入前端代码。密钥被作废或账户被停用后将无法使用。最多可创建 5 个密钥。
/api/v1/messages一次发送到 1,000 个号码
将同一条短信内容发送到多个号码。请求经验证后加入发送队列并立即响应。如需为每个号码发送不同内容,请分别发起请求并使用新的 Idempotency-Key。
| 字段 | 类型 | 说明 |
|---|---|---|
country * | string | ISO 3166-1 alpha-2 国家代码,例如 US、GB、JP、KR。没有默认国家。 |
text * | string | 去除首尾空白后 1~1,600 个字符。同一请求中的所有号码接收相同内容。 |
recipients * | string[] | 1~1,000 个手机号码。建议使用 +国家代码格式,所有号码必须与 country 属于同一国家。 |
Idempotency-Key * | header | 8~100 个英文字母、数字、连字符或下划线。每个请求请使用唯一值。 |
只要有一个无效或重复号码,整个请求都会被拒绝,此时不会发送也不会扣费。重复号码按转换为国际格式后的号码判断。
curl -X POST 'https://hexsms.com/api/v1/messages' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: notice-20261024-001' \
-d '{
"country": "US",
"text": "Your verification code is 482913.",
"recipients": ["+12025550123", "+12025550124"]
}'{
"id": "35bed356-b84a-452a-8e94-98b538972ecd",
"country": "US",
"state": "RUNNING",
"total": 2,
"segments": 1,
"unitPrice": 0.025,
"cost": 0.05,
"createdAt": 1792800000000,
"note": null,
"replayed": false
}使用相同账户、相同 Idempotency-Key、相同内容和号码顺序重试时,不会额外发送或扣费,而是返回原有结果(200, replayed: true)。请求体不同则返回 409。更换 API 密钥后防重复机制依然有效。请求键永久保存,不会过期。
费用计算方式
号码数 × 条数(segments)× 账户单价即为费用。UCS-2 字符 70 个以内计为 1 条,超出后每 67 个字符计 1 条。GSM-7 基本字符 160 个以内计为 1 条,超出后每 153 个字符计 1 条。扩展字符按 2 个字符计,表情符号按 UTF-16 长度计。unitPrice 和 cost 的单位为 USDT。响应中的单价为实际适用单价,上文的 0.025 仅为示例。
/api/v1/messages/{id}查看每个号码的发送结果
使用发送 API 返回的 id。只能查询同一账户通过 API 发送的记录。查询返回已保存的结果。如需运营商的最新结果,请先调用下面的状态刷新 API。
curl 'https://hexsms.com/api/v1/messages/35bed356-b84a-452a-8e94-98b538972ecd?limit=1&offset=0' \
-H 'Authorization: Bearer YOUR_API_KEY'{
"id": "35bed356-b84a-452a-8e94-98b538972ecd",
"country": "US",
"state": "DONE",
"total": 2, "segments": 1,
"unitPrice": 0.025, "cost": 0.05,
"createdAt": 1792800000000, "note": null,
"summary": { "DELIVERED": 1, "PENDING": 1 },
"messages": [
{
"id": "d2787184-d8b8-49c6-9c15-1db90a6d5516",
"to": "12025550123",
"status": "DELIVERED",
"statusName": "DELIVERED_TO_HANDSET",
"description": "Message delivered to handset",
"error": null,
"updatedAt": 1792800005000
}
],
"pagination": { "limit": 1, "offset": 0, "nextOffset": 1 }
}limit 为 1~1,000(默认 100),offset 为 0~1,000(默认 0)。nextOffset 为 null 表示最后一页。summary 是全部号码按状态统计的数量。to 以不含 + 的国际号码格式返回,时间以 Unix 毫秒返回。查询顺序可能与最初发送的号码顺序不同,请用每条 message 的 id 区分。
它表示发送队列已处理完毕。实际是否送达,请确认 messages 中的 status 是否为 DELIVERED。
/api/v1/messages/{id}/refresh获取最新接收状态
查询运营商日志并更新已保存的结果。无需请求体。更新后请用 GET 重新读取结果。同一发送任务每 30 秒可刷新一次。运营商日志在发送后 48 小时内可查询。已配置 Webhook 的环境中,结果也可能自动更新。
curl -X POST 'https://hexsms.com/api/v1/messages/35bed356-b84a-452a-8e94-98b538972ecd/refresh' \
-H 'Authorization: Bearer YOUR_API_KEY'{ "id": "35bed356-b84a-452a-8e94-98b538972ecd", "updated": 2 }updated 为已更新的行数。若消息仍在排队或没有新结果,可能为 0。建议以 10 秒以上的间隔调用 GET,仅在需要时请求 refresh。
了解状态码
发送请求 state
PREPARING 准备中 · RUNNING 处理中 · PAUSED 已暂停 · DONE 队列处理完成 · CANCELED 已取消
| 各号码 status | 含义 |
|---|---|
| QUEUED | 等待发送。 |
| SENDING | 正在向运营商提交。 |
| PENDING | 运营商已接收,正在等待最终接收结果。 |
| DELIVERED | 已送达接收终端。 |
| UNDELIVERABLE | 无法送达。 |
| EXPIRED | 已超过送达有效期。 |
| REJECTED | 请求被拒绝或发生处理错误。 |
| CANCELED | 等待中的发送已取消。 |
| UNKNOWN | 尚未确认结果。 |
运营商可能会新增状态码,请同时处理未知的 status。失败原因可在 statusName、description、error 中查看。
出错时这样排查
{ "error": "积分不足,请充值后重新请求。", "code": "INSUFFICIENT_CREDITS" }| HTTP | code | 检查事项 |
|---|---|---|
| 403 | COUNTRY_NOT_ENABLED | 确认各国发送费率及是否已启用。 |
| 400 | INVALID_COUNTRY | 请在 country 中填写 ISO 国家代码。 |
| 400 | INVALID_BODY / INVALID_JSON / INVALID_TEXT | 检查 JSON 对象和短信内容。 |
| 400 | INVALID_RECIPIENTS / INVALID_PHONE / DUPLICATE_PHONE | 检查号码数量、格式和重复情况。 |
| 400 | INVALID_IDEMPOTENCY_KEY / INVALID_PAGINATION | 检查请求键或分页参数。 |
| 401 | UNAUTHORIZED | 缺少 Bearer API 密钥或密钥无效。 |
| 402 | INSUFFICIENT_CREDITS | 请充值积分。 |
| 403 | ACCOUNT_INACTIVE | 确认账户已审核通过且处于正常状态。 |
| 404 | NOT_FOUND | 检查发送 ID 及账户归属。 |
| 409 | IDEMPOTENCY_CONFLICT | 相同的请求键被用于不同的请求体。 |
| 413 / 415 | BODY_TOO_LARGE / UNSUPPORTED_MEDIA_TYPE | 请发送不超过 128KiB 的 JSON 请求体。 |
| 429 | RATE_LIMITED / REFRESH_TOO_SOON | 等待 Retry-After 指定的秒数后再请求。 |
| 500 / 502 | INTERNAL_ERROR / PROVIDER_UNAVAILABLE | 请稍后重试。重试发送时请使用相同的请求键。 |
| 503 | PREVIEW_ONLY | 预览模式下无法调用真实 API。 |
发送、查询和刷新合计,每个 API 密钥每分钟最多可请求 120 次。触发限制时请查看 Retry-After 请求头。该 API 用于服务器间集成,不支持浏览器 CORS 调用。
用 Node.js 接入
const response = await fetch('https://hexsms.com/api/v1/messages', {
method: 'POST',
headers: {
Authorization: 'Bearer ' + process.env.HEXSMS_API_KEY,
'Content-Type': 'application/json',
'Idempotency-Key': 'notice-20261024-001'
},
body: JSON.stringify({
country: 'US',
text: 'Your order is on its way.',
recipients: ['+12025550123', '+12025550124']
})
});
const result = await response.json();
if (!response.ok) throw new Error(result.code + ': ' + result.error);
console.log(result.id); // Use this ID to check delivery status.每个任务只生成一次请求键,因未收到响应而重试时也请使用相同的值。若用新键重新发送已成功的任务,将被视为另一次发送。