查询电话号码
一次调用即可了解号码的全部信息。本文所有操作都需要具有 lookup 权限范围的 API 密钥。
执行基本查询
只需发送号码,无需其他参数。基本查询始终计费一次,始终返回号码所属国家、当前服务网络、号段发放网络以及大致的线路类型。
const answer = await bird.lookup.phoneNumber({
phone_number: "+31612345678",
type: ["classification", "score"],
});
console.log(answer.country_code, answer.line_type);
// Only a block whose status is ok carries a value, and only that one is billed.
if (answer.score?.status === "ok") console.log(answer.score.value);answer = client.lookup.phone_number(
phone_number="+31612345678", type=["classification", "score"]
)
print(answer.country_code, answer.line_type)
# Only a block whose status is ok carries a value, and only that one is billed.
if answer.score is not None and answer.score.status == "ok":
print(answer.score.value)answer, err := client.Lookup.PhoneNumber(context.Background(), bird.LookupPhoneNumberParams{
PhoneNumber: "+31612345678",
Type: []bird.LookupProperty{"classification", "score"},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(*answer.CountryCode, *answer.LineType)
// Only a block whose status is ok carries a value, and only that one is billed.
if answer.Score != nil && *answer.Score.Status == "ok" {
fmt.Println(*answer.Score.Value)
}$answer = $bird->lookup->phoneNumber(
(new PhoneNumberLookupRequest())
->setPhoneNumber('+31612345678')
->setType(['classification', 'score']),
);
echo $answer->getCountryCode(), ' ', $answer->getLineType();
// Only a block whose status is ok carries a value, and only that one is billed.
if ($answer->getScore()?->getStatus() === 'ok') {
echo $answer->getScore()->getValue();
}bird lookup phone-number \
--phone-number +31612345678 \
--type classification \
--type presencecurl -X POST "https://us1.platform.bird.com/v1/lookup/phone-number" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"phone_number": "+31612345678",
"type": [
"classification",
"presence"
]
}'号码书写方式
先发送国家呼叫代码,再发送国内号码。开头的 + 是可选的,用 00 代替也可以,因此 +31612345678、31612345678 和 0031612345678 都是同一个号码。
仅按国内拨号格式书写、不含国家代码的号码会被拒绝,而非猜测其归属。0612345678 会返回 E22000,因为补上国家代码可能指向另一个真实号码,并导致你为该查询付费。
基础查询返回的内容
country_code 是号码所属的国家;当号码不属于任何单一国家时(如非地理号段),该字段为空。
network_info 是当前为该号码提供服务的网络,original_network_info 是分配该号段的网络。两者在号码发生过携号转网时会不同,此时 flags 包含 ported。
line_type 表示号码的线路类型:mobile、fixed_line、voip、toll_free、premium_rate、satellite、pager、payphone、m2m、service、other 或 unknown。unknown 表示运营商平台对该号段没有分类;other 表示有分类但在此处没有对应值。如需更精确的分配业务类型,请请求 classification 属性。它从不同的数据源返回结果,词汇范围更广,并且独立报告,便于你区分两者。
添加属性
在 type 中指定你需要的属性。每个属性单独计费,且仅在成功返回时收费。
| 属性 | 返回内容 |
|---|---|
classification | 号段的精确分配业务类型:高费率、卫星、M2M、公用电话。 |
porting | 号码最近一次转网的时间,以及所有转网记录。 |
presence | 号码当前是否在网络上处于活跃状态。 |
roaming | 号码是否在漫游,以及使用的是哪个网络。 |
sim_swap | SIM 卡最近一次更换的时间。 |
score | 0 到 100 的可信度评分。 |
classification、porting 和 score 读取存储数据,返回速度快。presence、roaming 和 sim_swap 需要访问实时网络,因此速度较慢,且覆盖范围因运营商而异。相比存储类属性,这些属性更常返回 unavailable 或 inconclusive。
有两个属性以更高精度回答基础查询已涉及的问题。porting 提供转网日期和完整历史记录,而基础查询的 ported 标志仅表明是否曾发生过转网。classification 将 line_type 解析为精确的分配业务类型。
先读状态,再读值
每个属性块都带有 status,只有 ok 才携带值。
{
"phone_number": "+441904123456",
"country_code": "GB",
"line_type": "service",
"classification": {
"status": "ok",
"value": "premium_rate"
},
"score": {
"status": "unavailable"
}
}在该响应中,你被收取了基础查询和 classification 的费用,未被收取 score 的费用。
先读取 status,将 ok 以外的任何值都视为 "not answered"。这是一个开放词汇表,你不认识的值是未来新增的状态,而非错误。
当网络不提供精确数值时,有两个块会返回范围而非确切值。sim_swap 在只知道时间范围时返回 min_days 和 max_days,而非 last_swapped_at。porting 在登记机构记录了转网时段但未记录具体日期时设置 last_ported_at_is_approximate。
有一个字段读起来像是否定结果,但实际上是肯定发现:porting.ported 设为 false 表示已查询登记机构且该号码无转网记录,而非无法查询。这正是 status 的作用所在。
重试而不重复付费
查询会产生费用,因此重试的请求不应再次购买结果。发送一个 Idempotency-Key,相同请求的重复调用将回放存储的结果,而非执行新的查询。请参阅幂等性。
该操作的 GET 形式将号码放在 URL 中,无法携带幂等键。对于任何自动化场景,请使用 POST 形式。
错误
| 错误码 | 含义 |
|---|---|
E22000 | 号码不是有效的国际格式电话号码。未产生费用。 |
E22001 | 组织的钱包余额不足以支付此次查询。请充值后重试。未产生费用。 |
E22002 | 查询服务暂时不可用。请使用退避策略重试。未产生费用。 |
属性失败不是错误。它以状态的形式出现在对应的块中,基础查询结果仍然正常返回。
后续步骤
- 查询邮箱地址是 Lookup 的另一部分。
- Lookup API 参考文档记录了每个字段和每个属性块。
- 请求速率限制介绍了这些调用所使用的
lookup桶。 - 电话号码查询:发送前验证号码 是一段演示如何执行查询并添加实时网络检查的视频。