Sign inGet Started

从 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 合作伙伴 APIBird 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 调用。表下方的说明介绍请求或响应中的变化。

购买

任务TelservBird
搜索在售号码GET /shopGET /v1/numbers/available
查询单个号码GET /shop/{stockDnisId}GET /v1/numbers/available/{number}
购买号码POST /shop/{stockDnisId}POST /v1/numbers/orders
锁定号码POST /shop/{stockDnisId}/reserve、GET /shop/reservedPOST /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,需要轮询其状态。
  • 锁定。 下单即锁定该号码。先查询候选号码,然后下单。

号码

任务TelservBird
列出号码GET /numbersGET /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 立即释放号码。两者都不接受日期参数。释放号码展示了两种请求。

目标地址和配置文件

任务TelservBird
将呼叫发送到 SIP 设备POST /numbers/{dnisId}/destinationsPOST /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 通过名称寻址配置文件。

文档和终端用户数据

任务TelservBird
查看要求GET /products/conditions、GET /masterdata/productconditions针对该号码使用 GET /v1/compliance/requirements;或使用 program 且不带 subject_id,查看某个国家在您持有号码之前要求填写的表单
上传文档POST /numbers/{dnisId}/documentsPOST /v1/compliance/attachments,然后在提交中引用该附件。参见提交所有权文件
发送终端用户数据POST /numbers/{dnisId}/enduserdataPOST /v1/compliance/submissions,一次请求中同时提交这些数据和文档。参见提交所有权文件
替换文档再次调用 POST /numbers/{dnisId}/documentsPOST /v1/compliance/submissions/{submission_id}/resupply,提交被拒绝或已过期的答复
查看文件审核进度GET /numbers/{dnisId}/documentsGET /v1/numbers/{number_id} 上的 ownership,以及提交记录中每项答复的审核结论
  • 要求。 Telserv 的条件目录一次涵盖所有产品;Bird 一次读取一份表单。要查询单个号码的要求,请使用 subject_kind=number,将其 nda_ 标识符作为 subject_id,并提供其 country_code;或在购买前读取表单,将 program 设为号码类型且不提供 subject_id。fields 中的每个条目取代一个 Telserv 条件或终端用户标签:其 key 是您作答时使用的键,data_type document 表示该条目需要上传文件。
  • 文档。 以 multipart/form-data 上传文件,代替 base64 fileContent;上传每份文档列出了接受的文件。重复上传同一文件会返回同一附件。仅上传不会提交任何内容:引用其 attachment_id 的提交才会提交。
  • 同时提交终端用户数据和文档。 Telserv 每份文档单独调用一次,终端用户数据则作为一个标签列表在另一次调用中提交。Bird 在一次提交中接收所有答复(包括填写的数据和文档),且没有草稿:该请求会直接提交答复供审核。之后请跟踪 ownership.next,它会指明需要更正时使用补充提交,仅在必要时才需要新的提交(提交所有答复)。
  • 替换。 只发送您要替换的答复,其他答复保留各自的审核状态。Telserv 在号码待验证期间接受某个条件的新文件,并重置该条件的审核;Bird 可替换被拒绝、已过期或尚未提供的答复,但会拒绝仍在审核中或已通过的答复,除非在我们发起的更正请求未关闭期间,该答复被标记为 editable_for_verifier_repair(更正被拒绝的答复)。
  • 进度。 ownership.status 和 ownership.next 报告号码所处的状态。每项答复都有自己的 state,被拒绝的答复附带审核人员的 reason。Bird 还会通过电子邮件将每个结果发送给您组织的所有者,以及最近一次提交或更正该提交的人员。当号码无需提交文件时,ownership 通常为 null。

提交所有权文件展示了相关请求,提交号码的所有权文件介绍了完整流程,包括通过控制台提交以及随订单一起提交。

产品与主数据

任务TelservBird
浏览产品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 numberTypeBird number_type
DIDlocal 或 national,取决于号码
FreePhonetoll_free
Mobilemobile

实现方式不同的任务

以下 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 则在您上传文档后,通过一次提交同时接收两者。

  1. 读取号码的 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)
  2. 读取号码所在国家的要求。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 表示该国家没有所有权表单。

  3. 上传每个 document 字段要求的文档,以文件形式上传,而不是使用 base64 fileContent。将响应中的 id(即附件的 tca_ 标识符)保存为 ATTACHMENT_ID:

    代码示例
    curl --request POST "$BIRD_API_URL/v1/compliance/attachments" \
      --header "Authorization: Bearer $BIRD_API_KEY" \
      --form "file=@registration-certificate.pdf"
  4. 一次提交所有答案:每个 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 表示未提交任何内容:请更正请求体,并使用新的幂等键发送,因为原来的键会重放该拒绝结果。提交所有答案解释了每种拒绝情况。

  5. 当审核人员拒绝某个答案时,只需替换该答案,具体方法见更正被拒绝的答案:

    代码示例
    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 中继介绍了如何将您的设备连接到中继。

  1. 创建中继并开启入站呼叫。保留响应中的 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}'
  2. 添加网关。默认情况下,网关接收的被叫号码和主叫号码为 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。

  3. 查找号码的语音记录。使用号码的数字进行搜索,取 provider.number_id 等于分配记录 id 的条目的 id。将其存为 VOICE_NUMBER_ID:

    代码示例
    curl "$BIRD_API_URL/v1/voice/numbers?search=31612345678" \
      --header "Authorization: Bearer $BIRD_API_KEY"
  4. 将号码指向中继:

    代码示例
    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,等于接入码和区号,例如 3170country_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 过滤器列出拨往该号码的呼叫段,并检查您的设备是否收到了呼叫。创建语音呼叫介绍了来电显示和目的地要求以及重试规则。

后续步骤

继续查看此主题的文档、指南和示例。