从 Telserv 迁移到 Bird
本指南适用于调用 Telserv 合作伙伴 API(V1 或 V2)来购买、路由和释放号码,并且现在要迁移到 Bird API 的集成。
Bird API 服务于所有 Bird 产品,因此其号码和语音操作遵循 Bird 自身的约定,而非 Telserv 的约定。您的集成使用的大多数功能都有对应的 Bird 调用。端点、载荷、标识符和身份验证方式均不同,因此请计划重写集成。当 Bird 以不同方式完成某项任务时,本指南会展示具体做法。
本指南仍在编写中。它涵盖了 Bird 已支持的内容,并随着迁移的推进而扩充。如果您使用的某个 Telserv 操作未在此列出,说明它仍需范围界定和开发才能添加;请向您的迁移联系人咨询。
开始之前
- 已完成身份验证的 Bird 组织,首次购买号码需要此验证。
- 一个具有示例所需权限范围的 API 密钥:
numbers的写入权限(用于号码和订单),compliance的写入权限(用于独立的所有权文件操作),以及voice_management的写入权限(用于 SIP 中继、语音号码和已验证号码)。测试呼叫还需要voice:write,读取呼叫段需要voice:read。 - 钱包余额。订单从钱包中扣款。当订单被拒绝时解释了
402和412拒绝的原因。
您在 Telserv 中管理的号码无需重新购买。号码迁移到您的 Bird 工作区后,它们会出现在 GET /v1/numbers 中。您的迁移联系人会确认迁移完成的时间。要获取已迁移号码的 nda_ 标识符,请使用 GET /v1/numbers?number=<digits> 查找,输入带国家代码的号码,并将 id 保存为 NUMBER_ID。
示例从 BIRD_API_KEY 读取您的密钥,从 BIRD_API_URL 读取其区域主机:bk_eu1_ 密钥使用 https://eu1.platform.bird.com,bk_us1_ 密钥使用 https://us1.platform.bird.com。其他变量(如 TRUNK_ID 和 NUMBER_ID)保存的是前一个响应中的标识符;每个步骤会说明它设置的变量。
接口约定的变化
| 方面 | Telserv 合作伙伴 API | Bird API |
|---|---|---|
| 认证 | X-ApiKey 请求头(V2)或 apiKey 参数(V1),根据您的 IP 白名单进行校验 | 使用 Authorization: Bearer 搭配一个 API 密钥,其权限范围指定了可访问的产品领域。IP 白名单为可选项:在 API keys 中的密钥上通过 IP restrictions 设置 |
| 标识符 | 整数。购买号码时会为其分配一个新的 id | 带前缀的 TypeID,如 nda_、nor_、vnu_ 和 spt_。号码在分配给您期间保持其 nda_ id 不变 |
| 电话号码 | 不带前导 + 的数字 | 带前导 + 的 E.164 格式 |
| 分页 | start 和 limit 偏移量,每页最多 1000 条 | 游标分页:limit 最大 100(默认 25),然后将 starting_after 设为上一页的 next_cursor。参见分页 |
| 错误 | errorCode 表示异常类名,403 涵盖资源缺失和许多校验失败 | error.code 是稳定的 E 代码,附带文档页面,在已知恢复方式时还附带 remediation。资源缺失返回 404,前提条件不满足返回 412,输入无效返回 422 并附字段详情。参见错误 |
| 环境 | LIVE 和 SANDBOX,各有独立密钥 | 单一环境。每笔订单购买并扣费一个真实号码,每次测试通话都是真实通话 |
| 重试 | 无幂等键 | 写入操作使用 Idempotency-Key 请求头。相同的键和请求体会以 Idempotency-Replay: true 重放首次响应;相同的键搭配不同的请求体则返回 409。参见幂等性 |
Bird API 会以 422 和 E01029 拒绝无法识别的查询参数。请从请求中移除 city 等 Telserv 专有过滤器,而不是直接传递它们。
一个号码,两个标识符
分配到您工作区的语音号码有两条记录,各自拥有独立的标识符:
- 分配记录,由
GET /v1/numbers返回。其id对专属号码以nda_开头,对共享号码以nal_开头;订单的number_id是所购号码的nda_标识符。用它来读取、命名和引用号码,以及释放专属号码。 - 语音记录
vnu_,由GET /v1/voice/numbers返回。用它来读取和更改号码来电的路由目标。没有语音功能的号码(例如仅支持 SMS 的号码)没有语音记录。
语音操作会以 422 拒绝 nda_ 或 nal_ 标识符。要查找号码的语音记录,请将 search 设为号码的数字来列出语音号码,然后取 provider.number_id 等于分配记录 id 的条目。将号码路由到您的 SIP 中继展示了该请求,管理您的电话号码介绍了查找方法。
Telserv 的 GET /numbers/{dnisId} 在 Bird 中变为两次读取:分配记录用于状态和所有权文件,语音记录用于路由。
将 Telserv 操作映射到 Bird
每张表列出一项任务、执行该任务的 Telserv 调用,以及现在执行该任务的 Bird 调用。表下方的说明介绍请求或响应中的变化。
购买
| 任务 | Telserv | Bird |
|---|---|---|
| 搜索在售号码 | GET /shop | GET /v1/numbers/available |
| 查询单个号码 | GET /shop/{stockDnisId} | GET /v1/numbers/available/{number} |
| 购买号码 | POST /shop/{stockDnisId} | POST /v1/numbers/orders |
| 锁定号码 | POST /shop/{stockDnisId}/reserve、GET /shop/reserved | POST /v1/numbers/orders |
- 搜索。
country_code为必填项,因此一次搜索只覆盖一个国家。prefix接受国家代码后的国内号码:Telserv 的prefix=3170对应为country_code=NL&prefix=70。使用prefix代替city按区号筛选,使用number_type和capabilities代替productId进行筛选。 - 搜索结果中的所有权文件。 每条结果包含
ownership_registration_required,替代excludeNumbersRequireVerification筛选条件。true值表示该号码从购买时开始计费,但在其所有权文件审核通过之前,不会发送 SMS,也无法承载呼入或呼出语音通话。 - 查询单个号码。 通过其 E.164 号码进行查询。
- 价格。 Telserv 在号码和产品的详细查询中返回
pricing.staticPricing。在 Bird 中,每条搜索结果在pricing中包含您组织的价格:setup_price替代nrc,recurring_price每recurring_period替代mrc,intervals_per_charge表示一次收费涵盖多少个计费周期。使用您的引用标识搜索并购买号码介绍了价格字段。 - 购买。 发送
number和可选的reference。订单从您的钱包中扣款。大多数订单返回201;等待运营商处理的订单返回202,需要轮询其状态。 - 锁定。 下单即锁定该号码。先查询候选号码,然后下单。
号码
| 任务 | Telserv | Bird |
|---|---|---|
| 列出号码 | GET /numbers | GET /v1/numbers |
| 读取单个号码 | GET /numbers/{dnisId} | GET /v1/numbers/{number_id},使用分配记录的 nda_ 或 nal_ id;以及 GET /v1/voice/numbers/{number_id},使用语音记录的 vnu_ id |
| 变更号码 | PATCH /numbers/{dnisId} | PATCH /v1/numbers/{number_id},使用分配记录的 nda_ 或 nal_ id;以及 PATCH /v1/voice/numbers/{number_id},使用语音记录的 vnu_ id |
| 释放号码 | DELETE /numbers/{dnisId}?requestedCancelDate= | 在已付费周期结束时 DELETE /v1/numbers/{number_id},或立即 POST /v1/numbers/{number_id}/release,两者均使用分配记录的 nda_ id |
- 列表。 列表中包含当前分配给您的号码。在 Bird 中订购后已释放的号码仍可通过
GET /v1/numbers/orders中的订单查看。核对您的号码列出了筛选条件的映射关系。 - 读取。 状态、所有权文件和价格在分配记录上,路由在语音记录上。分配记录的
pricing对象(含每recurring_period的recurring_price和intervals_per_charge)取代了pricing.staticPricing.mrc,且列表也包含该信息,而 Telserv 的GET /numbers则不包含。 - 变更。
name和reference在分配记录上,路由在语音记录上。在您的 SIP 设备上设置强制编解码器和并发呼叫上限。destinationDistributionType变为 SIP 中继上的网关priority:FailOver为每个网关分配不同的priority,RoundRobin则为它们分配相同的值。 - 释放。
DELETE保留号码直到您已付费周期结束后再释放。POST …/release立即释放号码。两者都不接受日期参数。释放号码展示了两种请求。
目标地址和配置文件
| 任务 | Telserv | Bird |
|---|---|---|
| 将呼叫发送到 SIP 设备 | POST /numbers/{dnisId}/destinations | POST /v1/voice/trunks/{trunk_id}/gateways,然后路由 trunk |
| 将呼叫转接到电话 | POST /numbers/{dnisId}/destinations | 路由 forward |
| 停止接听来电 | DELETE /numbers/{dnisId}/destinations | 路由 reject |
| 读取目标配置文件 | GET /destinationprofiles、GET /destinationprofiles/{id} | GET /v1/voice/trunks 和 GET /v1/voice/trunks/{trunk_id}/gateways |
| 将配置文件应用到号码 | POST /numbers/{dnisId}/destinations/profile | 使用 trunk_id 路由 trunk |
- SIP 设备。 网关属于中继,为路由到该中继的每个号码提供服务,因此需要不同目标列表的号码需要不同的中继。
sortOrder变为priority。在您的 SIP 设备上设置振铃时间和时间窗口。 - 转发。 设置
forward_to和forward_as。forward_to必须是您的已验证号码之一;未验证的号码会返回412和E21053。forward_as选择转发来电显示的主叫号码。一个号码同一时间只能有一条路由,因此如果需要从 SIP 设备回退到电话号码,请从您的 SIP 设备转发来电。 - 停止接听来电。 该号码会拒绝来电,直到您重新为其设置路由。如果需要用常设的默认路由代替默认配置文件,请将该号码路由到包含您默认网关的中继。
- 配置文件。
distributionType变为priority:FailOver为每个网关分配不同的priority,RoundRobin则为它们分配相同的值。分配策略按中继设置,因此需要不同分配策略的号码需要不同的中继。{dnis}占位符变为destination_format中的{number},prefixCLIP变为origination_format中{number}之前的文本。 - 应用配置文件。 中继通过其
spt_标识符寻址,而 Telserv 通过名称寻址配置文件。
文档和终端用户数据
| 任务 | Telserv | Bird |
|---|---|---|
| 查看要求 | GET /products/conditions、GET /masterdata/productconditions | 针对该号码使用 GET /v1/compliance/requirements;或使用 program 且不带 subject_id,查看某个国家在您持有号码之前要求填写的表单 |
| 上传文档 | POST /numbers/{dnisId}/documents | POST /v1/compliance/attachments,然后在提交中引用该附件。参见提交所有权文件 |
| 发送终端用户数据 | POST /numbers/{dnisId}/enduserdata | POST /v1/compliance/submissions,一次请求中同时提交这些数据和文档。参见提交所有权文件 |
| 替换文档 | 再次调用 POST /numbers/{dnisId}/documents | POST /v1/compliance/submissions/{submission_id}/resupply,提交被拒绝或已过期的答复 |
| 查看文件审核进度 | GET /numbers/{dnisId}/documents | GET /v1/numbers/{number_id} 上的 ownership,以及提交记录中每项答复的审核结论 |
- 要求。 Telserv 的条件目录一次涵盖所有产品;Bird 一次读取一份表单。要查询单个号码的要求,请使用
subject_kind=number,将其nda_标识符作为subject_id,并提供其country_code;或在购买前读取表单,将program设为号码类型且不提供subject_id。fields中的每个条目取代一个 Telserv 条件或终端用户标签:其key是您作答时使用的键,data_typedocument表示该条目需要上传文件。 - 文档。 以
multipart/form-data上传文件,代替 base64fileContent;上传每份文档列出了接受的文件。重复上传同一文件会返回同一附件。仅上传不会提交任何内容:引用其attachment_id的提交才会提交。 - 同时提交终端用户数据和文档。 Telserv 每份文档单独调用一次,终端用户数据则作为一个标签列表在另一次调用中提交。Bird 在一次提交中接收所有答复(包括填写的数据和文档),且没有草稿:该请求会直接提交答复供审核。之后请跟踪
ownership.next,它会指明需要更正时使用补充提交,仅在必要时才需要新的提交(提交所有答复)。 - 替换。 只发送您要替换的答复,其他答复保留各自的审核状态。Telserv 在号码待验证期间接受某个条件的新文件,并重置该条件的审核;Bird 可替换被拒绝、已过期或尚未提供的答复,但会拒绝仍在审核中或已通过的答复,除非在我们发起的更正请求未关闭期间,该答复被标记为
editable_for_verifier_repair(更正被拒绝的答复)。 - 进度。
ownership.status和ownership.next报告号码所处的状态。每项答复都有自己的state,被拒绝的答复附带审核人员的reason。Bird 还会通过电子邮件将每个结果发送给您组织的所有者,以及最近一次提交或更正该提交的人员。当号码无需提交文件时,ownership通常为null。
提交所有权文件展示了相关请求,提交号码的所有权文件介绍了完整流程,包括通过控制台提交以及随订单一起提交。
产品与主数据
| 任务 | Telserv | Bird |
|---|---|---|
| 浏览产品 | GET /products、GET /products/{productId} | GET /v1/numbers/available,需要提供 country_code,并返回该国家在售的号码。Bird 没有全球产品目录,也没有与 productId 对应的内容。没有任何 API 列出在售的国家和号码类型;电话号码定价页面按国家列出 Bird 的标准价格。 |
每条搜索结果用 number_type、capabilities 和 ownership_registration_required 描述其产品,并携带您组织的价格,代替产品的 pricing.staticPricing(nrc 和 mrc)。Bird 的标准价格在电话号码定价页面上。Telserv 的按分钟 sessionPricing 在这些读取中没有对应项;语音费率在语音定价页面上。
Telserv 的号码类型与 Bird 的 number_type 对应关系如下:
Telserv numberType | Bird number_type |
|---|---|
DID | local 或 national,取决于号码 |
FreePhone | toll_free |
Mobile | mobile |
实现方式不同的任务
以下 Telserv 任务在 Bird 中的实现方式有所不同。在迁移依赖其中某项功能的集成之前,请提前做好规划。
- 所有权文件。 在一次提交中提交号码的文档和终端用户数据,不支持草稿;被拒绝的答案通过补充提交(resupply)进行更正。
- 预留。 选定号码后直接下单;下单即锁定该号码。
- 单号码通话设置。 在您的 SIP 设备上设置强制编解码器、并发通话上限、振铃时间和时间窗口。
- 释放日期。 Bird 在已付费周期结束时或立即释放号码,不支持指定日期。请在您自己一侧保留之前发送给 Telserv 的取消日期,并在到期时执行操作。
- 钱包余额。 在控制台中查看余额并充值。
使用您的引用标识搜索并购买号码
搜索一个国家。组合 number_type、capabilities 和 prefix 来缩小结果范围:
curl "$BIRD_API_URL/v1/numbers/available?country_code=NL&number_type=mobile&capabilities=voice&limit=10" \
--header "Authorization: Bearer $BIRD_API_KEY"每条结果包含一个 pricing 对象,其中是您的组织为该号码支付的价格,为税前金额并以您的账单货币计价,已应用您与 Bird 协商的任何价格:
setup_price在您下单购买号码时一次性收取。公布的开通费为零时,其amount为"0"。无开通费时该字段本身为null;当recurring_price为null时也为该值,因为该号码无法订购。recurring_price是每recurring_period的费率。intervals_per_charge是一次收费所计费的recurring_period数量。税前周期费用为recurring_price乘以intervals_per_charge,在号码分配到您的工作区时以及每次续费时收取;开通费另计。对于等待运营商处理的订单,号码在订单完成时分配。
API 参考文档展示了一个示例结果。包含 pricing.recurring_price: null 的结果未提供周期性价格。请在下单前联系销售,为您获取该国家和号码类型的定价。
控制台和 API 使用相同的组织价格,包括换算为您账单货币的金额。读取价格不会锁定报价:在后续收费之前,资费或汇率的变动可能改变该笔收费的金额。如果价格查询失败,搜索会返回 503 和 E14009。请使用指数退避重试读取;查询失败绝不意味着该号码不收费。
要在下单前确认候选号码及其价格,请使用 GET /v1/numbers/available/{number} 读取该号码。404 表示该号码已不再出售。
使用您在 Telserv 中使用的引用标识下单购买号码,并选择一个幂等键,在本次购买的任何重试中继续使用:
curl --request POST "$BIRD_API_URL/v1/numbers/orders" \
--header "Authorization: Bearer $BIRD_API_KEY" \
--header "Content-Type: application/json" \
--header "Idempotency-Key: order-CUST-778812" \
--data '{"number": "+31612345678", "reference": "CUST-778812"}'201 响应包含 status: completed 和一个 number_id,即号码的 nda_ 标识符。将其保存为 NUMBER_ID。202 响应表示订单正在等待运营商处理:轮询订单,直到其 status 变为 completed 或 failed。如果订单最终失败,已收取的开通费不予退还。引用标识在订单完成时设置到号码上。引用标识最多支持 100 个字符,不需要唯一。
对工作区已分配的号码重试下单会返回现有订单,因此重试不会重复扣费。购买和释放号码解释了各种拒绝情况。
要稍后设置或更改引用标识,请将 reference(以及可选的 name)发送到 PATCH /v1/numbers/{number_id}。发送 null 可清除字段。
检查号码是否可以承载通话
status 为 pending_ownership_registration 的号码已被分配并计费,但在其所有权文件审核通过之前,它不会发送 SMS,并会拒绝所有来电和去电语音通话。在为号码配置路由或对其发起测试呼叫之前,请使用 GET /v1/numbers/{number_id} 读取该号码,并检查 status 是否为 active。如果状态为待审核,请提交所有权文件。已分配号码的状态解释了每个值的含义。
以下示例使用一个荷兰手机号码。无论号码属于哪个国家,请以相同方式检查您自己号码的 status。
提交所有权文件
Telserv 接收号码所有权文件的方式是每份文档一次 POST /numbers/{dnisId}/documents 调用,所有标签一次 POST /numbers/{dnisId}/enduserdata 调用。Bird 则在您上传文档后,通过一次提交同时接收两者。
-
读取号码的
country_code并将其保存为COUNTRY_CODE。该命令使用jq提取该值;如果您不使用jq,请手动读取:代码示例COUNTRY_CODE=$(curl -s "$BIRD_API_URL/v1/numbers/$NUMBER_ID" \ --header "Authorization: Bearer $BIRD_API_KEY" | jq -r .country_code) -
读取号码所在国家的要求。
fields中的每个条目包含您作答时使用的key、一个data_type,以及表示是否必须作答的required。将响应中给出的program保存为PROGRAM:代码示例curl "$BIRD_API_URL/v1/compliance/requirements?subject_kind=number&subject_id=$NUMBER_ID&country_code=$COUNTRY_CODE" \ --header "Authorization: Bearer $BIRD_API_KEY"返回
422和E19001表示该国家没有所有权表单。 -
上传每个
document字段要求的文档,以文件形式上传,而不是使用 base64fileContent。将响应中的id(即附件的tca_标识符)保存为ATTACHMENT_ID:代码示例curl --request POST "$BIRD_API_URL/v1/compliance/attachments" \ --header "Authorization: Bearer $BIRD_API_KEY" \ --form "file=@registration-certificate.pdf" -
一次提交所有答案:每个
required为true的字段各一个条目,您有真实答案的每个可选字段也各一个条目;终端用户数据作为value,每份文档作为attachment_id。不要为可选字段编造值,直接省略即可。示例展示了两个答案;发送前请补全其余必填答案。此请求会提交答案以供审核。将响应中的id(即提交记录的csb_标识符)保存为SUBMISSION_ID:代码示例curl --request POST "$BIRD_API_URL/v1/compliance/submissions" \ --header "Authorization: Bearer $BIRD_API_KEY" \ --header "Content-Type: application/json" \ --header "Idempotency-Key: ownership-CUST-778812" \ --data '{"subject_kind": "number", "subject_id": "'"$NUMBER_ID"'", "program": "'"$PROGRAM"'", "country_code": "'"$COUNTRY_CODE"'", "answers": [{"key": "business_registration_number", "value": "90012768"}, {"key": "business_registration_certificate", "attachment_id": "'"$ATTACHMENT_ID"'"}]}'201响应返回提交记录。422表示未提交任何内容:请更正请求体,并使用新的幂等键发送,因为原来的键会重放该拒绝结果。提交所有答案解释了每种拒绝情况。 -
当审核人员拒绝某个答案时,只需替换该答案,具体方法见更正被拒绝的答案:
代码示例curl --request POST "$BIRD_API_URL/v1/compliance/submissions/$SUBMISSION_ID/resupply" \ --header "Authorization: Bearer $BIRD_API_KEY" \ --header "Content-Type: application/json" \ --header "Idempotency-Key: ownership-fix-1-CUST-778812" \ --data '{"answers": [{"key": "business_registration_number", "value": "90012769"}]}'
要在购买时一并提交,请在 POST /v1/numbers/orders 的 compliance 块中发送相同的 answers。该订单使用现有的 numbers 写入权限范围,即使订单附带所有权文件也是如此。
使用 GET /v1/numbers/{number_id} 上的 ownership.status 跟踪审核进度。这些回答是以您企业名义作出的法律陈述,因此只提交已由相关负责人确认的回答。提交号码的所有权文件介绍了每个请求、审核流程以及随订单提交的方式。
将号码路由到您的 SIP 中继
新号码没有自己的路由,因此遵循您工作区的默认路由。该默认路由初始为 reject,但如果工作区已经设置了默认路由,新号码一经分配就会按该路由接听来电。要将来电投递到您的设备,请创建一个开启入站呼叫的 SIP 中继,为其添加网关,然后将号码指向该中继。SIP 中继介绍了如何将您的设备连接到中继。
-
创建中继并开启入站呼叫。保留响应中的
id,即中继的spt_标识符,存为TRUNK_ID:代码示例curl --request POST "$BIRD_API_URL/v1/voice/trunks" \ --header "Authorization: Bearer $BIRD_API_KEY" \ --header "Content-Type: application/json" \ --header "Idempotency-Key: trunk-production-pbx" \ --data '{"name": "Production PBX", "inbound_enabled": true}' -
添加网关。默认情况下,网关接收的被叫号码和主叫号码为 E.164 格式,带有
+。如果您的设备需要不带+的号码(如 Telserv 的{dnis}占位符),请将被叫号码的destination_format和主叫号码的origination_format设置为{number}:代码示例curl --request POST "$BIRD_API_URL/v1/voice/trunks/$TRUNK_ID/gateways" \ --header "Authorization: Bearer $BIRD_API_KEY" \ --header "Content-Type: application/json" \ --header "Idempotency-Key: gateway-pbx-primary" \ --data '{"sip_uri": "sip:pbx.example.com:5060", "priority": 0, "destination_format": "{number}", "origination_format": "{number}"}'如需故障转移,请添加第二个网关;网关所需的配置说明了
priority和号码格式。在没有幂等键的情况下再次创建相同的网关会返回409和E21047。 -
查找号码的语音记录。使用号码的数字进行搜索,取
provider.number_id等于分配记录id的条目的id。将其存为VOICE_NUMBER_ID:代码示例curl "$BIRD_API_URL/v1/voice/numbers?search=31612345678" \ --header "Authorization: Bearer $BIRD_API_KEY" -
将号码指向中继:
代码示例curl --request PATCH "$BIRD_API_URL/v1/voice/numbers/$VOICE_NUMBER_ID" \ --header "Authorization: Bearer $BIRD_API_KEY" \ --header "Content-Type: application/json" \ --data '{"inbound_configuration": {"route": {"type": "trunk", "trunk_id": "'"$TRUNK_ID"'"}}}'200响应显示新路由。入站呼叫关闭的中继会返回412和E21052。
关闭中继的入站呼叫或删除中继,会将路由到该中继的每个号码恢复为您工作区的默认路由,重新开启入站呼叫不会恢复这些路由。将呼叫送达 SIP 中继对此以及 trunk、forward 和 reject 路由进行了说明。
核对您的号码
使用最大页面大小遍历列表。将每页的 next_cursor 作为 NEXT_CURSOR 传入以读取下一页,直到 next_cursor 为 null。列表不返回总数。
curl "$BIRD_API_URL/v1/numbers?limit=100" \
--header "Authorization: Bearer $BIRD_API_KEY"
curl "$BIRD_API_URL/v1/numbers?limit=100&starting_after=$NEXT_CURSOR" \
--header "Authorization: Bearer $BIRD_API_KEY"Telserv 的列表过滤器对应到 Bird 的方式如下:
Telserv GET /numbers 上的过滤器 | GET /v1/numbers 上的 Bird 过滤器 |
|---|---|
number,匹配号码开头 | 不带 country_code 的 prefix,从完整号码开头匹配数字 |
prefix,等于接入码和区号,例如 3170 | country_code,将 prefix 设为国内号码数字:country_code=NL&prefix=70 |
reference,使用部分值 | search,匹配号码、名称或引用标识的部分内容,不区分大小写 |
reference,使用引号括起的精确值 | reference,返回具有该精确引用标识的号码。匹配区分大小写 |
| Bird 中新增 | number 返回一个带国家代码的完整号码,带或不带 + 或 00 均可:+31612345678、31612345678 和 0031612345678 查找的是同一个号码 |
在列表中查找号码详细介绍了每个过滤器。
每条记录包含 pricing,其中有每 recurring_period 的 recurring_price 和 intervals_per_charge。除非号码的价格已固定,否则 recurring_price 是您所在组织的当前费率,每次续费按续费时的有效费率收取,因此已计费的金额可能与之不同。列出您持有的所有号码说明了每个号码的计费货币、pricing 或其价格何时为 null,以及设置了 pricing.error 时应如何处理。
已释放的号码会从此列表中消失,通过 number_id 读取它会返回 404。如果您通过 Bird 订购了该号码,其已完成的订单仍保留在 GET /v1/numbers/orders 中。
释放号码
两个请求都针对专属号码,使用其 nda_ 标识符;共享号码会被拒绝,返回 E14002。要保留号码直到已付费周期结束,请取消它:
curl --request DELETE "$BIRD_API_URL/v1/numbers/$NUMBER_ID" \
--header "Authorization: Bearer $BIRD_API_KEY" \
--header "Idempotency-Key: cancel-CUST-778812"202 响应返回带有 releases_at(已付费周期结束时间)的号码。在此之前号码保持当前状态,订阅不再续费,届时号码将被释放。再次请求会返回相同的 releases_at,且取消操作不可撤销。没有订阅的号码会立即释放,响应为 200,号码的 status 设为 released。
要立即释放号码(包括已安排取消的号码):
curl --request POST "$BIRD_API_URL/v1/numbers/$NUMBER_ID/release" \
--header "Authorization: Bearer $BIRD_API_KEY" \
--header "Idempotency-Key: release-CUST-778812"204 响应表示号码已释放,立即生效。当前周期的剩余部分不予退款。
当号码的续费款项逾期未付时,两个请求都会返回 409 和 E03015,直到付款完成。
两个请求都不接受日期参数,因此请在您这边保留之前作为 requestedCancelDate 发送给 Telserv 的时间表。要保留号码到指定日期,请在该日期落入当前计费周期后取消号码:号码会在该周期结束时释放,即在指定日期当天或之后。要在指定日期准确放弃号码,请在当天释放它。释放号码介绍了每个请求对号码、费用和重试的影响。
向您的号码发起测试呼叫
要端到端检查路由,请从您的工作区可用作来电显示的另一个号码向该号码发起呼叫。该号码所在的国家必须在您的语音目的地中启用,否则呼叫无法接通。下面的请求运行一个内联序列,在呼叫接通后立即挂断,因此不需要已保存的序列。该请求会发起真实呼叫,正常通话费用适用。
将请求保存为 test-call.json。将您要显示的来电号码放在 from 中(您的工作区拥有的或已验证的号码),将被测号码放在 to 中:
{
"from": "+31612345679",
"to": "+31612345678",
"sequence": {
"definition": {
"schema_version": 1,
"expression_environment": "bird.cel.v1",
"nodes": [
{
"id": "entry",
"type": "trigger.start_call",
"type_version": 1,
"config": {},
"input": {},
"connections": { "event": { "node_id": "end", "port": "input" } }
},
{ "id": "end", "type": "voice.hangup", "type_version": 1, "config": {}, "input": {} }
]
},
"entry_node_id": "entry",
"trigger_data": {}
}
}发送请求:
curl --request POST "$BIRD_API_URL/v1/voice/calls" \
--header "Authorization: Bearer $BIRD_API_KEY" \
--header "Content-Type: application/json" \
--header "Idempotency-Key: ${TEST_CALL_KEY:?Set TEST_CALL_KEY once for this test call}" \
--data-binary @test-call.json每次测试将 TEST_CALL_KEY 设置为新值,在超时或结果不明确后重试同一测试时复用该值:三小时内相同的密钥和请求会重放首次接受结果,而不会发起第二次呼叫。202 响应表示呼叫已被接受,并返回其 initial_leg_id。接受并不证明呼叫已接通:使用 GET /v1/voice/legs/{leg_id} 读取呼叫段,或使用 GET /v1/voice/legs 及其 to 过滤器列出拨往该号码的呼叫段,并检查您的设备是否收到了呼叫。创建语音呼叫介绍了来电显示和目的地要求以及重试规则。