融全云 API · 开放接口 v1
面向所有渠道与开发者的接口 —— 代理商、自研系统、H5、小程序、App、SaaS 工具, 任何能发 HTTP 请求的系统都能接,不绑定任何特定平台或框架。 渠道用平台下发的 AppKey / AppSecret 调用本接口, 平台再去调上游数据源。上游密钥只存在平台服务器上,渠道永远拿不到。
- 接口根地址:
https://www.ttzy.net - 全部接口都是
POST,路径形如/open/v1/query - 请求体统一
application/json(UTF-8) - 返回统一是
{"code":0,"msg":"ok","data":{...}},成功看的是code=0 - 哪些接口能调、每次扣多少钱,见下方「接口清单」或登录后「接口目录」
一个坑先说在前面:HTTP 状态码永远是 200,出错时也是 200。 所以判断成功必须看响应体里的 code,不能只看 HTTP 状态码。
一、接入三步
- 拿密钥:平台开通代理后会把账号密码和
AppKey/AppSecret一起发你;
也可以自助注册,登录代理后台在「接口凭据」里看。
- 填到你的系统里:把接口地址
https://www.ttzy.net、AppKey、AppSecret 填进你自己的
接口配置(或我们提供的模块后台)→ 保存。
- 按工具码发起查询:
/open/v1/ping通了以后,用/open/v1/query传tool+params。
异步工具(比如车牌查车架号)拿 request_id 调 /open/v1/fetch 取结果。
二、签名
每次请求带 4 个请求头:
| 请求头 | 说明 |
|---|---|
X-AppId | 平台给你的 AppKey |
X-Timestamp | 秒级时间戳,与服务器时间相差超过 300 秒会被拒 |
X-Nonce | 随机串,建议 16 位以上(如 bin2hex(random_bytes(8)))。同一个 nonce 只能用一次,重复会被判为重放 |
X-Sign | 签名,小写 32 位 MD5 |
签名算法(注意 md5(body) 是请求体的原始字节,不是重新 json_encode 一遍):
sign = md5( appKey + timestamp + nonce + md5(请求体原文) + appSecret )
几个容易踩的点:
- 拼接顺序固定,中间没有任何分隔符,最后整体做一次 md5。
md5(请求体原文):发出去什么字节就算什么字节。没有请求体时按md5('')算。- 时间戳是秒,不是毫秒;服务器时间要校准(装了 NTP 就不用管)。
- 四个头都要带,少一个直接 401。
三、接口清单
| 接口 | 路径 | 用途 |
|---|---|---|
| 连通测试 | POST /open/v1/ping | 验密钥、看余额,接完第一步就调它 |
| 工具清单 | POST /open/v1/tools | 当前可调的工具 + 你的进货价 |
| 发起查询 | POST /open/v1/query | 主要接口,一次查询扣一次费 |
| 取异步结果 | POST /open/v1/fetch | 异步工具取结果,只读、不重复扣费 |
| 查余额 | POST /open/v1/balance | 余额、今日用量、每日上限 |
| 调用流水 | POST /open/v1/calls | 最近调用记录(查询对象已脱敏) |
当前开放了哪些工具、每个要传什么参数,以 /open/v1/tools 的返回为准 —— 平台上下架工具会跟着变,文档不重复列,免得写的和实际能调的对不上。 网页版清单见 接口清单。
四、接口详情
1. 连通测试 /open/v1/ping
请求体:{}
{"code":0,"msg":"连通正常","data":{"channel":"某某车务","balance":"1000.00","server_time":"2026-09-22 10:00:00"}}
返回 401 一般是:AppSecret 填错、时间戳不对、或者 nonce 重复用了。
2. 工具清单 /open/v1/tools
请求体:{}
{"code":0,"msg":"ok","data":{"list":[
{"tool_code":"vehicle_five","name":"车辆五项查询","cost":"6.00","retail_tip":"8.00",
"params":["vin"],"async":false,"custom":false}
]}}
| 字段 | 含义 |
|---|---|
tool_code | 工具码,调 /query 时传它 |
name | 中文名,给终端用户看的话可以直接用 |
cost | 每次调用扣你的钱(这就是你的进货价) |
retail_tip | 平台建议零售价,仅供参考,卖多少你自己定 |
params | 这个工具要传哪些参数,见下方「参数说明」 |
async | true = 上游要等一会儿,出结果要用 /fetch 取 |
custom | true = 这是平台单独给你的协议价(不是默认价) |
3. 发起查询 /open/v1/query
{"tool":"vehicle_five","params":{"vin":"LSVAM4185E2109876"}}
params 里的键就是 /tools 返回的 params;车架号请传 17 位完整值,程序会自动转大写、去空格。
params 里还可以带一个公共参数(所有工具都认,不算业务参数、不参与必填校验):
| 参数名 | 含义 | 说明 |
|---|---|---|
order_no | 你自己的订单号 | 选填。你系统里那笔订单的编号,传了就会存进调用记录、原样返回。对账时直接拿它和你的账单核 |
order_no 放在 params 里,或者放在请求最外层都行(两种都认 —— 它本来就不是工具参数, 写在最外层更自然):
{"tool":"vehicle_five","params":{"vin":"LSVAM4185E2109876","order_no":"MY-20261002-001"}}
{"tool":"vehicle_five","order_no":"MY-20261002-001","params":{"vin":"LSVAM4185E2109876"}}
只留可见字符、最长 64 位,超了会截断。不传就是空串(调用记录里显示 —),不影响查询。
返回:
{"code":0,"msg":"ok","data":{
"status":"done","tool":"vehicle_five","tool_name":"车辆五项查询",
"fee":"6.00","refunded":"0.00","balance":"994.00","request_id":"","order_no":"","call_no":1234,
"msg":"ok",
"data":{"品牌":"大众","车架号":"LSVAM4185E2109876","车型":"...","发动机号":"...","燃料种类":"汽油"}
}}
order_no 是你传进来的那个单号(没传就是空串),call_no 是平台单号( 调用记录的编号,报障时给这个)。异步工具出结果后 request_id 是上游单号, 取结果和找上游查问题都要它。
data.status 有三种,必须按它分支:
| status | 含义 | 钱怎么算 | 你要做什么 |
|---|---|---|---|
done | 查到数据了,data.data 就是结果 | 扣费 | 存下来给用户看 |
nodata | 这台车查不到数据(老车 / 未收录) | 已自动全额退回 | 提示用户「查无数据」,别收用户的钱 |
pending | 上游还在出结果 | 先扣 | 拿 request_id 调 /fetch,出不来结果会退 |
nodata 示例:
{"code":0,"msg":"查无数据","data":{"status":"nodata","fee":"6.00","refunded":"6.00","balance":"1000.00","data":{}}}
工具不存在、参数缺失、余额不够时返回 code 非 0,data 为 null,具体见「错误码」。
4. 取异步结果 /open/v1/fetch
{"request_id":"1276874656273911808"}
返回结构和 /query 一样,status 可能是 pending / done / nodata / fail。 建议 每 5~10 秒取一次,最多取 3~5 分钟,别拿 1 秒的间隔去轮询。
/fetch 是只读接口,反复取不会重复扣费,也不会重复退款:
| 情况 | 返回 | 说明 |
|---|---|---|
| 上游还在出结果 | pending | 继续等 |
| 上游偶发 5xx / 连不上 | pending | 不是失败,过会儿再取 |
| 出结果了 | done + 数据 | 结果存在平台,再取一次原样返回 |
| 上游超过有效期(一般 60 分钟)还没出结果 | fail + 全额退款 | 之后一直回 fail,不会重复退 |
| 已经结束的单子再取 | 原样回最终状态 | 不报错、不动钱,免得你的订单一直卡在「等待中」 |
5. 查余额 /open/v1/balance
{"code":0,"msg":"ok","data":{"balance":"994.00","today_used":12,"daily_limit":0}}
balance:可用余额(元,字符串)today_used:今天已调用次数daily_limit:每日上限,0表示不限;到上限后/query返回429
6. 调用流水 /open/v1/calls
{"page":1,"size":20}
返回:
{"code":0,"msg":"ok","data":{"page":1,"size":20,"total":1,"list":[
{"id":1,"call_no":1,"order_no":"MY-20261002-001","request_id":"","tool_code":"vehicle_five",
"query":"LSV**********76","fee":"6.00","refund":"0.00",
"status":1,"status_text":"成功","msg":"ok","ms":640,"created_at":"2026-09-22 10:00:00"}
]}}
size最大 100status:0处理中 /1成功 /2失败 /3已退款 /4等上游出结果query是脱敏后的查询对象,完整车架号不返回给渠道call_no平台单号(=id,给个明确名字,别和request_id混)order_no你调用时传进来的自己的订单号,没传是空串request_id上游单号,异步工具有值
五、参数说明
工具要传哪些参数由 /tools 的 params 决定,常用的有:
| 参数名 | 含义 | 说明 |
|---|---|---|
vin | 车架号 | 17 位,不含字母 I O Q;传进来会转大写、去空格和横杠 |
plate | 车牌号 | 例如 京A12345,会转大写、去空格 |
engine | 发动机号 | 少数工具(如 4S 维保)需要 |
mobile | 手机号 | 手机号在网状态这类工具用 |
url_image | 图片地址 | 行驶证识别这类工具用,传可公网访问的图片 URL |
invoice_no | 发票号码 | 发票查验用,必填 |
invoice_date | 开票日期 | 发票查验用,必填,格式 2020-01-01 |
invoice_code | 发票代码 | 发票查验用,选填(全电发票没有代码,不传即可) |
invoice_amount | 价税合计 | 发票查验用,选填 |
invoice_check | 校验码 | 发票查验用,选填。传完整 20 位也行,程序会自动只取后六位 |
invoice_file | 发票文件 | PDF/OFD 查验用,传文件内容的 base64 |
name | 姓名 | 个人风险核查、婚姻查询用,必填 |
id_card | 身份证号 | 个人风险核查、婚姻查询用,必填,15 位或 18 位 |
keyword | 企业名称 | 企业法院查询用,必填 |
credit_code | 统一社会信用代码 | 企业法院查询用,必填,18 位 |
个人 / 婚姻 / 企业风险类接口
这三个工具都走小蓝数据,平台内部用同一套上游密钥;渠道侧仍然只用自己的 AppKey / AppSecret 调本平台,看不到上游凭证。
| 工具码 | 名称 | 需要传 | 主要返回字段 |
|---|---|---|---|
blue_personal_case | 个人风险核查 | name + id_card | 是否涉诉、各类案件数、summary_info、case_info |
marriage_query | 婚姻查询 | name + id_card | 婚姻状态、查询单号 |
court_query | 企业法院查询(企业风险核查) | keyword(企业名称)+ credit_code | 企业名称、统一社会信用代码、查询结果、案件总数、各类案件数、summary_info、case_info |
计费说明:
- 上游小蓝数据的成功标识是
code=1,但渠道看到的仍是本平台的code=0,按本平台统一格式判断即可。 - 婚姻查询:
data.message为空时平台返回婚姻状态=未查询到婚姻状态信息,该次按成功计费(上游已完成查询),不会自动退款。 - 企业法院查询:
respCode=404按无记录处理,返回status=nodata并自动退款;respCode=200且案件数为 0 表示“企业存在、无涉诉”,按成功计费,不退。 - 签名失败、参数错误、余额不足、网络超时等返回
status=fail,自动退款,不会误报成“无记录”。
生成类接口(AI 写作)
这类接口不是「取数据」,是按你给的材料写成一篇稿,用的是固定提示词 + 大模型, 所以有两处和普通查询不一样:
| 参数名 | 含义 | 说明 |
|---|---|---|
topic | 岗位 / 部门 / 主题 | 必填。工作总结、述职报告写岗位;演示稿写主题 |
points | 工作要点 | 必填,一行一条。你写的每一条都会用上,不会被丢掉 |
kind | 文体 | 选填:summary 工作总结(不传就是它)、report 述职报告、ppt 演示稿 |
period | 时间范围 | 选填,例如 2026年10月、2026年度;不填按最近一个自然月 / 年度写 |
words | 字数 | 选填。不传用默认(工作总结 1200 / 述职报告 1500 / 演示稿 12 页);范围 300~6000,超出按边界处理,见下 |
extra | 补充要求 | 选填,例如「突出团队协作」「语气正式一些」 |
style | 版式风格 | 选填:tech 科技风、business 企业风、minimal 简约风、vivid 活力风 |
industry | 行业 | 选填,影响用词和默认风格;不传 style 时按它推一个 |
format | 导出格式 | 选填,可多选:docx,pptx,pdf,png,text |
brand | 品牌名 | 选填,文件页脚署你的名字 |
color | 品牌主色 | 选填,例如 1657FF;传了会盖过风格自带配色 |
| 工具码 | 做什么 | 输出字段 |
|---|---|---|
doc_gen | 工作总结 / 述职报告 / 演示稿,一个接口三种文体 | 见下 |
kind 决定写什么,format 决定出什么文件:
| kind | 出什么 | 默认导出 |
|---|---|---|
summary | 工作总结 | Word + PPT |
report | 述职报告 | Word + PPT |
ppt | 演示稿 | PPT |
data 里会拿到:
| 字段 | 说明 |
|---|---|
标题 | 稿子标题 |
正文 | 全文(kind=ppt 时改为 PPT大纲,逐页纯文本) |
要点覆盖 | 你给的每条要点分别写进了哪一节,用来核对有没有漏 |
写作提示 | 模型提醒你「哪一页该补真实数据」这类话,不是稿子内容 |
files | 各格式的下载链接,{"docx":"https://…","pptx":"https://…"} |
formats | 这次实际生成出来了哪些格式 |
老的工具码doc_summary/doc_report/doc_ppt依然可用 —— 平台会自动转到doc_gen并补上对应的kind,已经接好的程序不用改。
words 怎么生效、写不到怎么办
| 问题 | 行为 |
|---|---|
不传、或传 0 | 用默认值:工作总结 1200 字、述职报告 1500 字、演示稿 12 页(老客户端行为不变) |
| 取值范围 | 字数 300 ~ 6000;kind=ppt 时是页数 4 ~ 30 |
| 传了 8000(超上限) | 不报错。夹到 6000 继续写,返回里 words_applied=6000 如实告诉调用方 |
| 传了 100(低于下限) | 夹到 300 |
| 模型写不够 | 平台自动续写补足(最多补两次),补不满也照常返回 |
| 模型写超了 | 平台自动压缩一遍(只删修饰和空话,事实、数字、要点一个都不动) |
| 计费 | 续写/压缩都是同一次调用的内部动作,只计一次费、只扣一次款 |
返回里会多三个字段,客户端可以直接把「你要求约 5000 字 · 这一版实际写了 4763 字」显示给用户:
| 字段 | 类型 | 说明 |
|---|---|---|
words_requested | int | 请求里 words 的原样回显;没传是 0;kind=ppt 时是页数 |
words_applied | int | 这次实际按多少写(被上下限夹过之后的值);kind=ppt 时是页数 |
chars | int | 正文字符数,算法 mb_strlen(preg_replace('/\s+/u','',正文)) |
一句话:words_requested是用户要的,words_applied是平台按多少写的,chars是最后真实写出来多少。三个数摆在一起,用户就不会怀疑「我填的字数没生效」。kind=ppt时这三个字段同样返回,但words_*是页数,chars量的是 PPT 大纲文本长度。 精度说明(重要):长文(3000 字以上)落点比较稳;短文(1000~1500 字)模型自己的 长度波动较大,实测在目标的 90%~160% 之间浮动。平台会尽力收敛(不足自动续写、 超长自动压缩,都不额外收费),但请不要把words当硬承诺—— 以chars为准展示「实际写了多少字」,是这套字段的设计目的。chars与导出文件(Word/PDF)的实际字数一致,不会出现「接口说 5000、文件只有 3000」。
生成失败会怎样(兜底行为)
模型偶尔会把 JSON 写坏(最常见的两种:输出太长被单次上限截断、字符串里混进控制字符)。 平台的处理顺序是:
- 先自己修:清洗非法 UTF-8、修逗号/引号/多余花括号,多数情况能救回来;
- 修不回来就把正文硬抠出来照常返回 —— 模型其实已经写了一整篇,
因为「JSON 没闭合」把内容丢掉最亏(你拿不到内容只能退款,用户白等一次)。 这种情况下返回里会多一个 _salvaged: 1,status 仍是 done; 标题/正文 都在,只是可能被截断,后面「不够就续写」那一套会接着把它补完;
- 只有连正文都抠不出来(少于 120 字)才真的报
status=fail、自动退款。
所以调用方不需要自己处理「解析失败」:拿到 status=done 就一定有内容; 看到 _salvaged=1 表示这次是兜底出来的,展示上没有任何区别。
个别格式没出来怎么办(skipped)
data.skipped 只在有格式没生成出来时才出现,是个「格式 → 原因」的对象:
{
"files": {"docx": "https://…", "pptx": "https://…"},
"formats": ["docx", "pptx"],
"skipped": {"png": "文档较长,长图需要约 247 MB 内存、本次可用约 96 MB,已跳过"}
}
| 原因 | 触发条件 | 建议 |
|---|---|---|
文档较长,长图需要约 … 已跳过 | 长图会把内存吃穿。长图的画布是「1080 × 高度」,高度跟着正文字数走 —— 5000 字的文档画布约 10800px,峰值要 126MB | 让用户看 Word/PPT;确实要长图就调小 words |
同一时间生成文件的请求较多,这次先跳过 | 平台对 PDF/长图这类吃内存的格式做了并发限制(默认同时 2 份),抢不到位置就让路 | 稍后重新调用一次即可 —— 注意会再扣一次费 |
没出来的格式绝不静默:files里有哪个就表示哪个真的成了;formats是这次的清单。 Word / PPT / 纯文本几乎不会失败,它们不吃内存。只有 PDF 和长图可能被跳过。 请求本身仍然是成功的(status=done),正文照常返回,不会因为少一张图就整单失败。
导出的 PPT 里有什么(都是程序按你的内容排的,不需要你提供素材):
- 分页、配色、版式跟着内容走,要点逐条进场(点一下出一条),讲汇报时节奏自己掌握
- 每个章节自动配一个线性图标(计划→靶心、问题→警示、成效→上扬箭头……)
- 要点里的关键数字会被单独拎出来,做成大号数字卡片;同量纲的数字(比如一排百分比)自动画成条形图
- 传了
brand/color的话,页脚署名和全套配色都会跟着你的品牌走
四个注意点:
- 超时要放长:生成一次要 2~10 秒,渠道那边的 HTTP 超时建议设 120 秒以上,
不然会出现「钱扣了、结果没收到」。失败会退款,但用户体验是「时好时坏」。
- 材料里别指望它编数据:你没给数字的地方,它会写「(此处补充具体数据)」,
提醒使用者自己填 —— 这是故意的,避免拿假数据去汇报。要让它写具体数字, 就把真实数字写进 points。
- 返回里带下划线的字段(
_model/_tokens等)是平台附加的用量信息,
不是稿子内容,展示时跳过即可。
- 文件是平台本地生成的,不额外收费:一次调用按工具价扣一次,想要几种格式就传几种。
下载链接带签名和有效期(默认 7 天),过期后重新调一次即可(会重新计费一次)。
传少了会返回 400 缺少参数 xxx;车架号格式不对会返回 400 车架号格式不正确。
「选填」的参数,工具定义里标了_optional,不传不会报 400。 发票查验的规则是:金额、价税合计、校验码三者至少填一个,都不填上游会回合计金额、价税合计和校验码都为空,这种情况平台按查无数据处理、自动退款。
六、错误码
判断成功只看 code,0 才算成功。
| code | 含义 | 怎么处理 |
|---|---|---|
| 0 | 成功 | 按 data.status 分支 |
| 400 | 参数错误(缺参数、车架号格式不对) | 检查 tool 和 params,别拿原参数重试 |
| 401 | 签名 / 时间戳 / nonce 有问题 | 核对 AppSecret、服务器时间;nonce 要每次新生成 |
| 402 | 余额不足 | 去代理后台充值;充值到账后恢复 |
| 403 | 渠道被停用 | 联系平台 |
| 404 | 工具不存在或已下架、request_id 找不到 | 重新拉 /tools 再调 |
| 405 | 用了 GET | 改 POST |
| 429 | 超过每日调用上限 | 明天再试或找平台提额 |
| 500 | 服务器或上游异常 | 稍后重试;这一笔已扣的钱会自动退回 |
七、计费与退款
- 先扣后调:发起查询时按工具
cost从余额扣,余额不够直接返回402,不会去调上游 - 查不到就退:
nodata/fail全额退回,余额明细里有一笔「退款」 - 异步只扣一次:
pending时扣一次,之后/fetch不再扣钱;最终没出结果也退 - 不会重复扣费、也不会重复退款:取结果是只读的,平台侧做了幂等
- 余额、扣费、退款都能在
/open/v1/balance、/open/v1/calls和后台「余额明细」里对上
八、接入示例
PHP
<?php
$appKey = '你的 AppKey';
$appSecret = '你的 AppSecret';
$base = 'https://www.ttzy.net';
function ocCall(string $path, array $payload, string $appKey, string $appSecret, string $base): array
{
// 注意:签名用的一定是「将要发出去的这串字节」,别在签名后又改 body
$body = json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
$timestamp = (string) time();
$nonce = bin2hex(random_bytes(8));
$sign = md5($appKey . $timestamp . $nonce . md5($body) . $appSecret);
$ch = curl_init($base . $path);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $body,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'X-AppId: ' . $appKey,
'X-Timestamp: ' . $timestamp,
'X-Nonce: ' . $nonce,
'X-Sign: ' . $sign,
],
]);
$raw = curl_exec($ch);
curl_close($ch);
return json_decode((string) $raw, true) ?: ['code' => -1, 'msg' => '响应不是 JSON'];
}
// 1) 连通
var_dump(ocCall('/open/v1/ping', [], $appKey, $appSecret, $base));
// 2) 查一台车
$res = ocCall('/open/v1/query', [
'tool' => 'vehicle_five',
'params' => ['vin' => 'LSVAM4185E2109876'],
], $appKey, $appSecret, $base);
if (($res['code'] ?? -1) === 0 && $res['data']['status'] === 'pending') {
// 3) 异步:过 5~10 秒再来取
$one = ocCall('/open/v1/fetch', ['request_id' => $res['data']['request_id']], $appKey, $appSecret, $base);
}
curl(排障用)
签名要算,所以先用 PHP/脚本算好再填进来:
curl -s -X POST 'https://www.ttzy.net/open/v1/ping' \
-H 'Content-Type: application/json' \
-H 'X-AppId: 你的AppKey' \
-H 'X-Timestamp: 1758500000' \
-H 'X-Nonce: 3f9a1c7b2e8d4056' \
-H 'X-Sign: 算出来的签名' \
-d '{}'
九、常见问题
Q:一直返回 401 签名不正确? 按顺序查:AppSecret 有没有多余空格 → 时间戳是不是秒 → nonce 是不是这次新生成的 → 签名的 body 和实际发出去的 body 是不是同一串字节(用 JSON 库重新序列化过就不一样了)。
Q:pending 一直不出结果怎么办? /fetch 每 5~10 秒取一次,超过工具有效期(一般 60 分钟)平台会自动判失败并退款, 你不用自己处理超时。
Q:nodata 是不是代表接口坏了? 不是。10 年以上的老车、进口车、信息没收录的车都会 nodata,平台不收费,钱已退回。
Q:能不能把车架号完整存到自己库里给用户看? 可以,你查出来的结果归你。但平台侧给渠道的接口和后台一律脱敏, 不存在「平台的接口把你客户的车架号泄出去」这件事。
Q:一次请求能查多台车吗? 不能。一个 request_id / 一次调用对应一台车,批量请自己循环,注意限流和余额。
Q:接口地址能换吗? 不能。我们提供的模块里默认写的就是 https://www.ttzy.net;自己接的话也是填这个地址,改了就调不通。
平台开通代理后可自助查看:接口凭据、接口目录(含你的进货价)、余额明细、调用记录、充值。 文档正文只有这一份,网页版(/docs/)和这里的内容永远一致。