REST API v1

狗狗接码开发者 API

通过 api.dogesms.com 的 REST API 自动化完成取号、收码、订单管理等操作。使用 API Key 进行鉴权,POST /v1/orders 支持传递 X-Idempotency-Key header 防止重复扣费。

接入流程总览

一个典型接入通常只包含四个环节:创建 API Key、查询余额、下订单、轮询收码。

1

创建 API Key

在控制台「设置 → API Keys」中创建密钥,复制后妥善保存,密钥只显示一次。

建议按环境(开发 / 测试 / 生产)分别创建密钥,方便独立做限流审计与密钥轮换。

2

查询余额

下单前调用 GET /v1/balance 确认账户余额充足,避免触发 INSUFFICIENT_BALANCE(422)错误。

余额以分(cents)为单位返回,除以 100 即为美元金额。余额不足时请在控制台充值。

3

创建订单

调用 POST /v1/orders 并传入 service_code 与 country_code,附带 X-Idempotency-Key UUID 防止重试时重复扣费。

拿到订单 id 后应立即落库,后续轮询状态和取消操作都依赖这个 id。

4

接收号码与短信

推荐:注册 webhook,实时接收 order.number_allocated(phone_number 就绪)和 order.completed(sms_code 就绪)两个事件,无需轮询。或者轮询 GET /v1/orders/{id}:status 为 active 表示 phone_number 就绪,completed 表示 sms_code 就绪。

expired / cancelled / failed 均为终态。短信未在预期窗口内到达时,调用 POST /v1/orders/{id}/cancel 取消订单并释放号码资源。

鉴权

在 Authorization 请求头中传递 API Key:Authorization: Bearer sk_live_…

密钥以 sk_live_ 开头,请勿提交到代码仓库或分享给他人。

可在控制台随时创建或撤销密钥,撤销后立即生效。

限流 & 幂等

在 POST /v1/orders(CreateOrder)请求中附带 X-Idempotency-Key: <uuid>,使重试操作安全可重入。取消订单接口不读取该 header。

同一幂等键永久绑定到最初的创建请求——复用旧 key 会静默返回原订单而非创建新订单。每次下单务必生成全新的 UUID。

返回 HTTP 429 时请采用指数退避策略后重试。

接入模型

建议把 API 接入视为订单工作流,而不是一次性的 request-response 调用。

幂等写操作

每次调用 POST /v1/orders 时生成新的 UUID 作为 Idempotency-Key 并与订单一起落库,重试同一 key 会返回原始结果,不再重复扣费。

追踪订单生命周期

订单状态流转为 pending → active(phone_number 就绪)→ completed(sms_code 就绪),或进入 expired / cancelled / failed 终态。订阅 webhook(order.number_allocated、order.completed)可实时响应,或退而轮询 GET /v1/orders/{id} 作为兜底。

按可重试系统设计

HTTP 429 和 422 SERVICE_NOT_AVAILABLE(无库存)是常规运行状态,不应暴露原始错误码给终端用户,建议退避重试或提示切换国家。

Webhook(推荐)

事件发生即通过 HTTP POST 实时推送,无需轮询。注册一个端点,我们会把订单全生命周期(号码分配、短信送达、失败/超时终态)都实时推给你。

注册端点

在控制台 设置 → Webhooks 配置你的 webhook URL(API Key 与 webhook 端点同属一个账号)。签名 secret 仅在创建时展示一次,请妥善保存。

事件

order.number_allocatedorder.number_allocated —— 号码分配完成(status 变为 active)时触发。payload 含 phone_number,可直接填入目标平台;此时 sms_code 尚未到达。

order.completedorder.completed —— 短信到达(status 变为 completed)时触发。payload 含 sms_code 和 sms_content。

order.failedorder.failed —— 订单失败(无可用号码或取号出错)时触发。payload 含脱敏 error_code;不保留扣费。

order.expiredorder.expired —— 号码已分配但短信未在窗口内到达(status 变为 expired)时触发,扣费自动退回。

Payload 示例

POST <your webhook url>
X-Webhook-Signature: sha256=<hex>
Content-Type: application/json

{
  "event_type": "order.number_allocated",
  "order_id": "01960a9b-…",
  "service_code": "whatsapp",
  "country_code": "US",
  "phone_number": "+12015550123",
  "status": "active",
  "allocated_at": "2024-11-01T09:00:05Z"
}
{
  "event_type": "order.completed",
  "order_id": "01960a9b-…",
  "service_code": "whatsapp",
  "country_code": "US",
  "phone_number": "+12015550123",
  "sms_code": "123456",
  "sms_content": "Your code is 123456",
  "completed_at": "2024-11-01T09:01:30Z"
}
{
  "event_type": "order.failed",
  "order_id": "01960a9b-…",
  "service_code": "whatsapp",
  "country_code": "US",
  "status": "failed",
  "error_code": "NO_NUMBERS_AVAILABLE",
  "failed_at": "2024-11-01T09:00:30Z"
}

校验签名

每个请求都带 X-Webhook-Signature: sha256=<hex> 头。用你的 secret 对原始请求体做 HMAC-SHA256,并在常数时间内比对,确认无误后再信任 payload。

import crypto from 'node:crypto'

function verify(rawBody, header, secret) {
  const expected = 'sha256=' + crypto
    .createHmac('sha256', secret)
    .update(rawBody)              // raw bytes, not parsed JSON
    .digest('hex')
  const sig = Buffer.from(header || '', 'utf8')
  const exp = Buffer.from(expected, 'utf8')
  // length check first — timingSafeEqual throws on unequal lengths
  return sig.length === exp.length &&
    crypto.timingSafeEqual(sig, exp)
}

投递与重试

请尽快返回 2xx(10 秒内)。投递失败最多重试 5 次,退避间隔 30s → 5m → 30m → 2h。投递为 best-effort。

对账兜底

由于投递是 best-effort,请保留 GET /v1/orders/{id} 作为兜底来对账漏投的事件。两个事件都接好后,轮询就从主路径退化为安全网。

API 接口列表

基础 URL:https://api.dogesms.com,以下路径均为相对路径。

MethodPath说明常见响应
GET/v1/balance查询账户余额200 成功,返回 { data: { balance_cents: number, currency: string }, request_id: string }。 / 401 API Key 缺失、无效或已撤销。
POST/v1/orders创建取号订单201 订单创建成功,返回订单对象(含 id、status)。status 变为 active 时 phone_number 可用,变为 completed 时 sms_code 就绪,轮询 GET /v1/orders/{id} 跟踪状态。 / 400 参数缺失或格式有误(如 service_code 为空、Idempotency-Key 格式错误等)。 / 412 实际价格超出愿付上限(max_price_cents),错误码 PRICE_CHANGED。 / 422 余额不足(INSUFFICIENT_BALANCE)、钱包未初始化(WALLET_NOT_INITIALIZED)或当前服务/国家组合暂无库存(SERVICE_NOT_AVAILABLE)。
GET/v1/orders查询订单列表200 成功,返回 { data: { items: Order[], total: number, limit: number, offset: number }, request_id: string }。 / 401 API Key 缺失、无效或已撤销。
GET/v1/orders/{id}查询单个订单200 成功,返回订单对象。 / 404 订单不存在或不属于当前账户。
POST/v1/orders/{id}/cancel取消订单200 取消成功。订单已处于终态(completed/expired/failed/cancelled)且状态可读取时幂等返回当前订单对象,无副作用。 / 404 订单不存在或不属于当前账户。 / 409 订单处于终态但状态无法读回——极罕见的防御性回退,错误码 ORDER_ALREADY_TERMINAL。请用 GET /v1/orders/{id} 获取当前状态。 / 422 订单创建后 2 分钟内不允许取消(冷却期),错误码 CANCEL_TOO_EARLY。
GET/v1/catalog/services查询可用服务列表200 请求成功,返回服务对象数组(每项含 code 和 name)。 / 401 鉴权失败。
GET/v1/catalog/countries查询可用国家列表200 请求成功,返回国家对象数组(每项含 code、name、phone_prefix、service_count)。 / 401 鉴权失败。
GET/v1/catalog/prices查询指定国家的服务价格200 请求成功,返回价格数组(每项含 service_code、service_name、price_cents、available_count)。 / 400 缺少 country_code 参数。 / 401 鉴权失败。 / 404 国家编码不存在或暂无价格数据。
GET/v1/balance

查询账户余额

返回当前账户余额(单位:分)。建议下单前调用此接口预判余额是否充足。

请求参数

该接口无需额外请求参数。

响应状态码

200

成功,返回 { data: { balance_cents: number, currency: string }, request_id: string }。

401

API Key 缺失、无效或已撤销。

POST/v1/orders

创建取号订单

创建指定服务与国家的取号订单,返回含 id 和 status 的订单对象。轮询 GET /v1/orders/{id}:status 变为 active 时 phone_number 可用;status 变为 completed 时 sms_code 就绪。建议携带 X-Idempotency-Key 防止重复扣费。

请求参数

service_codestring必填

目标服务编码,如 whatsapp、telegram。

country_codestring必填

两位字母国家编码,如 US、GB。

tierstring可选

价格档位:standard(默认)或 premium。

max_price_centsinteger可选

可选愿付上限(分)。实际价格超出时返回 412 PRICE_CHANGED,省略则无上限。

响应状态码

201

订单创建成功,返回订单对象(含 id、status)。status 变为 active 时 phone_number 可用,变为 completed 时 sms_code 就绪,轮询 GET /v1/orders/{id} 跟踪状态。

400

参数缺失或格式有误(如 service_code 为空、Idempotency-Key 格式错误等)。

412

实际价格超出愿付上限(max_price_cents),错误码 PRICE_CHANGED。

422

余额不足(INSUFFICIENT_BALANCE)、钱包未初始化(WALLET_NOT_INITIALIZED)或当前服务/国家组合暂无库存(SERVICE_NOT_AVAILABLE)。

GET/v1/orders

查询订单列表

返回当前 API Key 账户下的订单列表,支持分页与状态过滤。

请求参数

limitinteger可选

单页条数,默认 20,最大 100。

offsetinteger可选

分页偏移量,默认 0。

statusstring可选

逗号分隔的状态过滤,如 pending,completed。

响应状态码

200

成功,返回 { data: { items: Order[], total: number, limit: number, offset: number }, request_id: string }。

401

API Key 缺失、无效或已撤销。

GET/v1/orders/{id}

查询单个订单

根据订单 UUID 查询状态、号码、短信内容及各阶段时间戳。

请求参数

idstring必填

POST /v1/orders 返回的订单 UUID。

响应状态码

200

成功,返回订单对象。

404

订单不存在或不属于当前账户。

POST/v1/orders/{id}/cancel

取消订单

取消仍在处理中的订单——包括 pending(等待分配号码)和 active(号码已分配、等待短信)两种状态。释放号码资源并退款。已完成、已失败或已取消的订单无法再次取消。

请求参数

idstring必填

需要取消的订单 UUID。

响应状态码

200

取消成功。订单已处于终态(completed/expired/failed/cancelled)且状态可读取时幂等返回当前订单对象,无副作用。

404

订单不存在或不属于当前账户。

409

订单处于终态但状态无法读回——极罕见的防御性回退,错误码 ORDER_ALREADY_TERMINAL。请用 GET /v1/orders/{id} 获取当前状态。

422

订单创建后 2 分钟内不允许取消(冷却期),错误码 CANCEL_TOO_EARLY。

GET/v1/catalog/services

查询可用服务列表

返回平台支持的所有服务(如 WhatsApp、Telegram、Google 等),包含服务编码(code)和显示名称(name)。创建订单时请使用本接口返回的 code 作为 service_code。

请求参数

该接口无需额外请求参数。

响应状态码

200

请求成功,返回服务对象数组(每项含 code 和 name)。

401

鉴权失败。

GET/v1/catalog/countries

查询可用国家列表

返回所有支持的国家,按可用服务数量降序排列(热门国家优先)。创建订单时请使用本接口返回的 code 作为 country_code。

请求参数

该接口无需额外请求参数。

响应状态码

200

请求成功,返回国家对象数组(每项含 code、name、phone_prefix、service_count)。

401

鉴权失败。

GET/v1/catalog/prices

查询指定国家的服务价格

返回指定国家所有可用服务的参考价格及可用数量。价格以分(美分)为单位,为含 markup 的展示价格。下单时服务端以 catalog 权威定价为准——如需价格保护,可在 POST /v1/orders 时传入 max_price_cents。

请求参数

country_codestring必填

国家编码,如 US、GB(大小写均可)。

响应状态码

200

请求成功,返回价格数组(每项含 service_code、service_name、price_cents、available_count)。

400

缺少 country_code 参数。

401

鉴权失败。

404

国家编码不存在或暂无价格数据。

创建订单示例

调用 POST /v1/orders 时的请求体与响应 JSON。

POST https://api.dogesms.com/v1/orders
Authorization: Bearer sk_live_…
X-Idempotency-Key: 73b7f4a2-1c3e-4d5f-8e9a-0b1c2d3e4f52
Content-Type: application/json

{
  "service_code": "whatsapp",
  "country_code": "US"
}
HTTP 201 Created
X-Request-Id: req_abc123…

{
  "data": {
    "id": "01960a9b-…",
    "order_no": "ORD-20241101-0042",
    "service_code": "whatsapp",
    "country_code": "US",
    "status": "pending",
    "amount_cents": 0,
    "currency": "USD",
    "created_at": "2024-11-01T09:00:00Z"
  },
  "request_id": "req_abc123…"
}
// Poll GET /v1/orders/{id}:
//   "pending"  → waiting for number allocation
//   "active"   → phone_number now available; enter it on the target platform
//   "completed"→ sms_code ready; order done
//   "expired" / "cancelled" / "failed" → terminal error states

支持的服务与国家

当前开放 6 种服务、9 个国家/地区。

📱 WhatsApp✈️ Telegram🔍 Google🎵 TikTok🛒 Amazon🧧 淘宝

库存实时变动,请以订单响应为准,避免在客户端硬编码服务或国家列表。

常见错误码

以下状态在真实业务接入中最常见,建议显式处理,而不是统一走泛化重试。

401

鉴权失败

API Key 缺失、格式有误或已撤销。

检查 Authorization 请求头格式(Bearer sk_live_…),并在控制台确认密钥处于有效状态。

403

账户状态受限

API Key 有效但账户无权请求:已封禁(ACCOUNT_BANNED)、邮箱未验证(EMAIL_NOT_VERIFIED)或账户未激活(ACCOUNT_NOT_ACTIVE)。

在控制台检查账户状态;如需验证邮箱请完成验证;如账户被封请联系客服。

409

状态冲突

订单已处于终态(完成 / 取消 / 失败),无法再次执行当前操作。

先调用 GET /v1/orders/{id} 获取最新状态,再决定后续操作,不要盲目重试写请求。

412

价格已变动

实际号码价格超出了您传入的 max_price_cents 上限。

移除 max_price_cents 以当前市场价下单,或提高上限后重试。

422

请求无法处理

余额不足(INSUFFICIENT_BALANCE)或当前服务 / 国家组合暂无可用号码(SERVICE_NOT_AVAILABLE)。

INSUFFICIENT_BALANCE:在控制台充值后重试。SERVICE_NOT_AVAILABLE:稍后重试或改用其他国家,库存随号码回收自动恢复。

429

触发限流

当前请求超过了配额窗口的限制。

采用指数退避策略,保留幂等键排队重试,不要持续直接冲击同一接口。

技术支持

Telegram 支持

@dogesms_official

服务时间:每日 09:00-21:00(UTC+8)可实时跟进

邮件支持

support@dogesms.com

服务时间:7x24 小时接单,工作时段处理

如需高并发配额或企业级接入,请与商务团队联系。