手机归属地查询接口怎么用?从 AppKey 到第一条真实返回的完整路径

约 15 分钟 入门手机号码归属地查询API快速接入Python示例cURL
# 手机归属地查询接口怎么用?从 AppKey 到第一条真实返回的完整路径 接口:手机归属地查询(apiCode=6,接入点 6-1)|是否免费:是,注册后默认可调用,设使用档次限制|请求方式:POST / GET|返回格式:JSON|适用人群:新注册用户、第一次接第三方接口的开发者|阅读时间:约 6 分钟|最后实测核对:2026-09-18 ## 核心要点 - 手机归属地查询接口只要求一个必填参数 `num`,把手机号按 Query 参数传进去,省、市、运营商、号段、区号、邮编一次性返回。 - 业务数据在 `showapi_res_body` 里,外层 `showapi_res_code` 是网关级状态码,两层要分开判。 - 实测确认:失败(`ret_code != 0`)时 `showapi_fee_num` 为 0,不消耗调用额度。 ## 为什么值得先跑通这一条 手上有号码,想知道它属于哪个省、哪个市、哪家运营商,这件事自己维护一张号段表也能做。问题是号段表一直在动,新号段按批放出来就得跟着更新,维护的人得盯数据。这个接口把这件事换成一次 HTTP 调用,号段归属由官方侧维护。 很多业务只是想在注册页顺手显示一行「北京 · 移动」,或者给订单加一个地域标签。这类需求不值得为它建一套数据表和一个更新流程。 接口本身很简单:一个必填参数,一个 POST 或 GET 请求,返回一层扁平 JSON。这篇的目标是让你在 5 分钟内拿到第一条真实返回,后面几篇再展开字段、错误码和场景。 ## 接口速览 | 项目 | 内容 | |------|------| | 接口名称 | 手机号码归属地查询 | | apiCode | 6 | | 接入点 | 6-1,全接口仅此一个接入点,同步请求-响应 | | 接口地址 | `https://route.showapi.com/6-1` | | 请求方式 | POST 或 GET | | 鉴权方式 | Query 参数 `appKey` | | 必填参数 | `num`(String,要查询的手机号码) | | 返回格式 | JSON,业务数据封装在 `showapi_res_body` | | 超时设置 | 官方 OpenAPI 标注 `x-read-timeout: 10`、`x-connect-timeout: 10`,即连接与读取各 10 秒 | | 计费 | 免费服务,注册后默认可调用,设使用档次限制;失败不扣点数 | | 数据更新 | 每半年同步一次新增号段归属信息,由官方维护 | | 集成能力 | MCP 服务、OpenAPI 3.0(YAML / JSON) | ## 三个步骤拿到第一条返回 ### 第 1 步:注册并拿到 AppKey 在易源官网注册账号。手机归属地查询属于免费接口,注册后默认可调用,不需要先买资源包。注册完成后进入 AppKey 管理页复制 AppKey,后面代码里的 `YOUR_APPKEY` 换成它。 ### 第 2 步:发一次请求 下面三种写法都带 10 秒超时和 `ret_code` 判断,替换占位符就能跑。 Python(requests): ```python import requests API_URL = "https://route.showapi.com/6-1" APP_KEY = "YOUR_APPKEY" # 替换成你的真实 AppKey PHONE = "13800138000" # 要查询的手机号 resp = requests.get( API_URL, params={"appKey": APP_KEY, "num": PHONE}, timeout=10, # 对齐官方 x-read-timeout ) data = resp.json() # 网关级状态码先过一遍 if data.get("showapi_res_code") != 0: raise RuntimeError(f"网关层报错:{data.get('showapi_res_error')}") body = data.get("showapi_res_body", {}) if body.get("ret_code") == 0: print("省:", body.get("prov")) print("市:", body.get("city")) print("运营商:", body.get("name")) print("号段:", body.get("num")) print("区号:", body.get("areaCode")) print("邮编:", body.get("postCode")) else: # 失败时 showapi_fee_num 为 0,不消耗额度 print("查询失败,ret_code =", body.get("ret_code"), "|", body.get("remark")) ``` cURL: ```bash curl -X POST "https://route.showapi.com/6-1?appKey=YOUR_APPKEY" \ -H "content-type: application/x-www-form-urlencoded" \ --data-urlencode "num=13800138000" \ --max-time 10 ``` Node.js(Node 18+ 原生 fetch): ```javascript const APP_KEY = "YOUR_APPKEY"; // 替换成你的真实 AppKey const PHONE = "13800138000"; const resp = await fetch( `https://route.showapi.com/6-1?appKey=${APP_KEY}`, { method: "POST", headers: { "content-type": "application/x-www-form-urlencoded" }, body: new URLSearchParams({ num: PHONE }), signal: AbortSignal.timeout(10000), // 对齐 x-read-timeout } ); const data = await resp.json(); if (data.showapi_res_code !== 0) throw new Error(data.showapi_res_error); const body = data.showapi_res_body || {}; if (body.ret_code === 0) { console.log(`${body.prov} ${body.city} | ${body.name} | 区号 ${body.areaCode}`); } else { console.log("查询失败,ret_code =", body.ret_code, "|", body.remark); } ``` ### 第 3 步:读懂两层状态码 返回最外层是网关字段,`showapi_res_code`、`showapi_res_error`、`showapi_res_id`、`showapi_fee_num`。业务数据全在 `showapi_res_body` 里。判断查询成不成功看 `ret_code`,不要看 `showapi_res_code`。 `showapi_res_code = 0` 并且 `showapi_res_body.ret_code = 0`,才是一次成功的查询。 ## 返回示例与解析 下面这条是 2026-09-18 实测的真实返回(`num=13800138000`): ```json { "showapi_res_error": "", "showapi_res_id": "6aaca381fb638c2f6956a193", "showapi_res_code": 0, "showapi_fee_num": 1, "showapi_res_body": { "provCode": "110000", "areaCode": "010", "ret_code": 0, "remark": "", "postCode": "100000", "num": 1380013, "cityCode": "110100", "name": "移动全球通卡", "type": 1, "city": "北京", "prov": "北京" } } ``` | 字段 | 类型 | 含义 | 本例值 | |------|------|------|--------| | `prov` | String | 省 | 北京 | | `city` | String | 市 | 北京 | | `name` | String | 运营商 | 移动全球通卡 | | `num` | Number | 号段,前 7 位 | 1380013 | | `type` | Number | 运营商枚举,1移动/2电信/3联通/4广电/-1未知 | 1 | | `areaCode` | String | 城市区号 | 010 | | `postCode` | String | 邮政编码 | 100000 | | `provCode` | String | 省别编码,本省身份证前几位 | 110000 | | `cityCode` | String | 城市编码,本城市身份证前几位 | 110100 | | `ret_code` | Number | 业务状态码,0 成功,其他失败 | 0 | | `remark` | String | 补充说明,失败时给出原因 | 空 | 这里有两处只有实测才会看到的信息。`postCode` 和 `remark` 不在官方 OpenAPI 的参数表里,参数表只登记了 9 个业务字段,但真实返回里确实带着这两个字段,`remark` 在失败时用来放原因文字。另外 `provCode`、`cityCode` 在 OpenAPI 里标的是 Number,实测返回的是字符串 `"110000"`。区号和邮编带有前导零(`"010"`、`"100000"` 这类),按字符串存才不会丢位。 字段逐个拆解在这篇:[手机归属地查询返回字段全解](https://www.showapi.com/guides/phone-attribution-response-fields-6)。 ## 计费与调用方式 手机归属地查询是免费接口,注册后默认可调用,设使用档次限制。成功返回时 `showapi_fee_num` 为 1,失败时为 0。缺 `num` 参数时 `showapi_res_code` 返回 -1、`showapi_res_error` 为 `must input num field`,也不计费。 免费档位从 L0 起算,每日调用量与并发上限见[免费接口与档位说明](https://www.showapi.com/free-api)。需要更高档位时用平台积分兑换。 ## FAQ **Q1:接口要传 AppKey 吗?传在哪里?** 要。AppKey 走 Query 参数,形如 `?appKey=YOUR_APPKEY`,不放在请求头里。 **Q2:POST 和 GET 有区别吗?** 没有区别,两种都支持,返回一致。参数多或号码本身可能带特殊字符时用 POST 更省事。 **Q3:`showapi_res_code` 和 `ret_code` 看哪个?** 判断业务成败看 `showapi_res_body` 里的 `ret_code`。外层的 `showapi_res_code` 反映网关层状态,比如缺参数、鉴权失败这类问题。 **Q4:返回的 `num` 是完整手机号吗?** 不是。`num` 是号段,只有前 7 位,实测 `13800138000` 返回的 `num` 是 `1380013`。完整号码不会回传。 **Q5:查询失败会扣次数吗?** 不会。失败时 `showapi_fee_num` 为 0,文档口径是失败时不扣点数。 **Q6:调用有超时限制吗?** 有。官方 OpenAPI 标注连接超时和读取超时都是 10 秒,客户端把超时设成 10 秒即可对齐。 **Q7:接口返回经纬度吗?** 不返回。要在地图上标点,需要拿 `prov`、`city` 文字再走一次地理编码服务。 **Q8:支持携号转网查询吗?** 不支持。号码办理携号转网后,返回的运营商仍按原号段归属,不会跟着变。 ## 下一步阅读 - [手机归属地查询返回字段全解:11 个字段的类型、取值与粒度](https://www.showapi.com/guides/phone-attribution-response-fields-6) —— 每个字段能拿来干什么 - [手机归属地查询返回 -2、-3、-4 是什么意思?错误码逐条对照与排查](https://www.showapi.com/guides/phone-attribution-error-codes-6) —— 失败时先看这张表 - [手机归属地查询 type 字段全解:1移动 2电信 3联通 4广电 -1未知怎么用](https://www.showapi.com/guides/phone-attribution-type-field-6) —— 运营商分支逻辑怎么写 - [手机归属地查询 MCP 服务:在 AI 客户端里直接问号码归属地](https://www.showapi.com/guides/phone-attribution-mcp-6) —— 不写代码也能查 - **本系列共 12 篇**:查看[手机归属地查询指南总目录](https://www.showapi.com/guides/phone-attribution-guides-6)
加载中...