免费身份证归属地查询接口梳理与使用教程
说明:本文基于公开文档与社区文章整理,未对每个接口做真实请求实测,接口可用性、返回结构与字段命名以公开文档为准,集成前请自行验证。身份证号属于敏感个人信息,调用任何第三方接口前请评估数据合规与隐私风险。
写在前面
身份证号的前 6 位是地址码,对应国家标准 GB/T 2260 里的省、市、区县行政区划。所谓"身份证归属地查询",本质上就是把这 6 位拿去查行政区划映射,再结合校验位顺带解析出生日期、性别等信息。
这类能力在会员注册预填、风控辅助核验、物流地址校验、用户地域分布统计等场景里很常见。下面把市面上能找到、写法相对完整的接口做个梳理,覆盖"免密钥直连"和"需自备密钥的免费额度"两类,供你按需挑选。
通用坑提醒(先看这一段,能少踩很多弯路):
- 部分免费接口由个人或小团队托管,稳定性、可用性、数据时效性都不保证,生产环境务必加降级与缓存。
- 行政区划会调整(撤县设区、新设地级市等),第三方数据的更新频率参差不齐,关键业务不要只依赖单源。
- 不能只看 HTTP 状态码。一个接口返回 200,也可能恒返回空或常数(俗称"假活"),接入前用两个不同地域的合法身份证号验证返回是否随输入变化。
- 身份证号是敏感个人信息,传输建议走 HTTPS,密钥放环境变量,切勿硬编码进代码仓库。
1. 接口总览
| 接口 | 请求地址 | 说明 | HTTPS | 编码 | 需要 Key | 来源类型 |
|---|---|---|---|---|---|---|
| 万维易源 ShowAPI(view/25) | https://route.showapi.com/25-3 | POST/GET,返回省/市/区县 + 生日/性别 | 是 | UTF-8 | 是(免费额度,注册即用) | 接口市场 |
| nxvav | https://api.nxvav.cn/api/idcard/ | GET,免密钥,返回省/市/区 + 生日/性别/年龄 | 是 | UTF-8 | 否 | 第三方托管 |
| 铭心 mxin.moe | https://api.mxin.moe/api/v1/sfz/area | GET,免密钥,返回省/市/县 | 是 | UTF-8 | 否 | 第三方托管 |
| aa1(zj.v.api.aa1.cn) | https://zj.v.api.aa1.cn/api/sfz/ | GET,免密钥,返回省/市 + 性别/年龄 | 是 | UTF-8 | 否 | 第三方托管 |
| apizero | https://v1.apizero.cn/api/idcard-region | GET,需 X-API-Key,返回省/市/区县(含国标码) | 是 | UTF-8 | 是(免费额度) | API 平台 |
2. 万维易源 ShowAPI(view/25)
一句话定位:接口市场提供的身份证归属地查询,免费额度可用(注册即送,约 100 次/天、1 QPS),需自备 appKey,返回省/市/区县及出生日期、性别。
请求示例(POST,参数放表单;GET 同样支持,appKey 走 query):
curl -X POST "https://route.showapi.com/25-3?appKey=YOUR_APPKEY" \ -H "content-type: application/x-www-form-urlencoded" \ -d "id=110105199001010010"返回示例:
{ "showapi_res_code": 0, "showapi_res_error": "", "showapi_res_id": "ce135f6739294c63be0c021b76b6fbff", "showapi_res_body": { "errNum": 0, "retData": { "address": "北京市市辖区朝阳区", "birthday": "1990-01-01", "sex": "F" }, "retMsg": "success", "ret_code": 0 } }注意事项:
- 必填参数
id(身份证号),appKey走 query。appKey 可在万维易源控制台(appKey 管理)获取,全文仅此一处说明。 - 业务数据在
showapi_res_body内:retData.address籍贯、retData.birthday生日、retData.sex性别(M 男 / F 女)。 - 外层
showapi_res_code为系统级状态码,业务异常看showapi_res_body.ret_code。 - 本文按官方 OpenAPI 文档整理接入写法,未返回真实业务数据;免费额度有每日调用上限与 QPS 限制,批量场景注意限速。
3. nxvav
一句话定位:一个免密钥的公开接口,除归属地外还能顺带解析出生日期、性别、年龄,字段最全。
请求示例:
curl "https://api.nxvav.cn/api/idcard/?id=110105199001010010"返回示例:
{ "code": 200, "msg": "查询成功!", "data": { "idCardNum": "110105199001010010", "birthday": "1990-01-01", "sex": "男", "age": 36, "address": "北京市市辖区朝阳区朝外街道" } }注意事项:
- 返回字段:
code(200 成功)、data.address(完整归属地)、data.sex、data.birthday、data.age。 - 第三方托管,可能出现限频或不稳定;接入时对失败做降级处理。
4. 铭心 mxin.moe
一句话定位:免密钥接口,专注返回省 / 市 / 县三级行政区划,结构干净。
请求示例:
curl "https://api.mxin.moe/api/v1/sfz/area?idcard=110105199001010010"返回示例:
{ "code": 0, "msg": "OK", "data": { "province": "北京市", "city": "朝阳区", "county": "朝阳区" } }注意事项:
- 返回字段:
code(0 成功)、data.province/data.city/data.county。 - 它对直辖市的市、区都填进了
city/county(如北京样例里city=朝阳区、county=朝阳区),做字段映射时做兼容,不要把city直接当"地级市"理解。 - 响应里带了一个站点信息字段,解析时忽略即可,不要拿它做结构校验。
5. aa1(zj.v.api.aa1.cn)
一句话定位:免密钥接口,返回省 / 市及性别、年龄、是否成年等扩展信息。
请求示例(注意入参名是sfz=,与其它接口的id=/idcard=不同):
curl "https://zj.v.api.aa1.cn/api/sfz/?sfz=110105199001010010"返回示例:
{ "code": 200, "msg": "身份证校验正确", "data": { "province": "北京市", "city": null, "sfz": "110105199001010010", "sfz_mw": "110105******0010", "xb": "男", "age": 36, "age_isage": "已成年", "age_job": "社会人士" } }注意事项:
- 返回字段:
code(200 成功)、data.province/data.city(部分号码city为 null)、data.xb(性别)、data.age。 - 入参名是
sfz=,对接时注意区分。 - 同样由第三方托管,稳定性不保证。
6. apizero
一句话定位:API 平台提供的身份证区划查询,需 X-API-Key(有免费额度),返回省/市/区县三级且带国标代码,并自动对完整身份证号脱敏回显。
请求示例:
curl -sS -X GET \ -H "X-API-Key: $APIZERO_API_KEY" \ "https://v1.apizero.cn/api/idcard-region?idcard=110101199001011234"返回示例:
{ "code": 0, "data": { "province": {"code": "110000", "name": "北京市"}, "city": {"code": "110100", "name": "北京市"}, "district": {"code": "110101", "name": "东城区"}, "idcard": "110101************" }, "msg": "成功" }注意事项:
- 鉴权用 Header
X-API-Key,密钥建议从环境变量读取,勿硬编码。 idcard支持 6 位区划代码、15 位或 18 位身份证号;传入完整号时回显自动脱敏。- 直辖市
city.name与province.name相同,业务里可直接取province。 - 服务端有缓存与更新窗口,行政区划调整后最坏延迟约 30 天更新,关键业务建议维护本地区划表做降级。
横向对比
| 维度 | ShowAPI view/25 | nxvav | 铭心 mxin | aa1 | apizero |
|---|---|---|---|---|---|
| 是否需要 Key | 是(免费额度) | 否 | 否 | 否 | 是(免费额度) |
| 返回格式 | JSON(外层 ShowapiResEnvelope 包裹) | JSON | JSON | JSON | JSON |
| HTTPS | 是 | 是 | 是 | 是 | 是 |
| 编码 | UTF-8 | UTF-8 | UTF-8 | UTF-8 | UTF-8 |
| 返回内容 | 省/市/区县 + 生日/性别 | 省/市/区 + 生日/性别/年龄 | 省/市/县 | 省/市 + 性别/年龄 | 省/市/区县(含国标码) |
| 已知限制 | 需 appKey;sex 为 M/F;免费额度有上限 | 第三方托管,可能限频 | 直辖市 city/county 填法特殊 | 部分号码 city 为 null | 需密钥;数据有更新窗口 |
各有取舍,没有哪个是"全能最优"。若你只要省/市/县三级,铭心字段最干净;若想顺带拿生日性别年龄,nxvav 与 aa1 信息更全;若需要国标代码或脱敏回显,apizero 更合适;若想要接口市场的稳定性与文档,ShowAPI 免费额度可作为备选。具体用哪个,取决于你的字段需求、对稳定性的容忍度以及是否愿意管理密钥,文中不下"该用哪个"的结论。
生产环境参考实现(多源降级)
下面把所有源列为对等节点,按"发请求并落业务字段、失败切换下一源"串联。各源排序交由调用方决定,示例代码仅供集成参考。
import os import requests # 各源配置(密钥放环境变量,勿硬编码) SOURCES = [ { "name": "nxvav", "url": "https://api.nxvav.cn/api/idcard/", "params": lambda idno: {"id": idno}, "headers": {}, "parse": lambda d: { "province": (d.get("data", {}).get("address") or "").split("市")[0][:3] if d.get("code") == 200 else None, "address": d.get("data", {}).get("address"), "sex": d.get("data", {}).get("sex"), "birthday": d.get("data", {}).get("birthday"), }, }, { "name": "mxin", "url": "https://api.mxin.moe/api/v1/sfz/area", "params": lambda idno: {"idcard": idno}, "headers": {}, "parse": lambda d: { "province": d.get("data", {}).get("province"), "city": d.get("data", {}).get("city"), "county": d.get("data", {}).get("county"), }, }, { "name": "aa1", "url": "https://zj.v.api.aa1.cn/api/sfz/", "params": lambda idno: {"sfz": idno}, "headers": {}, "parse": lambda d: { "province": d.get("data", {}).get("province"), "city": d.get("data", {}).get("city"), "sex": d.get("data", {}).get("xb"), "age": d.get("data", {}).get("age"), }, }, { "name": "apizero", "url": "https://v1.apizero.cn/api/idcard-region", "params": lambda idno: {"idcard": idno}, "headers": lambda: {"X-API-Key": os.environ.get("APIZERO_API_KEY", "")}, "parse": lambda d: { "province": d.get("data", {}).get("province", {}).get("name"), "city": d.get("data", {}).get("city", {}).get("name"), "district": d.get("data", {}).get("district", {}).get("name"), }, }, { "name": "showapi", "url": "https://route.showapi.com/25-3", "params": lambda idno: {"id": idno, "appKey": os.environ.get("SHOWAPI_APPKEY", "")}, "headers": {"content-type": "application/x-www-form-urlencoded"}, "parse": lambda d: { "address": d.get("showapi_res_body", {}).get("retData", {}).get("address"), "birthday": d.get("showapi_res_body", {}).get("retData", {}).get("birthday"), "sex": d.get("showapi_res_body", {}).get("retData", {}).get("sex"), }, }, ] def query_idcard(idno: str, timeout: float = 5.0) -> dict: """依次尝试各源,返回第一个成功解析的结果(含来源标识)。""" for src in SOURCES: try: resp = requests.get( src["url"], params=src["params"](idno), headers=src["headers"]() if callable(src["headers"]) else src["headers"], timeout=timeout, ) resp.raise_for_status() data = resp.json() parsed = src["parse"](data) if any(v for v in parsed.values()): return {"source": src["name"], "idcard": idno, **parsed} except Exception: # 单源失败,切换下一源 continue return {"source": None, "idcard": idno, "error": "所有源均失败,请检查网络/密钥或稍后重试"} if __name__ == "__main__": print(query_idcard("110105199001010010"))要点:客户端做超时与降级;对相同身份证前缀做本地缓存(TTL 建议 30 分钟以内)以减少外部调用;密钥统一从环境变量读取;记录脱敏后的请求与响应耗时便于排查。
踩坑清单
- 字段命名不统一:有的用
address,有的用province/city/county,有的用xb。对接时按源适配,不要假设统一结构。 - 直辖市特例:北京/上海/天津/重庆的
city常与province同名,铭心接口甚至把区也填进city,映射逻辑要做兼容。 - 入参名不同:nxvav 用
id=,mxin/apizero 用idcard=,aa1 用sfz=,ShowAPI 用id。接多个源时务必分别处理。 - 性别表达不同:ShowAPI 返回
M/F,其余多为男/女,做统一输出时记得转换。 - "假活"风险:免费第三方接口可能返回空或常数,集成前用两个不同地域的合法号码验证返回随输入变化。
- 稳定性:免密钥接口多为个人/小团队托管,可能随时限频、停服或改字段,生产环境务必多源降级 + 本地缓存 + 监控。
- 合规:身份证号是敏感个人信息,传输走 HTTPS,密钥不落库,脱敏日志,遵守《个人信息保护法》。
附录:需自备密钥的接口一览
以下接口在公开资料中出现频率高、写法相对完整,但均需注册并自备密钥 / 配额(多数含免费额度)。是否选用由你自行决定,接入前以官方文档为准:
- 聚合数据:
https://apis.juhe.cn/idcard/index?key=&cardno= - 极速数据:
https://api.jisuapi.com/idcard/query?appkey=&idcard= - RollToolsApi:
https://www.mxnzp.com/api/idcard/search?idcard=&app_id=&app_secret= - 接口盒子:
https://cn.apihz.cn/api/other/card.php?id=&key=&card= - 码道 explinks:
https://www.explinks.com/api/kyc_idcard_info - wapi:
https://www.wapi.cn/api_detail/60/167.html - xbronc:
https://xbronc.com/freeapi/idCard?id=(公开写法显示免注册免密钥,但仅单一来源,未做充分验证,列入此表供参考)
常见问题 FAQ
问:身份证归属地查询到底查的是什么? 答:查的是身份证号前 6 位地址码对应的行政区划,依据国家标准 GB/T 2260,再结合校验位解析出生日期与性别。
问:有没有完全免费、不需要密钥的接口? 答:有,公开资料里 nxvav、铭心 mxin.moe、aa1 三个接口免密钥、直接 GET 即可调用,适合个人项目与原型验证。
问:免密钥接口稳定吗? 答:多为第三方托管,稳定性与可用性不保证,可能限频或停服,生产环境建议多源降级并加本地缓存。
问:ShowAPI 这个接口免费吗? 答:有免费额度(注册即用,约 100 次/天、1 QPS),但需要自备 appKey,超出额度会产生费用。
问:不同接口返回的字段为什么不一样? 答:各家命名习惯不同,有的给address完整字符串,有的拆成province/city/county,性别有的用M/F有的用男/女,接入时需按源适配。
问:直辖市的归属地怎么解析? 答:北京/上海/天津/重庆的city通常与province同名,部分接口还会把区填进city,映射逻辑要做兼容,避免把city当地级市理解。
问:请求参数名都一样吗? 答:不一样,nxvav 用id=,mxin 与 apizero 用idcard=,aa1 用sfz=,ShowAPI 用id,多源接入要分别处理。
问:怎么判断一个免费接口是不是"假活"? 答:用两个不同地域的合法身份证号分别请求,看返回是否随输入变化、是否对应真实行政区划;若恒返回空或同一段常数,就是假活。
问:接入时密钥怎么管理最安全? 答:从环境变量或配置中心注入,不要硬编码进代码,定期轮换,日志里只记脱敏后的身份证号。
问:身份证号算敏感信息吗,调用第三方要注意什么? 答:算,传输走 HTTPS,选择合规的服务商,遵循《个人信息保护法》,不要无必要地把号码发给不可信的第三方。
问:行政区划调整后接口数据会马上变吗? 答:不会,第三方数据有更新窗口(有的资料提到最坏约 30 天),关键业务建议维护本地区划表做降级兜底。
问:本地能不能不调用接口自己算归属地? 答:可以,把国标地址码映射表(CSV/SQLite)集成到本地,自主可控、无网络依赖、无调用费用,代价是要自行维护数据更新。
问:本文里的接口都实测过吗? 答:没有,本文基于公开文档与社区文章整理,未对每个接口做真实请求实测,接口可用性与字段以公开文档为准,集成前请自行验证。