深圳二手房成交数据 API · 客户版接口文档(v1)
- 契约版本:
1.0 - 本文说明接口怎么调、字段什么意思、怎么扣费、报错怎么办。
- 文中所有价格数字都是占位值,正式价格以
GET /v1/pricing的返回为准。 - 全文用
$BASE表示服务地址(我们开通时单独提供给你的那串地址),示例命令里不要照抄。 - 所有日期、时间均为北京时间(UTC+8)。
1 这是什么
这是一个用 HTTPS 调用的深圳二手房成交数据接口:你用自己的密钥请求,按返回的条数扣积分(也可以买月度套餐,套餐内按条数算额度),能查到逐条成交明细、区·月统计、小区·年统计,以及每天变化的增量;数据每天更新一次,字段名、含义、单位在本文和随数据下发的契约里完全一致,程序读和做表格用的是同一套字段。数据范围:成交明细为滚动近 24 个月(当期约 5.7 万条,覆盖约 4,270 个小区),两张统计表为全部历史(最早 2010-01,约 14.5 万条成交参与统计)。
2 三分钟上手
第 1 步:拿到密钥
密钥形如 pcfh_ 加 32 位字符,只显示一次,请立刻存进密码管理器或私密文件(文件权限建议 chmod 600)。
- 密钥只能放在请求头:
Authorization: Bearer <你的密钥>。 - 不接受把密钥写在网址参数里(会被拒绝)。
- 不要把密钥贴进聊天、配置正文、命令行参数或代码仓库。
本文示例统一用占位符 pcfh_XXXXXXXX,请替换成你自己的密钥。
第 2 步:用 curl 查一个小区
export PCFH_API_KEY='pcfh_XXXXXXXX' export BASE='你的服务地址' curl -s -H "Authorization: Bearer $PCFH_API_KEY" \ "$BASE/v1/deals?community=示例花园&limit=5"
返回是一段 JSON:data 里一行就是一笔成交。
第 3 步:把结果整理成表格
data 里每行挑你需要的列就是一张表,例如:
| community_name | sign_date | area_sqm | total_price_yuan | unit_price_yuan |
|---|---|---|---|---|
| 示例花园 | 2026-09-18 | 89.50 | 5600000 | 62570 |
| 示例花园 | 2026-08-02 | 76.20 | 4980000 | 65354 |
条数多的时候不要手抄,用第 9 节的命令行直接导出 CSV(UTF-8 带 BOM,Excel 双击不乱码):
pcfh deals --community 示例花园 --max-rows 200 --format csv --output ./deals.csv
3 接口一览
| 方法 | 路径 | 作用 | 是否收费 |
|---|---|---|---|
| GET | /v1/status | 服务状态、当前数据版本、数据截至日期 | 不收费 |
| GET | /v1/deals | 成交明细查询(支持筛选、翻页) | 按返回条数 |
| GET | /v1/deals/{deal_id} | 按编号取一条成交 | 1 条 |
| GET | /v1/communities?q= | 小区名模糊搜索,最多 20 个结果 | 按命中条数(当前价格为 0) |
| GET | /v1/stats/district-monthly | 区·月统计 | 按返回条数 |
| GET | /v1/stats/community-yearly?community= | 小区·年统计(必须指定小区) | 按返回条数 |
| GET | /v1/delta?since= | 增量操作流(需开通增量权限) | 按返回操作条数 |
| GET | /v1/releases/current | 当前版本清单 | 不收费 |
| GET | /v1/releases/current/files/{name} | 下载清单里列出的整份文件(需开通文件权限) | 按文件固定积分 |
| GET | /v1/usage | 今日/本月用量、余额、套餐剩余额度、每日上限 | 不收费 |
| GET | /v1/pricing | 当前价格与限额 | 不收费 |
| PUT | /v1/account/limits | 设置你自己的每日消费上限 | 不收费 |
通用约定:
- 全部返回 JSON;响应超过 1 KB 时启用 gzip 压缩。
- 成功返回:
{"release_id", "data": [...], "next_cursor", "truncated", "charged_credits", "balance_credits"};订阅账户另有套餐额度字段。 - 出错返回:
{"error": {"code": "...", "message": "中文说明"}},错误码见第 8 节。 - 未知参数会直接返回 400,不会被忽略。
4 查询成交明细 /v1/deals
4.1 必填条件(二选一)
community:小区名(精确匹配,按记录原名);或district+month_from+month_to:行政区 + 起止月份(YYYY-MM),跨度不超过 3 个自然月。
两个都没给、或区县条件给不全,返回 400 filter_required(见第 8 节)。
4.2 可选筛选
| 参数 | 含义 |
|---|---|
sign_date_from / sign_date_to | 成交日期区间 YYYY-MM-DD |
bedrooms | 卧室数(几室) |
min_area / max_area | 面积区间(平方米) |
property_type | 普通住宅 / 公寓 / 商业办公 / 别墅 |
exclude_dup_suspect | true 时剔除疑似重复的记录 |
limit | 每页条数,1–50,默认 50;超过 50 返回 400 |
排序固定为:成交日期倒序,同一天按 deal_id 升序。
4.3 翻页与上限
- 翻页:上一页的返回里有
next_cursor;下一页的请求里用参数 **cursor** 带上它的值(请求参数叫cursor,返回字段叫next_cursor,名字不一样)。没有 offset / 页码。例如:GET /v1/deals?community=某小区&limit=50&cursor=<上一页返回的 next_cursor>。 next_cursor是签名过的密文串,不要自己拼、不要改,改过会返回 400invalid_cursor。- 单次查询最多返回 1,000 条。到顶后
next_cursor为null、truncated为true;要更多数据请把条件拆窄(例如分月份、分小区查)。 - 数据版本在你翻页期间发生切换时,继续翻页会返回 409
release_changed,请从第一页重新查(已扣的积分不退,但可以据此缩小条件)。
4.4 请求例子
curl -s -H "Authorization: Bearer $PCFH_API_KEY" \ "$BASE/v1/deals?district=福田区&month_from=2026-08&month_to=2026-10&bedrooms=3&limit=1"
4.5 返回例子(虚构数据)
{
"release_id": "20261019-1",
"data": [
{
"deal_id": "3f9c2a7d81b04e65",
"district": "福田区",
"community_name": "示例花园",
"sign_date": "2026-09-18",
"area_sqm": 89.5,
"total_price_yuan": 5600000,
"unit_price_yuan": 62570,
"bedrooms": 3,
"floor_level": "mid",
"total_floors": 32,
"orientation": "南+北",
"property_type": "普通住宅",
"property_type_basis": "record",
"is_foreclosure": false,
"record_count": 2,
"dup_suspect": false,
"first_published_date": "2026-10-20",
"last_changed_date": "2026-10-20"
}
],
"next_cursor": "eyJ2IjoxLCJyIjoiMjAyNjEwMTktMSJ9.7f3a...",
"truncated": false,
"charged_credits": 1,
"balance_credits": 999
}
4.6 字段含义
| 字段 | 类型 | 可能为空 | 含义 |
|---|---|---|---|
deal_id | 字符串,16 位 | 否 | 成交记录编号,永久不变。只在每天增量同步对账时用,做表格可以忽略 |
district | 字符串 | 是 | 行政区:福田区、罗湖区、南山区、盐田区、宝安区、龙岗区、龙华区、坪山区、光明区、大鹏新区 |
community_name | 字符串 | 否 | 小区名称,按记录原名。同一小区可能有不同写法,v1 不做名称统一 |
sign_date | 日期 YYYY-MM-DD | 否 | 成交日期 |
area_sqm | 数字,2 位小数 | 否 | 面积(平方米),一般为建筑面积 |
total_price_yuan | 整数 | 否 | 成交总价(元),不等同于网签价 |
unit_price_yuan | 整数 | 否 | 成交单价(元/平方米) |
bedrooms | 整数 1–9 | 是 | 卧室数 |
floor_level | low / mid / high | 是 | 楼层高低(低/中/高),不提供具体楼层 |
total_floors | 整数 | 是 | 所在楼栋总层数 |
orientation | 字符串 | 是 | 朝向,由东、南、西、北、东南、西南、东北、西北组成,多个用 + 连接,如 南+北 |
property_type | 枚举 | 是 | 物业类型:普通住宅 / 公寓 / 商业办公 / 别墅 |
property_type_basis | 枚举 | 是 | 类型依据:record(本条记录写明)/ community_inferred(按同小区推断,后续可能撤回) |
is_foreclosure | 布尔 | 否 | 是否法拍成交(法拍价与普通成交差异大,统计表里单独计数) |
record_count | 整数 ≥ 1 | 否 | 印证次数:同一笔成交被几个不同渠道记录过(同一渠道的重复记录只算一次)。数字越大,被印证越多;可能随新记录到达而变大,也可能因为合并重复记录而一次性变小,这不代表数据变少 |
dup_suspect | 布尔 | 否 | 疑似重复:存在另一条高度相似但未合并的记录,是否剔除由你决定 |
first_published_date | 日期 | 否 | 首次对外发布日期。**找「新到的记录」用这个字段,不要用 sign_date** |
last_changed_date | 日期 | 否 | 最近一次字段变化日期 |
遇到不认识的新字段请忽略、不要报错:次版本升级只会加字段,不删字段、不改名、不改含义和单位。
5 统计表
5.1 区·月统计 GET /v1/stats/district-monthly
参数:district(可选,不传返回全部区含 全市)、month_from / month_to(YYYY-MM,可选)、limit(1–50,默认 50)、cursor(翻页,值取自上一页返回的 next_cursor)。排序:月份倒序。
5.2 小区·年统计 GET /v1/stats/community-yearly?community=
参数:community(必填,精确小区名)、limit、cursor(翻页,值取自上一页返回的 next_cursor)。排序:年份倒序。
5.3 统计表字段
| 字段 | 含义 |
|---|---|
month / year | 区月表为月份 YYYY-MM;小区年表为年份 YYYY |
district | 行政区,或 全市(小区年表可能为空) |
community_name | 小区名称(仅小区年表) |
deal_count | 普通成交条数(不含法拍、不含质量不合格、完全重复已合并) |
foreclosure_count | 法拍成交条数 |
community_count | 当月有普通成交的小区数(仅区月表) |
median_unit_price_yuan / avg_unit_price_yuan | 单价中位数 / 平均数(元/平方米) |
p25_unit_price_yuan / p75_unit_price_yuan | 单价第 25 / 第 75 百分位(仅区月表) |
median_total_price_yuan / median_area_sqm | 总价中位数 / 面积中位数 |
sample_sufficient | deal_count ≥ 5 时为 true;**为 false 时上面所有价格、面积字段一律为空** |
is_provisional | 数字还会因补录明显变化:区月表最近 3 个自然月为 true,小区年表当年为 true |
统计表不提供最高价、最低价(容易反推出单笔成交)。样本少于 5 条时价格字段为空是设计如此,不是出错。
6 每天同步(增量接口 GET /v1/delta)
给「每天自己存表」的客户:不用每天拉全量,拉增量即可。
参数 since:你手上那一期的版本号(release_id,形如 20261019-1),返回该期之后到当前版本的全部操作。每页最多 500 个操作,把返回的 next_cursor 作为请求参数 cursor 继续翻;增量流不受「单次 1,000 条」上限限制,保证完整。
每行一个操作:
op | 什么时候出现 | 附带内容 |
|---|---|---|
add | 新出现的成交 | record:完整一行 |
change | 已有成交的任一字段变化 | changed_fields:变化的字段名列表;record:变化后的完整一行 |
remove | 该成交不再提供 | reason:aged_out(超出 24 个月窗口,每月 1 号集中出现)/ withdrawn(撤回或复核不合格)/ merged(确认与另一条是同一笔,附 merged_into = 保留的 deal_id) |
{"op":"change","deal_id":"3f9c2a7d81b04e65","changed_fields":["property_type","property_type_basis"],"record":{"...":"完整一行"}}
{"op":"remove","deal_id":"9a01c3e5d7b2f468","reason":"aged_out"}
使用规则:
- 按版本号顺序逐期应用,不要跳期、不要乱序。
- 漏了一期,或本期
base_release_id和你手上的版本对不上,就重新拉全量,不要硬拼。 since太旧(已不在我们保留的版本链里)或无法识别,返回 410full_refresh_required,同样是重新拉全量。deal_id只在这里有用:用来判断哪一条新增、哪一条变了、哪一条删了。按小区查询和导出表格时可以完全忽略它(表格导出默认不带这一列)。
7 计费规则
7.1 怎么扣
- 按成功返回的条数扣积分,不按请求次数。
- 报错不扣费(4xx / 5xx 一律 0),查不到数据也不扣费(返回 0 条记 0 积分)。
- 扣费和记账在返回数据之前完成,返回里的
charged_credits是本次实扣、balance_credits是扣后余额。
7.2 当前价格(**全部为占位值,以 /v1/pricing 返回为准**)
| 项目 | 占位值 |
|---|---|
| 成交明细,每条 | 1 积分 |
| 统计表(区月、小区年),每条 | 1 积分 |
| 小区搜索,每条命中 | 0 积分 |
| 增量,每个操作 | 1 积分 |
| 整份文件下载,每个文件 | 1000 积分 |
| 试用账户每天条数上限 | 200 条 |
| 每密钥限速 | 每秒 5 次请求 |
| 月度套餐(占位档「starter」) | 每月 10000 条额度,30 天 |
正式价格调整时以 /v1/pricing 为准,本文数字只作示意;/v1/pricing 不收费,程序可以每次先查再算预算。
7.3 不重复扣费:Idempotency-Key
可选请求头。同一个账户 + 同一密钥 + 完全相同的请求,24 小时内带同一个 Idempotency-Key,服务端直接重放上次的结果,不再扣费。网络超时、断线重试时请务必带上,避免为同一页付两次钱。
同一个 Idempotency-Key 配了不同的请求,返回 422 idempotency_conflict,请换一个 Key。
7.4 单次上限:X-Max-Credits
可选请求头,整数 ≥ 0。写 30 就表示「这一次最多只允许扣 30 积分」:如果本次要扣的比 30 多,返回 402 max_credits_exceeded,一条数据都不给、一分钱都不扣。适合交给程序或智能助手自动跑时兜底。
7.5 每日消费上限
用 PUT /v1/account/limits 自己设,随时可改:
curl -s -X PUT -H "Authorization: Bearer $PCFH_API_KEY" \
-H "Content-Type: application/json" \
-d '{"daily_cap_credits": 500}' \
"$BASE/v1/account/limits"
500= 每天最多扣 500 积分;0= 今天一律不许扣费;null= 不设上限。- 今天已扣 + 本次要扣 超过上限 → 429
daily_cap_reached,本次不扣费、不返回数据。
7.6 账户类型
- 试用(trial):没有余额,每个自然日最多
200条(占位值),不能查增量、不能下载整份文件;超了返回trial_limit_reached。 - 积分(credits):按实际扣分从余额里减,余额不够当页就返回 402
insufficient_balance(不返回数据、不扣费)。 - 订阅(subscription):每月有固定条数额度(占位档 10000 条/30 天),月初重置;额度用完后自动转扣余额,余额也没有则返回 402
insufficient_balance。
8 错误码表
出错时返回 {"error": {"code": "...", "message": "中文说明"}},请按 code 判断,不要按中文文字判断。
| 错误码 | HTTP 状态 | 含义 | 怎么办 |
|---|---|---|---|
filter_required | 400 | 必填筛选条件没给或给不全(既没给小区名,也没给「区 + 起止月份」,或月份跨度超过 3 个月) | 补上 community,或补全 district + month_from + month_to 且跨度 ≤ 3 个月 |
invalid_cursor | 400 | 请求参数 cursor 被改动、过期,或不属于这次查询 | 不要自己拼游标;从第一页重新查 |
release_changed | 409 | 翻页途中数据版本切换了,旧游标失效 | 从第一页重新查(缩小条件可少花积分) |
insufficient_balance | 402 | 余额不足以支付本页 | 充值,或把 limit 调小,或先查 /v1/usage 看余额 |
daily_cap_reached | 429 | 触到你设的每日消费上限 | 明天再查,或用 PUT /v1/account/limits 调整上限 |
rate_limited | 429 | 请求太快,超过每密钥限速(占位:每秒 5 次) | 降低并发、加间隔后重试;不要立刻狂重试 |
max_credits_exceeded | 402 | 本次要扣的积分超过 X-Max-Credits 上限 | 调大上限,或把 limit 调小后重试(本次未扣费) |
trial_limit_reached | 429 | 试用账户当天条数已用完 | 次日再查,或联系我们升级为积分/订阅账户 |
idempotency_conflict | 422 | 同一个 Idempotency-Key 被用于另一个不同的请求 | 换一个新的 Idempotency-Key;同一个 Key 只对应同一个请求 |
full_refresh_required | 410 | 增量的 since 太旧或无法识别,已不在保留的版本链里 | 重新拉全量,之后按版本号顺序逐期应用增量 |
delta_forbidden | 403 | 当前账户未开通「每天同步」(增量)权限 | 联系我们开通 |
bulk_forbidden | 403 | 当前账户未开通整份文件下载权限 | 联系我们开通 |
file_unavailable | 503 | 文件暂时不可用 | 稍后重试;持续出现请联系我们 |
release_unavailable | 503 | 暂时没有可用的数据版本 | 稍后重试;持续出现请联系我们 |
此外还有:密钥无效/已吊销返回 401,账户被暂停返回 403,参数不认识返回 400,请先看code再看message。
9 命令行与智能助手
9.1 pcfh 命令行
密钥只从环境变量 PCFH_API_KEY 或 --key-file 私密文件读取,不要作为命令行参数传。
pcfh status --format json pcfh communities 示例 --format table pcfh deals --community 示例花园 --max-rows 200 --format csv --output /tmp/deals.csv pcfh deals --district 福田区 --month-from 2026-08 --month-to 2026-10 --budget 60 --max-rows 200 --format json pcfh stats district --district 福田区 --month-from 2026-01 --month-to 2026-10 --format json pcfh stats community 示例花园 --format json pcfh usage --format json
要点:
deals支持--sign-date-from、--sign-date-to、--bedrooms、--min-area、--max-area、--property-type、--exclude-dup-suspect。- 默认最多 200 条,可选 1–1000;不多取后丢弃,不为限行之外的数据付费。
--budget(积分预算)会给每一页带上X-Max-Credits,超预算自动停止,报告stop_reason: budget。- 表格默认显示前 20 条;CSV 为 UTF-8 带 BOM,
--zh-headers可加中文第二标题行。 - 成交表格与 CSV 默认省略
deal_id,加--with-id才显示;JSON 与接口原始返回保持原样。 - 默认拒绝覆盖已有文件,加
--overwrite才允许(会先生成.bak-备份)。 - 服务地址由
PCFH_API_BASE指定(我们开通时提供,远程必须是 HTTPS)。
9.2 MCP 工具(给智能助手用)
配置好以后,助手侧应看到且只看到六个工具:
| 工具 | 用途 |
|---|---|
search_communities(q) | 小区模糊搜索,最多 20 个 |
query_deals(...) | 成交明细筛选,默认 50、上限 1000 条,返回前 20 行预览;include_id=true 才返回编号 |
export_deals_csv(output_path, ...) | 同筛选条件直接导出 CSV(UTF-8 BOM),只返回行数、路径、扣费、截断汇总 |
get_district_monthly_stats(...) | 区月统计,默认 50 条,可筛区和月份 |
get_community_yearly_stats(community, ...) | 小区年统计,默认 50 条 |
get_usage() | 免费查余额、用量、套餐额度 |
查询与统计都支持 max_rows(最多条数)和 budget(积分预算)。要存文件就用 export_deals_csv,不要手抄。
通用 MCP 客户端配置(把路径换成你本机的实际路径,密钥只给文件路径,不要写进配置正文):
{
"mcpServers": {
"pcfh": {
"command": "/绝对路径/agent/.venv/bin/pcfh-mcp",
"args": ["--key-file", "/你的私密目录/api-key"],
"env": {"PCFH_API_BASE": "你的服务地址(开通时提供)"}
}
}
}
9.3 一句话接入
把下面这段发给你的智能助手(把中文引号里的三处换成真实路径/地址,不要把「密钥文件路径」换成密钥正文):
请把我已下载到「插件绝对路径」的 pcfh 插件接入当前智能助手:先读其中的 skill/pcfh/SKILL.md 和接入各种Agent.md,使用我在本机提供的密钥文件「私密文件路径」和服务地址「API地址」,先在临时目录验证配置与 get_usage,再给出适合当前客户端的项目配置;不读取或显示完整密钥,不覆盖原配置,不改本机全局配置;完成后查示例花园近六个月成交,预算最多 200 积分、最多 200 条,整理成表格并保存 CSV,告知日期范围、费用和是否完整。
10 数据说明与限制
请在使用前读完这一节,它决定了这些数字能怎么用、不能怎么用。
- 不是官方网签数据。 本数据仅供业务参考,不构成估价或投资建议;全市成交总量请以官方网签数据为准。
- 可能有遗漏、重复和滞后。 同一笔成交可能被记录多次,我们做了合并,但
deal_count等总数仍可能偏多几个百分点,不是完全去重后的数字;疑似重复的行标了dup_suspect,是否剔除由你决定。 - 成交日期不等于数据到达日期。 记录可能在成交后几周、几个月甚至更久才到,所以「新到的记录」请看
first_published_date,不要用sign_date判断。 - 最近 1–3 个月的数据不完整,当月尤其少;统计表用
is_provisional = true标出这些月份/年份,做趋势分析时请自行留意。 - 月度条数反映的是我们的覆盖程度,不等于全市真实成交量,不宜当作市场成交量指数使用。
- 样本少于 5 条时价格字段为空,统计表也不提供最高价、最低价。
- 不提供的信息:具体楼层、楼栋 / 单元 / 房号、原始楼层文字、原始户型文字、经纪人 / 业主 / 买方信息、内部编号。楼层只给
low/mid/high。 - 小区名称为记录原名,同一小区可能有不同写法,v1 不做名称统一;搜索时建议用
/v1/communities先确认写法。 - 版本与兼容:契约版本
1.0。次版本升级只新增可选字段,不删字段、不改名、不改含义和单位,遇到不认识的字段请忽略;主版本升级会提前 30 天通知。 - 数据保留:超出 24 个月窗口的成交会从明细里移除(增量里表现为
remove+reason: aged_out);能否继续保存和使用,以合同约定为准。