Data API(本页此前记为 Server API)让您的后端能够读取 TRACIO 已经为您的工作区收集的识别数据:某位访客的历史记录、单次会话,以及短窗口的活动速率计数器。少数路由也支持写入 —— 账户记录、自定义字段和列表条目 —— 让您的后端可以补充 TRACIO 掌握的信息。
它是对 Webhooks 的补充,而不是替代:
| Webhooks | Data API | |
|---|---|---|
| 方向 | TRACIO 推送到您的端点 | 您的后端按需拉取 |
| 时机 | 每次识别发生时 | 在您的保留期内的任意时刻 |
| 适合场景 | 对某个事件作出反应 | 决策过程中查数据、回填、事后调查 |
两种方式都从 Pro 套餐起提供。
https://api.tracio.ai/v2它与浏览器端点(edge.tracio.ai)以及仪表盘(app.tracio.ai)分属不同的主机。三者
彼此独立:浏览器用您的公钥与边缘通信,您的后端用您的私密密钥与 Data API
通信。
/v1 路由已被移除。请使用 /v2:路由保持不变,所有 JSON 键和查询参数均采用 snake_case(visitor_id、risk_score、min_risk_score)。您自己的 fields 和 labels 字典中的键属于您的数据,保留原有拼写。JavaScript SDK 继续使用 camelCase 接口。
每个请求都以 bearer 令牌的形式携带您的私密密钥:
curl -H "Authorization: Bearer tracio_sk_XXXX...XXXX" \ "https://api.tracio.ai/v2/visitors/X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y"Data API 仅用于服务器之间的调用。 它有意不返回 CORS 头,因此浏览器无法调用它 —— 正是这一点让您的私密密钥远离客户端代码。切勿把私密密钥下发到浏览器。
在仪表盘的 API Keys 中创建,并选择 secret 类型。
tracio_sk_ 后跟 43 个字符,总长 53 个字符。仪表盘按开头的几个字符列出
密钥,方便您区分。404,与数据不存在时完全相同。轮换会签发一个新密钥,并让旧密钥继续可用 7 天,因此您可以在没有停机的情况下完成 切换。部署新密钥,确认流量已经切过去,然后让旧密钥自然过期。公钥不可轮换 —— 它们不是 机密,按设计就会出现在您的页面源码里。
| 方法 | 路径 | 返回内容 |
|---|---|---|
GET | /v2/visitors/{visitor_id} | 某位访客的聚合历史,以及其最新会话 |
GET | /v2/visitors/{visitor_id}/sessions | 该访客会话的分页列表 |
GET | /v2/visitors/{visitor_id}/sessions/latest | 仅最近的一次会话 |
GET | /v2/visitors/{visitor_id}/velocity | 短窗口内的活动计数器 |
GET | /v2/sessions/{request_id} | 按请求标识符获取的单次会话 |
POST | /v2/accounts/metadata | 为您的账户 ID 附加显示名称和电子邮件 |
POST | /v2/events/fields | 在页面加载之后为某次访问附加自定义字段 |
POST | /v2/events/fields/delete | 从某次访问中清除自定义字段 —— 访问本身不受影响 |
GET | /v2/lists | 您工作区的列表:id、名称、类型(即动作)、模式、条目数 |
POST | /v2/lists/{list_id}/entries | 向列表添加一个值,可选设置 TTL |
POST | /v2/lists/{list_id}/entries/delete | 从列表中移除一个值 |
GET | /.well-known/webhook-keys | 用于 webhook 平台签名的公钥(无需认证) |
同一个密钥和主机还提供决策类 API,全部采用 snake_case:
| 方法 | 路径 | 用途 |
|---|---|---|
POST | /v2/transactions | 对业务事件给出同步的 APPROVE / REVIEW / DECLINE 决策 —— Business 及以上;联盟推广转化(带 affiliate_id 的 account_register 或 deposit)除外,它在所有具备 API 访问权限的套餐中提供 |
GET | /v2/transactions/{transaction_id} | 重新读取某个决策及其标签和生效状态 —— Business 及以上;归属于联盟推广者的交易除外 |
PUT, DELETE | /v2/transaction-labels | 为最多 50 笔交易设置或移除结果标签 —— Business 及以上 |
GET | /v2/transaction-labels/value-set | 可接受的标签取值及其极性 —— Business 及以上 |
POST | /v2/logins/assess | 评估一次登录:allow / challenge / review / deny,并附原因 |
POST, GET | /v2/accounts/{user_id}/trusted-devices | 在您的升级验证之后,将某次访问的设备设为该账户的受信任设备,或列出该账户的受信任设备 |
DELETE | /v2/accounts/{user_id}/trusted-devices/{device_ref} | 撤销某台设备的信任 |
GET | /v2/affiliates/{affiliate_id} | 某个联盟推广者 90 天内的质量报告,附 hold / review 建议 |
POST, GET | /v2/self-exclusions | 为某个账户设置或延长自我排除,或列出自我排除 |
DELETE | /v2/self-exclusions/{user_id} | 提前解除自我排除 |
它们的结果也会以 webhook 事件的形式送达:
transaction_state_changed、login_risk、trusted_device_enrolled、
trusted_device_revoked 和 affiliate_threshold_crossed。
末尾的斜杠会被接受并忽略。未知路径或错误的方法同样返回与其他情况一致的 JSON 错误信封, 绝不会返回 HTML 或纯文本页面。
每次读取都受一个时间窗口约束,由两个可选的查询参数控制:
| 参数 | 接受的取值 |
|---|---|
from | YYYY-MM-DD 或完整的 RFC 3339 时间戳 |
to | YYYY-MM-DD 或完整的 RFC 3339 时间戳 |
to 只给日期时,会包含那一整天。400 invalid_request 及消息 time must be YYYY-MM-DD or RFC3339
被拒绝。meta 中回传,因此请检查 meta.from 和 meta.to,不要假定您的请求被原样采纳。curl -H "Authorization: Bearer tracio_sk_XXXX...XXXX" \ "https://api.tracio.ai/v2/visitors/X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y"响应携带聚合历史,并内嵌最新的一次会话,因此常见场景只需要一次请求而不是两次:
{ "visitor_id": "X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y", "first_seen_at": "2026-05-02T10:11:12Z", "last_seen_at": "2026-07-25T08:00:00Z", "visits": 42, "incognito_visits": 3, "unique_ips": 5, "unique_countries": 2, "browsers": ["Chrome"], "os": ["macOS"], "devices": ["desktop"], "risk": { "max_risk_score": 63, "avg_bot_score": 12.5, "bot_sessions": 7, "last_decision": "real" }, "network": { "vpn_seen": false, "proxy_seen": false, "tor_seen": false, "datacenter_seen": true, "proxy_detected_seen": true, "last_isp": "Deutsche Telekom", "last_real_ip": { "address": "203.0.113.7", "country": "NL", "isp": "KPN" } }, "last_session": { "request_id": "9c1f6a2e-3b7d-4c58-a1e2-6f0d8b4a7c31", "visitor_id": "X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y", "account_id": "user_8842", "account": { "id": "user_8842", "email": "ann@example.com", "display_name": "Ann Lee" }, "timestamp": "2026-07-25T08:00:00Z", "tag": "checkout", "fields": { "order_ref": "A-1029" }, "url": "https://shop.example.com/checkout", "ip": "203.0.113.42", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36", "browser": { "name": "Chrome", "version": "126.0" }, "os": { "name": "macOS", "version": "14.5" }, "device": "desktop", "gpu": "Apple M2", "geo": { "country": "DE", "city": "Berlin", "timezone": "Europe/Berlin", "isp": "Deutsche Telekom" }, "network": { "vpn": false, "proxy": false, "tor": false, "datacenter": false, "connection_type": "residential", "proxy_detected": true, "real_ip": { "address": "203.0.113.7", "country": "NL", "isp": "KPN" }, "asn": 3320 }, "screen": { "width": 2560, "height": 1600, "color_depth": 30, "pixel_ratio": 2 }, "locale": { "languages": ["en-US", "de"], "timezone": "Europe/Berlin" }, "client_hints": { "architecture": "arm", "bitness": "64", "platform_version": "14.5.0" }, "extensions": [ { "slug": "ublock-origin", "name": "uBlock Origin", "category": "adblock", "risky": false, "store_url": "https://chromewebstore.google.com/detail/cjpalhdlnbpafiamejdnhcphjbkeiagm" } ], "bot": { "result": "human", "score": 4.5, "antidetect_score": 2.1 }, "identification": { "confidence": 0.97, "incognito": false, "match_type": "exact", "match_confidence": 0.99 }, "device_info": { "device_id": "d_4f9c2e", "cross_browser": true, "confidence": 0.88, "linked_browsers": 2 }, "decision": { "action": "real", "risk_score": 12, "suspect_score": 3 } }, "meta": { "plan": "business", "retention_days": 90, "from": "2026-04-26T00:00:00Z", "to": "2026-07-25T12:00:00Z" }}| 字段 | 含义 |
|---|---|
visits、incognito_visits | 窗口内的总访问次数,以及其中有多少次发生在隐私窗口中 |
unique_ips、unique_countries | 窗口内出现过的不同地址与国家数量 |
browsers、os、devices | 该访客出现过的不同环境 |
risk.max_risk_score | 窗口内记录到的最高风险评分,0..100 |
risk.last_decision | 最近一次访问所记录的判定 |
risk.avg_bot_score、risk.bot_sessions | 机器人评分均值与机器人会话数 —— Business 及以上 |
network.*_seen | 该访客是否曾出现过 VPN、代理、Tor 出口节点或数据中心地址 |
network.proxy_detected_seen | 窗口内是否至少有一次访问经由浏览器前面的代理或 VPN 出网 —— 参见设备事实中的 network.proxy_detected |
network.last_isp | 最近一次的 ISP —— Business 及以上 |
network.last_real_ip | 在代理或 VPN 背后观测到的最近一个地址(address、country、isp)—— Business 及以上;没有访问带来这样的地址时不存在 |
last_session | 最近一次访问的完整会话对象 |
meta | 套餐、以天为单位的保留期,以及实际生效的窗口 |
在保留期内没有数据的访客会返回 404 not_found,消息为
visitor not found in the retention window —— 这不是您集成中的错误,它意味着该访客是新
访客,或其数据已超出保留期。
会话携带两种判定,它们回答的是不同的问题 —— 客户端是否为自动化程序,以及风险引擎的 总体结论是什么:
| 字段 | 取值 |
|---|---|
bot.result | human、bot、uncertain |
bot.type | 当 bot.result 为 bot 时存在:要么是具体工具(playwright、puppeteer、selenium、jsdom、claude_computer_use 等),要么是经过验证的 AI 代理(ai_agent:<vendor>),要么在无法指名工具时给出所属类别 —— automation、headless、antidetect、extension、privacy_browser、impersonation、other |
decision.action | real、fake、suspicious |
bot.score 和 decision.risk_score 的取值范围都是 0..100。在 Business 及以上套餐中,
guidance 会把它们转化为阶梯 allow → challenge → review → deny 上按场景给出的建议
—— 每一级的含义参见Guidance。
取值与刻度和同一次访问的 v3 webhook 正文一致,guidance 也按相同的规则计算。
curl -H "Authorization: Bearer tracio_sk_XXXX...XXXX" \ "https://api.tracio.ai/v2/visitors/X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y/sessions?limit=100&min_risk_score=50"| 参数 | 默认值 | 说明 |
|---|---|---|
limit | 50 | 上限为 500;更大的值会被收窄,而不是被拒绝 |
from、to | 套餐保留期 | 上文所述的共用时间窗口 |
cursor | —— | 上一页返回的不透明分页游标 |
bot_result | —— | 只保留具有该机器人判定的会话 |
min_risk_score | —— | 只保留风险评分不低于该值的会话,0..100 |
会话按从新到旧返回:
{ "items": [ { "request_id": "9c1f6a2e-3b7d-4c58-a1e2-6f0d8b4a7c31", "visitor_id": "X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y", "timestamp": "2026-07-25T08:00:00Z" } ], "next_cursor": "MTcyMTg5NDQwMDAwMDphYmMxMjM", "has_more": true, "meta": { "plan": "business", "retention_days": 90, "from": "2026-04-26T00:00:00Z", "to": "2026-07-25T12:00:00Z" }}翻页基于游标。没有 page 或 offset 参数:把收到的 next_cursor 作为 cursor 传回去,
并在 has_more 为 true 时继续翻页。最后一页可能根本不包含 next_cursor,因此不要把该字段设为必填。
async function allSessions(visitorId: string, secretKey: string) { const sessions = [] let cursor: string | undefined
do { const url = new URL(`https://api.tracio.ai/v2/visitors/${visitorId}/sessions`) url.searchParams.set("limit", "500") if (cursor) url.searchParams.set("cursor", cursor)
const res = await fetch(url, { headers: { Authorization: `Bearer ${secretKey}` } }) if (!res.ok) throw new Error(`Data API: ${res.status}`)
const page = await res.json() sessions.push(...page.items) cursor = page.has_more ? page.next_cursor : undefined } while (cursor)
return sessions}请把游标当作不透明值 —— 它的内容属于实现细节,可能发生变化。被改动过的游标会以
400 invalid_request 及消息 malformed cursor 被拒绝。
除了取自 User-Agent 的浏览器和操作系统之外,会话还携带访客浏览器上报的关于这台机 器的信息,已在我方净化。访问未携带此类数据时每个字段都不存在,因此请把每个字段都 当作可选的。
| 字段 | 含义 |
|---|---|
gpu | 浏览器报告的显卡型号(WebGL),归一化为可读名称——Intel Iris Xe Graphics、Apple M1 Pro、Qualcomm Adreno 830;Software renderer 表示没有真实 GPU(虚拟机或 headless 环境);Safari 报告为 Apple GPU |
network.proxy_detected | 该次访问的 HTTP 流量与其原始网络路径经由不同网络出口——浏览器前面有代理或 VPN;同一服务商的两个地址(运营商 NAT、同一 VPN 的第二个出口)不算;地址无法比较时(iCloud Private Relay、IPv4 与 IPv6 并存)不会标记 |
network.real_ip.address, .country, .isp | 在原始网络路径上观测到的公网地址,也就是代理或 VPN 背后的地址,并附带其国家与 ISP——Business 及以上;未观测到这样的地址时不存在(country 与 isp 在无法解析时不存在) |
device_info.device_id, .cross_browser, .confidence, .linked_browsers | 在识别出设备身份时存在:跨这台机器上多个浏览器的物理设备稳定 id、本次访问是否来自与以往不同的浏览器、这次匹配的置信度,以及有多少个不同的访客(浏览器)共用这台设备——大于一表示同一台机器以多个浏览器身份出现——Business 及以上 |
os_environment | 在 Linux 机器上实测到的桌面环境(Mint 22+、Ubuntu 25.04+、Ubuntu、GNOME、KDE)——Business 及以上;无法判定时不存在 |
spoofing | 该次访问的声称与独立检查实测结果的对照(claimed、real、取自 os、gpu、screen、network、browser 的 spoofed_axes;带产品名称的 anonymous_browser)——Business 及以上;只有检测到伪装时才存在 |
screen.width, .height, .color_depth, .pixel_ratio | 浏览器报告的屏幕分辨率、色深与 device pixel ratio——Business 及以上 |
locale.languages, locale.timezone | 浏览器自身偏好的语言与时区——不同于由 IP 地址推导出的 geo.timezone;两者不一致是位置被伪造的常见迹象——Business 及以上 |
client_hints.architecture, .bitness, .model, .device_name, .platform_version | User-Agent Client Hints:CPU 架构与位数、设备型号代码(Android,例如 SM-A556B)及其来自 Google Play 设备列表的营销名称(device_name,例如 Samsung Galaxy A55 5G),以及确切的平台版本;仅限基于 Chromium 的浏览器——Business 及以上 |
environment.virtual_machine, environment.hypervisor | 只有显卡自报为虚拟显卡时才存在;hypervisor 是封闭字典(vmware、virtualbox、parallels、qemu、hyperv、bochs、intel-gvt、vgpu)。缺少该块意味着没有此类证据——Business 及以上 |
extensions 列出本次访问期间检测到的浏览器扩展 —— Pro 及以上。
每一项都是一个对象:
| 字段 | 含义 |
|---|---|
slug | 该扩展稳定的机器标识符,与 Webhook 传递的值相同 |
name | 便于阅读的名称 |
category | 粗略分类 —— adblock、privacy、automation、wallet、vpn、devtools、other 等 |
risky | 对于与自动化、伪装或凭据窃取相关的扩展为 true |
store_url | 指向该扩展商店页面的链接,在已知时提供 |
只有在通过我方可信度检查之后,一条发现才会被报告 —— 对每一次探测都回答“已安装”的环境,或者一次超过十二个名称的批量结果,都会作为不可靠数据被丢弃。因此,空列表或缺失的列表意味着“我们无法确认任何东西”,而不是“没有安装任何扩展”。请把它当作证据来读,而不是当作一份清单。
fields 包含您的集成附加到本次访问上的自定义键值对,例如订单编号、套餐名称、支付结果。键和值始终是字符串:附加的数字或布尔值会以文本形式返回。与会话的其他部分一样,它在所有可使用 API 的套餐(Pro 及以上)中提供;访问没有任何字段时,该字段不出现。
fields 在每次请求时实时读取,而不是在访问发生时复制保存。访问之后附加的字段(参见访问之后附加字段)也会出现在这里,因此对于同一次访问,fields 可能比 Webhook 传递的内容更多。
请勿将姓名、电子邮件地址或电话号码等个人数据放入自定义字段,而应附加一个您自己的系统能够解析的引用标识,并把账户是谁作为账户记录发送(见下文)。
account 是您为该次访问背后的账户保存的记录 —— 即您最近一次通过 POST /v2/accounts/metadata 为该 account_id 发送的内容:
{ "account": { "id": "user-42", "email": "ann@example.com", "display_name": "Ann Lee" }}| 字段 | 说明 |
|---|---|
id | 您的账户 ID —— 与 account_id 的值相同 |
email | 您为该账户发送的电子邮件地址;为空时不存在 |
display_name | 您为该账户发送的显示名称;为空时不存在 |
该记录在每次请求时实时读取,因此改名也会体现在旧的访问上:这个块描述的是账户现在的样子,而不是访问发生时的样子。它在所有具备 API 访问权限的套餐(Pro 及以上)中提供。随记录发送的标签不会返回。
在以下情况下该块不存在:访问没有关联账户;该账户没有记录(或您通过发送空值清除了它);以及 —— 极少数情况下 —— 记录无法读取:此时会话仍会完整返回,而不会让请求失败,因此请把缺失的块当作“未知”,而不是“该账户没有电子邮件”。Webhook 不携带这个块。
最近的一次:
curl -H "Authorization: Bearer tracio_sk_XXXX...XXXX" \ "https://api.tracio.ai/v2/visitors/X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y/sessions/latest"它直接返回一个会话对象 —— 不是数组,也没有包在信封里。窗口内没有会话的访客会得到
404 not_found,消息为 no sessions for this visitor in the retention window。
或者按 request_id 获取,这个标识符同样会出现在 webhook 载荷中:
curl -H "Authorization: Bearer tracio_sk_XXXX...XXXX" \ "https://api.tracio.ai/v2/sessions/9c1f6a2e-3b7d-4c58-a1e2-6f0d8b4a7c31?visitor_id=X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y"这里的 visitor_id 是可选的,但在您知道它时一并传入会让查询明显更快。
identification.drift_score —— 账户盗用判定所依据的平滑行为评分,Business 及以上 —— 只由这个单会话读取返回。行为漂移是在访问过程中、初次识别之后测量的,因此列表和最新会话路由不包含它。行为从未被评判过的访问没有 drift_score。同样的值也会通过 account_takeover webhook 送达。
一次访问可能通过 webhook 投递不止一次:先是 primary,随着较慢的信号和行为证据到达,再是 late 或 correction —— 而较晚的阶段可能推翻先前的判定。Data API 依据 primary 记录作答。 较晚的阶段不会合并回该记录,因此对于被更正的访问,最后一次 webhook 才是较新的答案。如果您在访问发生几分钟后才采取行动,请优先采用最后收到的阶段,而不是在这里重新读取。
有一件事方向相反:一旦账户盗用检测器针对某次访问触发,这里的 guidance 会反映它,而同一次访问的 identification webhook 正文不携带这一维度 —— 它随专门的 account_takeover 投递送达。
活动速率回答的是“这位访客最近做了多少事” —— 撞库、盗卡试刷和批量注册都是这种形态。
curl -H "Authorization: Bearer tracio_sk_XXXX...XXXX" \ "https://api.tracio.ai/v2/visitors/X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y/velocity?window=1h"window 接受 1h、24h 或 7d,默认值为 24h。其他任何取值都会以
400 invalid_request 及 window must be one of: 1h, 24h, 7d 被拒绝。
{ "window": "1h", "events": 37, "unique_ips": 9, "unique_countries": 3, "unique_accounts": 12, "bot_events": 4, "meta": { "plan": "business", "retention_days": 90, "from": "2026-07-25T11:00:00Z", "to": "2026-07-25T12:00:00Z" }}unique_accounts 统计的是您为该设备发送过的不同 linkedId 取值 ——
参见账户关联。bot_events 为 Business 及以上;在 Pro 上该键不存在。
TRACIO 只通过您的网站作为 linkedId 传入的 ID 认识您的账户 —— 一个像 usr_8412 这样的不透明字符串。只需发送一次便于阅读的标签,仪表盘上每个展示该账户的界面就会显示名称或电子邮件而不是原始 ID,会话对象也会在其 account 块中返回它们。这里的内容不影响检测或评分;它只是一个展示层。
curl -s -X POST "https://api.tracio.ai/v2/accounts/metadata" \ -H "Authorization: Bearer tracio_sk_XXXX...XXXX" \ -H "Content-Type: application/json" \ -d '{"accounts":[ {"account_id":"usr_8412","email":"ann@example.com","display_name":"Ann Lee","labels":{"tier":"vip"}}, {"account_id":"usr_9130","display_name":"Bob Ray"} ]}'{ "updated": 2 }fields。 在这里发送的电子邮件或姓名只保存在您工作区的账户记录中:它不按访问存储,不写入页面,一次发送即可更新该账户的每一次访问。400 invalid_request,并且一条错误的条目就会导致整批被拒绝 —— 错误信息会指出它的位置。同一批中重复的账户 ID 没有问题:以最后一条为准。限制:单次请求最多 1000 个账户,请求体 1 MiB,account_id ≤ 256 个字符,email ≤ 320,display_name ≤ 256,标签最多 16 个,键 ≤ 64、值 ≤ 256 个字符。
浏览器只能发送页面在渲染时知道的内容 —— 订单 ID 可以,但支付检查的结果或其他稍后才确定的事情就不行。这个路由填补了这一空缺:通过某次访问已经携带的字段找到它,再在服务端为它附加更多字段。
curl -s -X POST "https://api.tracio.ai/v2/events/fields" \ -H "Authorization: Bearer tracio_sk_XXXX...XXXX" \ -H "Content-Type: application/json" \ -d '{"match":{"key":"order_ref","value":"A-1029"},"fields":{"amount":"120.00"}}'{ "updated": 1 }match 通过访问已有的字段找到访问,而不是通过 request_id,范围限于您密钥所属的工作区和环境。404 not_found —— 请在结果确定后尽快写入字段。updated 统计的是不同访问的数量。 只有当您的 match 命中多于一次访问时它才会大于 1 —— 也就是该键值对并非某一个订单或购物车独有。命中超过 100 个事件的 match 会以 400 invalid_request 被拒绝,而不是应用到随意的一部分上。server 标记显示,并优先于浏览器写入的同名键的值。404 not_found,而不是空的 200。限制与浏览器通道一致:单次调用 50 个字段,键 ≤ 40 字节,值 ≤ 500 字节 —— 是字节,不是字符 —— 键的字符集为 A-Za-z0-9_.:-,请求体 1 MiB。
清除自定义字段 —— 绝不删除访问本身。用于您不再需要附加在访问上的值,例如订单总额。已经发出的 webhook 和已经导出的数据不会被更改。
# 按 request_id —— 清除这一次访问上的所有字段curl -s -X POST "https://api.tracio.ai/v2/events/fields/delete" \ -H "Authorization: Bearer tracio_sk_XXXX...XXXX" \ -H "Content-Type: application/json" \ -d '{"request_id":"9c1f6a2e-3b7d-4c58-a1e2-6f0d8b4a7c31"}'
# 按 match —— 从当前带有 "A-1029" 的每次访问中清除 "order_ref"curl -s -X POST "https://api.tracio.ai/v2/events/fields/delete" \ -H "Authorization: Bearer tracio_sk_XXXX...XXXX" \ -H "Content-Type: application/json" \ -d '{"match":{"key":"order_ref","value":"A-1029"}}'{ "deleted": 1 }request_id 与 match 互斥 —— 两者同时发送或都不发送,返回 400 invalid_request。match 使用与附加相同的 24 小时窗口和相同的 100 个事件上限。deleted 统计的是从访问中移除的字段数(按 request_id)或被移除该字段的访问数(按 match)。404 not_found。与您的操作员在仪表盘中管理的列表相同,可从您自己的后台访问。列表的类型就是它对匹配访问执行的动作 —— block、manual_review、challenge、allow —— 而它的模式决定是否执行该动作:observe 只统计匹配次数,enforce 将动作应用到 guidance(list 维度)。列表及其模式在仪表盘中创建;Data API 读取列表并添加和移除条目。
curl -s "https://api.tracio.ai/v2/lists" \ -H "Authorization: Bearer tracio_sk_XXXX...XXXX"[ { "id": "7f3a9d2e-4c1b-4e8f-9a6d-1b2c3d4e5f60", "name": "Chargeback accounts", "type": "block", "mode": "enforce", "entries_count": 128 }]# 封禁一个账户 30 天curl -s -X POST "https://api.tracio.ai/v2/lists/7f3a9d2e-4c1b-4e8f-9a6d-1b2c3d4e5f60/entries" \ -H "Authorization: Bearer tracio_sk_XXXX...XXXX" \ -H "Content-Type: application/json" \ -d '{"value":"usr_8412","value_type":"linked_id","ttl_minutes":43200}'{ "id": "02b4c8d1-6e7f-4a90-b1c2-d3e4f5a6b7c8", "value": "usr_8412", "value_type": "linked_id", "expires_at": "2026-10-19T12:00:00Z", "propagation": "immediate"}用相同的请求体调用 POST /v2/lists/{list_id}/entries/delete 即可移除条目;响应为 { "removed": true, "propagation": "immediate" }。
value_type 表示该值用于匹配什么:linked_id、visitor_id、device_id、ip、cidr 或 country。无法按其类型解析的值返回 400 invalid_request。linked_id → visitor_id → device_id → ip → cidr → country —— 在同一类型中,最严格的动作胜出。ttl_minutes 是可选的。 省略时采用列表的默认 TTL;如果列表没有默认值,条目永不过期(expires_at 为 null)。重新添加条目会为其续期。propagation 说明变更何时生效:immediate,或 ttl —— 大约五分钟内。200 及 removed: false;404 保留给未知的列表。字段缺失表示“没有数据”,而绝不表示零。 没有取值的字段会被整个省略,而不会以 0、
"" 或 null 的形式发送:全新的访客没有 match_confidence,干净的访问没有
antidetect_score 或 suspect_score。唯一有意的例外是 bot.score,即使为零它也始终存在。
请以防御性的方式读取字段。
载荷取决于您的套餐。 API 访问从 Pro 起提供,Pro 可获得基础会话 —— 标识符、时间戳、URL、IP、user agent、浏览器、操作系统、设备、地理位置、网络、机器人、识别与判定 —— 以及 identification.match_type、identification.match_confidence、bot.score、bot.type、bot.antidetect_score、gpu、network.proxy_detected、extensions、fields 和 account。Business 与 Enterprise 增加 geo.isp、network.asn、network.real_ip、decision.suspect_score、identification.drift_score、reasons、behavior、guidance、device_info、spoofing、os_environment、screen、locale、client_hints 和 environment。人员级字段(person_id、reputation、linked_accounts_count、linked_visitors_count)保留给 Business 与 Enterprise,将在人员层启用后出现 —— 目前它运行在观察模式下,这些字段不会下发。在 Pro 套餐上没有 Business 字段并不是错误。
任何套餐都不会返回信号级别的内部细节:单个信号的名称、它们的权重、判定背后的阈值、 原始信号取值以及评分构成,都留在我们这一侧。一旦评分可以被反推回它的输入,它作为防护 手段就失效了。
每一次失败都使用同一个信封:
{ "error": { "code": "unauthorized", "message": "missing Authorization: Bearer <secret key>", "request_id": "8f14e45fceea167a5a36dedd" }}这里的 request_id 不是访问标识符。两个不同的取值共用了同一个名字:在会话载荷中,
request_id 是该次访问的 UUID,与 webhook 投递的那个相同;而在错误信封中,它是为每次
HTTP 调用生成的 24 字符追踪标识符。无论请求成功与否,该追踪标识符也会通过每个响应的
X-Request-Id 头返回。联系支持时请附上它 —— 我们正是靠它找到您那一次具体的调用。
| HTTP | code | 含义 |
|---|---|---|
| 400 | invalid_request | 缺少某个参数,或参数格式不正确 |
| 401 | unauthorized | 密钥缺失、无效、已吊销或已过期 |
| 402 | upgrade_required | 您的套餐不包含 API 访问权限 |
| 404 | not_found | 保留期内没有任何匹配项,或它属于另一个环境 |
| 405 | method_not_allowed | 该路由存在,但不支持这个方法 |
| 429 | rate_limited | 超出了每秒请求数,或每日配额 |
| 500 | internal | 我们这一侧出现了故障 |
| 503 | unavailable | 某个后端存储暂时不可达 |
各项检查按固定顺序执行 —— 先密钥,再套餐,最后限额 —— 因此密钥不正确的请求总是先报告
密钥问题,绝不会报成配额问题。来自其他工作区的数据与不存在的数据无法区分:它返回 404,而不是 403。
两种 401 的措辞是有意区分的:missing Authorization: Bearer <secret key> 表示该头
根本没有送达,而 invalid or revoked API key 表示它送达了但没有匹配上。402 携带的是
Data API requires the Pro plan or higher。
对 429 和 503 请以逐渐加长的间隔重试;重试其他 4xx 没有意义 —— 它们意味着请求本身需要修正。
密钥已被识别的响应会携带您当前的状态(401 和 402 响应不携带;没有每日配额的 Enterprise 不会收到配额相关的头):
| 头 | 含义 |
|---|---|
X-RateLimit-Limit | 您的每日配额;因超出每秒限额被拒绝时,为每秒限额 |
X-RateLimit-Remaining | 今天剩余的调用次数 |
X-RateLimit-Reset | 配额重置的 Unix 时间 —— UTC 零点 |
Retry-After | 需要等待的秒数,仅随 429 发送 —— 请以它为准:它对两种限额都准确 |
| 套餐 | 每秒请求数 | 每日请求数 | 历史深度 |
|---|---|---|---|
| Free | 不提供 API 访问 | —— | 7 天 |
| Pro | 10 | 10,000 | 30 天 |
| Business | 50 | 100,000 | 90 天 |
| Enterprise | 200 | 不计量 | 365 天 |