手机归属地查询:CRM/客服系统接入,来电即显示归属地与运营商
# 手机归属地查询:CRM/客服系统接入,来电即显示归属地与运营商
> **接口**:手机归属地查询 `6-1` | **是否免费**:是(注册默认可免费调用,有使用档次限制)| **请求方式**:POST / GET | **返回格式**:JSON | **适用人群**:CRM/客服系统开发者、呼叫中心集成工程师 | **阅读时间**:约 8 分钟
## TL;DR
- 把手机归属地查询嵌进坐席系统,来电瞬间弹屏显示**省/市/运营商**,坐席不再靠"猜号码是哪里的"。
- 用 `type` 字段(1移动/2电信/3联通/4广电)做**话术分流**:不同运营商可走不同推荐口径或套餐路径。
- 这是**同步接口、实时查即可**,ShowAPI 无推送/回调能力,来电时查一次就行,不要设计"订阅推送"。
## Why:客服为什么需要在弹屏上看到归属地?
呼叫中心每天接成百上千通电话,坐席第一句话往往就是"先生/女士您好"。可如果连对方在哪个省、用哪家电信号码都不知道,开场就少了一层语境。
更实际的是**话术分流**:移动、电信、联通、广电的用户,在套餐续费、宽带办理、携号转网咨询等场景里的诉求差异很大。能在接起电话的那一刻把 `prov`/`city`/`type` 推到坐席眼前,等于给每通电话自动贴好了"前置标签"。
自己维护号段库来支撑弹屏?三网号段半年一变、广电(192 段)等新运营商不断加入,维护成本不低。手机归属地查询接口**只要求一个必填参数 `num`**,来电号码作为参数发过去,毫秒级拿回结构化结果,非常适合嵌入现有 CRM 的来电事件钩子。加上**失败时(ret_code!=0)不扣点数**,对接入方几乎没有试错成本。
## What:前置条件与接口速览
| 项目 | 内容 |
|------|------|
| 接口名称 | 手机归属地查询 |
| 接入点 | `6-1`(本接口仅 1 个接入点,同步请求-响应) |
| 接口地址 | `https://route.showapi.com/6-1?appKey={your_appKey}` |
| 请求方式 | POST 或 GET |
| 鉴权方式 | Query 参数 `appKey` |
| 必填参数 | `num`(手机号,字符串,示例 `18908711111`) |
| 返回格式 | JSON,业务数据在 `showapi_res_body` 内 |
| 弹屏关键字段 | `prov`/`city`/`name`/`type` |
| 运营商枚举 `type` | 1=移动、2=电信、3=联通、4=广电、-1=未知 |
| 计费 | 免费服务(有使用档次限制);**失败不扣点数** |
| 集成能力 | 同步查询,无订阅/无回调/无官方批量 |
| 注意 | **不支持携号转网查询** |
**架构要点:** 在 CRM 的"来电事件"触发时,由后端用号码调一次接口,再把 `showapi_res_body` 推送到前端弹屏。不要试图做"订阅推送"——ShowAPI 本接口是纯同步请求-响应,没有推送/回调能力。
## How:后端查询封装 + 弹屏推送
### 步骤 1 · 后端查询封装(Python)
下面封装一个 `lookup_caller`,返回可直接序列化给前端的字典:
```python
import requests
API_URL = "https://route.showapi.com/6-1"
APP_KEY = "YOUR_APPKEY" # 替换为你的真实 AppKey
TYPE_NAME = {1: "移动", 2: "电信", 3: "联通", 4: "广电", -1: "未知"}
def lookup_caller(phone: str):
"""根据来电号码查询归属地与运营商。失败(含 ret_code!=0)返回 None,且不扣点数。"""
if not str(phone).strip().isdigit() or len(str(phone).strip()) != 11:
return None
try:
resp = requests.get(
API_URL,
params={"appKey": APP_KEY, "num": phone},
timeout=10,
)
body = resp.json().get("showapi_res_body", {})
except requests.RequestException:
return None
if body.get("ret_code") != 0:
return None # 失败不扣点数,弹屏可显示"归属地未知"
return {
"phone": phone,
"prov": body.get("prov"),
"city": body.get("city"),
"name": body.get("name"),
"type": body.get("type"),
"typeName": TYPE_NAME.get(body.get("type"), "未知"),
"areaCode": body.get("areaCode"),
}
# 在来电事件里调用
info = lookup_caller("18908711111")
if info:
push_to_agent_screen(info) # 把 info 推送到对应坐席弹屏
else:
push_to_agent_screen({"phone": "18908711111", "prov": "未知", "city": "", "typeName": "未知"})
```
### 步骤 2 · 基于 type 做话术分流
拿到 `type` 后,可在后端直接决定弹屏上展示哪套推荐话术:
```python
def pick_script(type_code):
return {
1: "推荐口径:移动套餐/宽带续费",
2: "推荐口径:电信融合套餐",
3: "推荐口径:联通流量包",
4: "推荐口径:广电 192 新套餐",
-1: "提醒:未知运营商,先核对号码",
}.get(type_code, "通用口径")
```
### 步骤 3 · 把结果推送到前端弹屏(示意)
弹屏推送通常用 WebSocket 或 CRM 已有的消息通道。示意:
```python
import json
def push_to_agent_screen(info):
# 假设 agent_ws 是坐席对应的 WebSocket 连接
payload = {
"event": "incoming_call",
"data": info,
"script": pick_script(info.get("type")),
}
# agent_ws.send(json.dumps(payload))
print("推送到弹屏:", json.dumps(payload, ensure_ascii=False))
```
前端收到后,在来电弹屏面板渲染 `prov`/`city`/`typeName`,并高亮对应话术。整个过程是"来电 → 后端查一次 → 推送一次",**同步、实时,无需任何后台轮询或订阅**。
## 返回示例与解析
```json
{
"showapi_res_code": 0,
"showapi_res_error": "",
"showapi_res_id": "ce135f6739294c63be0c021b76b6fbff",
"showapi_res_body": {
"num": 1890871,
"prov": "云南",
"ret_code": 0,
"areaCode": "0871",
"name": "电信",
"cityCode": "530100",
"postCode": "650000",
"provCode": "530000",
"type": 2,
"city": "昆明"
}
}
```
| 字段 | 含义 | 弹屏用途 |
|------|------|----------|
| `prov` | 省 | 显示来电归属省份 |
| `city` | 市 | 显示来电归属城市 |
| `name` | 运营商名称 | 直接展示运营商 |
| `type` | 运营商枚举(1移动/2电信/3联通/4广电/-1未知) | **核心**:话术分流依据 |
| `areaCode` | 城市区号 | 辅助核对地域 |
| `ret_code` | 业务状态码,0 成功,其他失败 | 失败则不扣点数 |
> 字段的完整含义、类型与取值见 [《手机归属地返回字段全解》](https://www.showapi.com/guides/phone-attribution-response-fields-6)。
## 进阶 / 边界
- **同步、无推送**:本接口是同步请求-响应,ShowAPI 没有订阅推送/回调能力。来电时后端查一次即可,不要设计成"订阅某号码变动"。
- **失败不扣点数**:`ret_code != 0` 时不消耗额度。查不到(如 `type=-1`)时弹屏显示"归属地未知"即可,不计费。
- **不支持携号转网**:返回的 `type` 是按原号段归属,无法反映携号转网后的实际运营商。话术分流应以返回值为准,不要叠加"推测当前运营商"的逻辑。
- **免费档位限制**:客服是高频场景,每通来电查一次会累积调用量。可做短时本地缓存(同一号码短时间内重复来电不再查),详见系列缓存篇。
- **无经纬度**:接口只返回归属地文字,无法直接在地图上标点。
## FAQ
**Q1:能做到"号码一变动就主动推给我"吗?**
不能。本接口是同步请求-响应,ShowAPI 没有推送/回调/订阅能力。正确做法是:来电事件触发时,由后端用号码查一次并推送到弹屏,实时性足够,无需推送机制。
**Q2:type=-1(未知)时弹屏怎么显示?**
说明查不到运营商归属,属正常边界情况。建议弹屏显示"归属地未知",不扣点数,不影响接听,可提示坐席先核对号码。
**Q3:同一来电号码短时间内多次弹屏,会重复扣费吗?**
成功调用会计入档位,但失败(ret_code!=0)不扣点数。建议对近期查过的号码做本地缓存,避免重复查询。
**Q4:返回的 type 能告诉我用户现在用的是哪家运营商吗(携号转网)?**
不能。官方不支持携号转网查询,返回按原号段归属,无法判断实际在用运营商。
**Q5:接口返回里有经纬度吗?能做地图弹屏吗?**
没有经纬度字段。本接口只返回省/市等文字归属地,地图标点需另行配合外部地理编码服务。
**Q6:返回里的 num 是完整手机号吗?**
不是。`num` 返回的是**号段(前 7 位)**,如 `1890871`,不是完整号码,弹屏上应使用你自己的来电号码,而非这个字段。
## 相关能力 / 下一步阅读
- [《5 分钟接入手机归属地查询:从注册到第一条返回》](https://www.showapi.com/guides/phone-attribution-quickstart-6) —— 还不会发请求?从注册到第一条返回 5 分钟跑通
- [《手机归属地返回字段全解:prov/city/type/postCode 一文读懂》](https://www.showapi.com/guides/phone-attribution-response-fields-6) —— 每个字段的类型、取值与坑位
- [《type 字段全解:1移动/2电信/3联通/4广电/-1未知怎么用》](https://www.showapi.com/guides/phone-attribution-type-field-6) —— 运营商枚举在话术分流中的实战用法
> **本系列共 12 篇**:查看[手机归属地查询 · 官方指南总目录](https://www.showapi.com/guides/phone-attribution-guides-6)