HTTP API v1
以编程方式访问电话号码、通话、SMS、语音信箱和 AI 功能。通过 HTTPS 传输 JSON。在关键操作中保证幂等性。无需 SDK,但我们提供 5 个。
简介
NoKYCNumber API 以 REST 为基础构建。我们使用可预测的资源导向 URL,接受并返回 JSON 编码的请求体,并使用标准 HTTP 响应码、身份验证和动词。
基础 URL
https://api.nokycnumber.com/v1/所有请求必须通过 HTTPS 发送。通过普通 HTTP 发送的请求将返回 301 Moved Permanently。未经身份验证的请求将返回 401 Unauthenticated。
JSON 规范
- 所有带有请求体的请求均使用
Content-Type: application/json。表单编码的请求体将被拒绝并返回415。 - 时间戳以 ISO-8601 UTC 字符串格式返回(
2026-04-26T14:23:00Z),接受相同格式的输入。 - 电话号码以 E.164 格式返回,带有前导
+(如+33647189022),并在相关时以display字段友好显示。 - 对象 ID 以其资源类型为前缀:
num_、call_、sms_、vm_、whk_、evt_。
身份验证
使用从面板 设置 → API 密钥 中签发的持有者密钥进行身份验证。存在两种密钥类型:
sk_live_…— 服务端密钥,具有完整读写权限。切勿在客户端代码中暴露。pk_live_…— 可公开密钥。目前保留,尚未被任何端点使用。
标头格式
Authorization: Bearer sk_live_5f3a8b2c4d1e9f6a7b8c2d1e9f6a7b8c
Content-Type: application/json
NoKYC-Version: 2026-04-01使用 NoKYC-Version 标头固定到特定版本的 API 接口(参见 版本控制)。省略时,使用您账户的固定默认版本。
权限范围
密钥签发时具有以下三种权限范围之一:
| 权限范围 | 允许的方法 | 使用场景 |
|---|---|---|
read | GET | 报告、监控仪表板。 |
read_write | GET · POST · PATCH | 大多数服务端集成。 |
admin | 全部权限,包含 DELETE | 配置自动化、账户管理。 |
密钥可随时轮换。旧密钥在轮换后仍有效 5 分钟,以支持零停机部署。
错误
API 使用标准 HTTP 状态码。2xx 表示成功,4xx 表示您的请求有问题,5xx 表示我方出现错误,欢迎反馈。
错误信封
{
"error": {
"type": "invalid_request_error",
"code": "parameter_missing",
"message": "Required parameter `country` is missing.",
"param": "country",
"request_id": "req_8a4c2f1e9b3d4a7c"
}
}状态码
| 代码 | 含义 |
|---|---|
200 | 成功 · 请求已成功 |
201 | 已创建 · 资源已创建 |
204 | 无内容 · 资源已删除,无响应体返回 |
400 | 错误请求 · JSON 格式错误或缺少必要参数 |
401 | 未认证 · API 密钥无效、缺失或已撤销 |
402 | 需要支付 · 账户余额不足以执行此操作 |
403 | 禁止 · 密钥缺少此操作所需的权限范围 |
404 | 未找到 · 资源不存在或属于其他账户 |
409 | 冲突 · 幂等键以不同参数重复使用 |
422 | 无法处理 · 语义错误(例如不支持的国家) |
429 | 请求过多 · 请参阅 速率限制 |
500 – 503 | 服务器/服务问题 · 可使用退避策略安全重试 |
错误类型
invalid_request_error— 格式错误的输入、缺少字段或无效格式。authentication_error— 密钥问题。authorization_error— 权限范围问题。rate_limit_error— 请求过于频繁,请降速。api_error— 我方错误,可重试。resource_error— 资源状态阻止了该操作(例如,尝试从已暂停的号码拨打电话)。upstream_error— 运营商或合作伙伴超时。
每个错误响应都包含一个 request_id。务必记录它——这是我们的支持团队将您的请求与内部追踪关联起来的唯一方式。
分页
列表端点使用仅向前游标分页。它们最多返回 limit 个对象(默认 25,最多 100)和一个 has_more 布尔值。要获取下一页,请将最后一个对象的 id 作为 starting_after 传入。
curl https://api.nokycnumber.com/v1/numbers?limit=10 \
-H "Authorization: Bearer sk_live_…"{
"object": "list",
"url": "/v1/numbers",
"data": [
{ "id": "num_8a4c2f1e9b3d", "object": "number", "number": "+33647189022", … },
{ "id": "num_2k7m9p3w8x4t", "object": "number", "number": "+12025550143", … }
],
"has_more": true,
"next_cursor": "num_2k7m9p3w8x4t"
}列表按最近创建的对象排在最前面。不支持通过 ending_before 进行向后分页——请改用游标分页。
幂等性
修改状态的 POST 请求接受 Idempotency-Key 标头。我们对该密钥进行 24 小时去重,重试时返回缓存的响应。每个逻辑操作请使用一个 UUID。
POST /v1/sms HTTP/1.1
Authorization: Bearer sk_live_…
Idempotency-Key: 9b3d4a7c-8a4c-2f1e-9b3d-4a7c8a4c2f1e
Content-Type: application/json
{ "from": "num_8a4c2f1e9b3d", "to": "+33612345678", "body": "Hello" }以不同请求体内容重放相同密钥将返回 409 Conflict,错误码为 idempotency_key_mismatch。
幂等键不是必需的,但对于任何涉及费用的操作(通话、SMS、号码购买)强烈建议使用。没有幂等键,网络重试可能导致重复收费。
速率限制
默认情况下,每个 API 密钥限制为每分钟 100 次请求。大客户可联系支持申请提升限额。限制按密钥执行,而非按 IP。
响应标头
X-Rate-Limit-Limit: 100
X-Rate-Limit-Remaining: 73
X-Rate-Limit-Reset: 1745672460
Retry-After: 8超出限制时,您将收到 429 Too Many Requests,响应中包含以秒为单位的 Retry-After 标头。建议使用线性退避最多重试 4 次;如持续发生,请申请更高限额。
突发请求配额
限速器采用令牌桶算法——只要滚动 60 秒平均值保持在上限以下,允许短暂超过 100 rpm 的突发请求。
版本控制
API 版本以日期命名(2026-04-01)。破坏性变更以新日期版本发布;非破坏性新增内容在当前版本中发布。使用 NoKYC-Version 标头固定版本。
兼容性
- 我们对每个版本提供下一次发布后至少 24 个月的支持。
- 废弃通知将提前 90 天通过邮件发送给账户所有者。
NoKYC-Deprecation响应标头会在您使用过时版本时发出警告。
当前版本:2026-04-01。
号码
号码代表您控制的虚拟电话线路。号码与国家和类型(mobile 手机或 landline 固话)绑定,并带有计费周期。
/v1/numbers
列出账户上的所有号码。返回分页的 number 对象列表。
| Field | 类型 | Description |
|---|---|---|
limit 可选 | integer | 1–100,默认 25。 |
starting_after 可选 | string | 分页游标。 |
country 可选 | string | 按 ISO-2 国家代码过滤(例如 fr)。 |
type 可选 | string | 按 mobile(手机)或 landline(固话)过滤。 |
status 可选 | string | 按 active(活跃)、paused(暂停)或 released(释放)过滤。 |
curl https://api.nokycnumber.com/v1/numbers?country=fr&type=mobile \
-H "Authorization: Bearer sk_live_…"{
"object": "list",
"data": [
{
"id": "num_8a4c2f1e9b3d",
"object": "number",
"number": "+33647189022",
"display": "+33 6 47 18 90 22",
"country": "fr",
"type": "mobile",
"tier": "standard",
"status": "active",
"billing_period": "yearly",
"renews_at": "2027-04-26T11:23:00Z",
"ai_enabled": true,
"created_at": "2026-04-26T11:23:00Z"
}
],
"has_more": false,
"next_cursor": null
}/v1/numbers/available
在指定国家和类型中搜索可用号码。调用 POST /v1/numbers 时使用返回的 id。
| Field | 类型 | Description |
|---|---|---|
country 必填 | string | ISO-2 国家代码。 |
type 必填 | string | mobile(手机)或 landline(固话)。 |
tier 可选 | string | standard(默认)或 premium(高级)。 |
pattern 可选 | string | 对本地数字的可选子字符串过滤,例如 "77"。 |
limit 可选 | integer | 1–50,默认 10。 |
curl "https://api.nokycnumber.com/v1/numbers/available?country=fr&type=mobile&tier=premium&limit=5" \
-H "Authorization: Bearer sk_live_…"{
"object": "list",
"data": [
{ "id": "navail_2k7m9p3w8x4t", "number": "+33611112222", "display": "+33 6 11 11 22 22", "tier": "premium", "pattern": "double-repeat", "price_usd_per_month": 11.98 },
{ "id": "navail_4n2v8j1q6h7y", "number": "+33612345678", "display": "+33 6 12 34 56 78", "tier": "premium", "pattern": "sequential", "price_usd_per_month": 11.98 }
],
"expires_at": "2026-04-26T11:33:00Z"
}可用号码将保留 10 分钟。超时后,相同 ID 可能会分配给其他用户。
/v1/numbers
通过预订 ID 激活新号码。将按配置的周期从账户余额中扣费。
| Field | 类型 | Description |
|---|---|---|
available_id 必填 | string | 来自 /v1/numbers/available 的 navail_… id。 |
billing_period 必填 | string | monthly(按月)、quarterly(按季度)或 yearly(按年)。 |
addons 可选 | array | 要启用的 AI 附加功能,例如 ["ai-pickup","ai-trans"]。 |
webhook_url 可选 | string | 将接收号码范围事件的端点。 |
curl https://api.nokycnumber.com/v1/numbers \
-H "Authorization: Bearer sk_live_…" \
-H "Idempotency-Key: 9b3d4a7c-8a4c-2f1e-9b3d-4a7c8a4c2f1e" \
-d '{
"available_id": "navail_2k7m9p3w8x4t",
"billing_period": "yearly",
"addons": ["ai-pickup"]
}'{
"id": "num_8a4c2f1e9b3d",
"object": "number",
"number": "+33611112222",
"display": "+33 6 11 11 22 22",
"country": "fr",
"type": "mobile",
"tier": "premium",
"status": "active",
"billing_period": "yearly",
"renews_at": "2027-04-26T11:23:00Z",
"ai_enabled": true,
"created_at": "2026-04-26T11:23:00Z"
}/v1/numbers/{id}
通过 id 检索单个号码。
curl https://api.nokycnumber.com/v1/numbers/num_8a4c2f1e9b3d \
-H "Authorization: Bearer sk_live_…"/v1/numbers/{id}
更新号码的可变字段。使用 POST /v1/numbers/{id}/renew 延长周期。
| Field | 类型 | Description |
|---|---|---|
auto_renew 可选 | boolean | 切换周期结束时的自动续费状态。 |
webhook_url 可选 | string | 替换号码范围的 webhook 目标。 |
addons 可选 | array | 替换当前启用的 AI 附加功能集。 |
on_off 可选 | object | 设置静音时间/关闭窗口。请参阅 AI 配置。 |
/v1/numbers/{id}
释放号码。号码将在周期结束时返回号码池,之后可能被重新分配给其他客户。返回 204 No Content。
curl -X DELETE https://api.nokycnumber.com/v1/numbers/num_8a4c2f1e9b3d \
-H "Authorization: Bearer sk_live_…"已释放的号码无法恢复。如果您可能还想使用它,建议先通过 PATCH 发送 { "status": "paused" } 进行暂停。
通话
通话是从您的号码发起的单次语音会话。出站通话通过 POST /v1/calls 发起;入站通话会镜像到您的 webhook,也可通过 API 检索。
/v1/calls从您的某个号码发起出站通话。
| Field | 类型 | Description |
|---|---|---|
from 必填 | string | 您拥有的 num_ id。 |
to 必填 | string | E.164 格式目标号码,例如 +33612345678。 |
recording_enabled 可选 | boolean | 默认为 false。录音存储 30 天。 |
callerid_mask 可选 | string | "hide"、"rotate" 或您拥有的任何 E.164 号码。 |
metadata 可选 | object | 通话 webhook 中返回的任意 JSON 数据。 |
curl https://api.nokycnumber.com/v1/calls \
-H "Authorization: Bearer sk_live_…" \
-d '{
"from": "num_8a4c2f1e9b3d",
"to": "+33612345678",
"callerid_mask": "rotate"
}'{
"id": "call_2k7m9p3w8x4t",
"object": "call",
"from": "num_8a4c2f1e9b3d",
"from_e164": "+33647189022",
"to": "+33612345678",
"status": "ringing",
"direction": "outbound",
"started_at": "2026-04-26T11:24:01Z",
"answered_at": null,
"ended_at": null,
"duration_sec": 0,
"recording_url": null,
"cost_usd": null
}/v1/calls列出通话记录。按 number、direction、status 或 created_after / created_before 过滤。
/v1/calls/{id}检索单次通话记录。
/v1/calls/{id}/hangup强制终止进行中的通话。幂等操作。
SMS 消息
发送和检索 SMS。长消息按 GSM-03.38 / UCS-2 规则自动分段;响应显示用于计费的实际分段数。
/v1/sms从您的某个号码发送 SMS。
| Field | 类型 | Description |
|---|---|---|
from 必填 | string | 您拥有的 num_ id。 |
to 必填 | string | E.164 格式目标号码。 |
body 必填 | string | 消息正文。最多 1,600 个字符(10 个分段)。 |
send_at 可选 | string | 用于定时发送的 ISO-8601 格式未来时间戳。 |
media_urls 可选 | array | 最多 5 个图片/视频 URL。仅限 MMS——在支持的国家有效。 |
curl https://api.nokycnumber.com/v1/sms \
-H "Authorization: Bearer sk_live_…" \
-H "Idempotency-Key: 9b3d4a7c-8a4c-2f1e-9b3d-4a7c8a4c2f1e" \
-d '{
"from": "num_8a4c2f1e9b3d",
"to": "+33612345678",
"body": "Bonjour. Your code is 482917."
}'{
"id": "sms_4n2v8j1q6h7y",
"object": "sms",
"from_e164": "+33647189022",
"to": "+33612345678",
"body": "Bonjour. Your code is 482917.",
"direction": "outbound",
"segments": 1,
"status": "queued",
"created_at": "2026-04-26T11:24:50Z",
"delivered_at": null,
"cost_usd": 0.012
}/v1/sms列出消息。按 number、direction、status 过滤。
/v1/sms/{id}检索单条消息,包含分段级别的送达状态。
语音信箱
语音信箱自动存储、转录和翻译。音频 URL 为预签名链接,签发后 1 小时过期。
/v1/voicemails列出语音信箱。分页方式与其他列表端点相同。
/v1/voicemails/{id}检索单条语音信箱,包含转录内容和音频 URL。
{
"id": "vm_5p3w8x4t9k2m",
"object": "voicemail",
"number_id": "num_8a4c2f1e9b3d",
"from_e164": "+33612345678",
"received_at": "2026-04-26T11:25:42Z",
"duration_sec": 27,
"audio_url": "https://files.nokycnumber.com/vm/5p3w8x4t9k2m.mp3?expires=1745676342&sig=…",
"transcript": {
"text": "Bonjour, c'est Marc. Rappelez-moi quand vous pouvez.",
"language": "fr",
"translation_en": "Hello, this is Marc. Call me back when you can.",
"summary": "Marc asks for a callback.",
"sentiment": "neutral"
}
}translation_en 和 summary 都需要 ai-summary 附加功能。
/v1/voicemails/{id}永久删除语音信箱及其音频文件。返回 204 No Content。
AI 配置
每个号码都可运行 AI 助手,在您无法接听时接听来电、筛选未知来电者、汇总语音信箱或实时翻译对话。通过 AI 子资源按号码配置。
/v1/numbers/{id}/ai检索号码的当前 AI 配置。
{
"object": "ai_config",
"number_id": "num_8a4c2f1e9b3d",
"addons": ["ai-pickup", "ai-summary"],
"auto_pickup": {
"enabled": true,
"after_rings": 4,
"script": "I'm unavailable right now. Leave your name, the reason for the call, and a callback number.",
"language": "auto",
"voice": "neutral_fr"
},
"screening": { "enabled": false },
"translator": { "enabled": false, "target_language": "en" },
"voicemail_summary": { "enabled": true, "include_sentiment": true }
}/v1/numbers/{id}/ai更新一个或多个 AI 功能。每个块均为可选;仅更新存在的字段。
语音
可用语音:neutral_en、neutral_fr、neutral_es、neutral_de、neutral_jp、warm_en、warm_fr。企业客户可申请自定义克隆语音。
账户
读取账户级别数据:余额、使用统计、已配置的 webhook。
/v1/account检索您的账户信息。
{
"object": "account",
"email_hash": "9b3d4a7c8a4c2f1e",
"balance_usd": 47.32,
"default_country": "fr",
"active_numbers": 3,
"monthly_call_minutes": 412,
"monthly_sms_segments": 1820,
"created_at": "2026-04-12T09:15:00Z"
}/v1/account/usage当前周期的详细用量明细。传入 period=last_30d 或 period=last_90d。
Webhook
订阅来自您账户或特定号码的事件。我们将向您的端点 POST 一个 JSON 事件,并在 24 小时内以指数退避方式最多重试 5 次。
事件信封
{
"id": "evt_3d4a7c8a4c2f",
"object": "event",
"type": "sms.received",
"created": "2026-04-26T11:25:42Z",
"livemode": true,
"data": { "object": { "id": "sms_…", … } },
"request_id": "req_8a4c2f1e9b3d4a7c"
}签名验证
每个请求都带有 X-NoKYC-Signature 标头,格式为 t=<ts>,v1=<hex>。签名是使用端点签名密钥对 <ts>.<raw_body> 计算的 HMAC-SHA256。请拒绝任何超过 5 分钟的请求。
# Pseudocode
ts, v1 = parse(header)
if abs(now - ts) > 300: reject
expected = hmac_sha256(secret, f"{ts}.{body}")
if not constant_time_eq(expected, v1): reject端点
/v1/webhook_endpoints注册新的 webhook 端点。签名密钥仅返回一次;请妥善保存。
| Field | 类型 | Description |
|---|---|---|
url 必填 | string | 我们将向其 POST 事件的 HTTPS URL。 |
enabled_events 必填 | array | 订阅列表,例如 ["sms.received","call.completed"]。使用 ["*"] 订阅全部。 |
description 可选 | string | 用于您自己记账的自由格式备注。 |
/v1/webhook_endpoints列出您的端点。
/v1/webhook_endpoints/{id}移除端点。返回 204。
事件类型
| 事件 | 触发条件 |
|---|---|
number.activated | 新号码已配置并准备就绪。 |
number.renewed | 周期续费成功。 |
number.paused | 号码已进入开/关时间窗口暂停状态。 |
number.released | 号码已永久释放回号码池。 |
call.initiated | 出站通话已发起。 |
call.answered | 对方已接听。 |
call.completed | 通话已结束(任何原因)。 |
call.recorded | 录音已完成并可访问。 |
sms.received | 入站 SMS 已送达您的号码。 |
sms.sent | 出站 SMS 已被运营商接受。 |
sms.delivered | 运营商已确认送达回执。 |
sms.failed | 运营商已拒绝——请检查 failure_code。 |
voicemail.created | 新语音信箱已录制并转录。 |
ai.pickup | AI 自动接听了一个来电。 |
account.balance_low | 余额低于您设置的阈值。 |
对象模式
number
{
"id": "string · num_…",
"object": "string · constant \"number\"",
"number": "string · E.164",
"display": "string · pretty-printed",
"country": "string · ISO-2",
"type": "enum · mobile | landline",
"tier": "enum · standard | premium",
"tier_pattern": "string | null · double-repeat | sequential | mirror | round | …",
"status": "enum · active | paused | released",
"billing_period": "enum · monthly | quarterly | yearly",
"renews_at": "string · ISO-8601 UTC",
"auto_renew": "boolean",
"addons": "array · ai-pickup | ai-screen | ai-summary | ai-trans",
"ai_enabled": "boolean",
"metadata": "object | null",
"created_at": "string · ISO-8601 UTC"
}call
{
"id": "string · call_…",
"object": "string · constant \"call\"",
"from": "string · num_…",
"from_e164": "string · E.164",
"to": "string · E.164",
"direction": "enum · inbound | outbound",
"status": "enum · queued | ringing | in_progress | completed | failed | no_answer | busy",
"started_at": "string · ISO-8601 UTC",
"answered_at": "string | null",
"ended_at": "string | null",
"duration_sec": "integer",
"recording_url": "string | null · pre-signed, expires in 1h",
"cost_usd": "number | null"
}sms
{
"id": "string · sms_…",
"object": "string · constant \"sms\"",
"from": "string · num_…",
"from_e164": "string · E.164",
"to": "string · E.164",
"body": "string",
"media_urls": "array · up to 5",
"direction": "enum · inbound | outbound",
"segments": "integer · 1–10",
"status": "enum · queued | sent | delivered | failed | undelivered",
"failure_code": "string | null",
"created_at": "string · ISO-8601 UTC",
"delivered_at": "string | null",
"cost_usd": "number | null"
}官方 SDK
HTTP API 是权威来源,但这些 SDK 提供了开箱即用的类型绑定、重试、幂等性和 webhook 验证。
-
node
npm install @nokycnumber/sdk -
python
pip install nokycnumber -
go
go get github.com/nokycnumber/sdk-go -
php
composer require nokycnumber/sdk -
ruby
gem install nokycnumber