Rybbit 2.9.2 API 使用详解

Rybbit v2.9.2 Stats API 实战:三种凭据(个人键/组织键 rb_org_/会话)、事件上报与 20+ 查询端点详解、游标分页与过滤约定,全部 curl 实测回显,附 403/500/bot 拦截排障。

Rybbit自托管产品分析隐私安全2026/10/30

Rybbit 2.9.2 API 使用详解

目标:掌握 Rybbit v2.9.2 Stats API 的认证体系(个人键/组织键/会话三种凭据)、事件上报端点与 20+ 查询端点的用法,能独立完成「建键 → 上报 → 查询 → 排错」的完整集成。全部请求与响应均在 192.168.1.200 服务器自托管实例上 curl 实测,实测日期 2026-10-30。API 官方标注为 beta,生产集成请关注版本变更。

一、环境信息

项目本次实测环境
实例形态Rybbit v2.9.2 自托管(Docker Compose 全家桶,见部署篇)
API 基址http://192.168.1.200:8129/api(backend 服务,容器端口 3001)
客户端工具curl 7.81(Ubuntu 22.04 自带)
实测凭据个人 API Key kBnXTk…、组织 API Key rb_org_XyVd…、管理员会话(admin@example.com)
实测站点siteId=1(短 id 2c0b9eb7c6a2,已注入 5 pageview + 1 custom_event)

二、前置条件

  1. 已部署实例并可访问 backend(健康检查 curl http://127.0.0.1:8129/api/health 实测返回 OK);
  2. 已注册管理员(注册接口实测用强口令,弱口令被拒);
  3. 推荐先在浏览器看板熟悉数据口径:任意站点侧边栏自带 API Playground(官方推荐的新手入口,可直接点选端点看真实响应与代码片段,来源:官方文档 getting-started.mdx);
  4. 实例内已有站点与流量数据(本篇回显均来自实测注入的 3 访客/5 PV/1 事件)。

三、API 总览

3.1 协议与形态

REST over HTTP/JSON,基址为 backend 的 /api 前缀。官方随仓库发布 OpenAPI 规范(v2.9.2 源码包 docs/src/app/openapi.json),云端实例提供 https://rybbit.com/openapi.json 在线版(404 兜底提示语实测指向该地址)。

3.2 端点域全景

v2.9.2 后端路由实测梳理(源码 server/src/index.ts 与 curl 探测双重确认):

域代表端点(前缀 /api)权限
公共上报POST /track、GET /site/tracking-config/:siteId、POST /session-replay/record/:siteId匿名(tracker 语义)
总览GET /sites/:siteId/overview、/overview/time-series、/overview-lite、/live-user-count站点读
维度统计GET /sites/:siteId/metric、/page-titles、/sessions/locations、/journeys、/retention站点读
会话/事件GET /sites/:siteId/sessions、/sessions/:sessionId、/events、/events/time-series、/events/count站点读
用户GET /sites/:siteId/users、/users/:userId、/user-traits/*站点读
转化GET /sites/:siteId/goals、/funnels、POST /sites/:siteId/goals、/funnels站点读写
错误跟踪GET /sites/:siteId/errors/names、/errors/events、/errors/time-series站点读
管理POST /organizations/:orgId/sites、PUT /sites/:siteId/config、组织/成员/团队管理组织/站点管理
凭据POST /user/api-keys、POST /organizations/:orgId/api-keys会话或全权键
MCP内置 Model Context Protocol 服务端OAuth(个人键同预算)

3.3 认证方式与限流

三种凭据(官方文档定义 + 实测行为对照):

凭据获取方式权限边界实测结果
会话 Cookie登录/注册响应 Set-Cookie当前用户全部权限建站/改配置/建键均成功
个人 API KeyPOST /api/user/api-keys以创建者身份跨全部组织成功查询站点数据
组织 API Key(rb_org_ 前缀)组织管理员经 POST /api/organizations/:orgId/api-keys 创建组织内全部站点,成员离开不失效实测键值以 rb_org_ 开头并成功查询

请求头:Authorization: Bearer <key>(官方推荐);?api_key=<key> 查询参数仅测试用(官方警告会进服务器日志)。另可携带登录会话 Cookie。

限流约定(官方文档口径,实测相符):自托管实例完全不限速、不返回限流响应头;官方云按套餐限制(Standard 50 次/10 秒突发 + 每日 5000 次,Pro 每日 25000 次),配额按凭据属主计费而非按键计费。

四、认证与首次调用

4.1 创建个人 API Key

curl -s -b /opt/rybbit/cookies.txt -X POST http://127.0.0.1:8129/api/user/api-keys \
  -H 'Content-Type: application/json' -H 'Origin: http://192.168.1.200:8129' \
  -d '{"name":"ci-integration"}'

实测回显(节选):

{"configId":"default","name":"ci-integration","start":"kBnXTk",...,"key":"kBnXTkkEVQeQgIueRegFxSpSYbMOffIAphlKLDlTKyTkElDKuwMFWcYGpvwbYrsn","enabled":true,...}

⚠️ key 字段只在创建响应出现一次,立即保存;此后仅能查看 start 前缀(kBnXTk)。可传 expiresIn(秒)设置有效期,缺省永不过期。

4.2 创建组织 API Key(集成推荐)

curl -s -b /opt/rybbit/cookies.txt -X POST \
  http://127.0.0.1:8129/api/organizations/lL3zKTX9RuNjYrSN1ahjXeAXBXfHiJzU/api-keys \
  -H 'Content-Type: application/json' -H 'Origin: http://192.168.1.200:8129' \
  -d '{"name":"org-ci"}'

实测回显(节选):

{"configId":"org","name":"org-ci","start":"rb_org","prefix":"rb_org_","key":"rb_org_XyVdVFfYrjxWbTJAEgHhTjVAvvSVENuCGeEsLCYlGNvqwXrPEoGmWvywKpDKeudc","enabled":true,...}

安全约束(官方文档 + 实测口径):创建「键」的动作本身只接受会话或全权个人键,作用域受限键与组织键不能再铸造新键(防止权限繁殖)。

4.3 首次调用

K='rb_org_XyVdVFfYrjxWbTJAEgHhTjVAvvSVENuCGeEsLCYlGNvqwXrPEoGmWvywKpDKeudc'
curl -s -H "Authorization: Bearer $K" 'http://127.0.0.1:8129/api/sites/1/overview?period=24h'

实测回显:

{"data":{"sessions":3,"pages_per_session":1.6666666666666667,"bounce_rate":33.33333333333333,"session_duration":0,"pageviews":5,"users":3}}

4.4 错误码体系

统一错误结构 {"error", "code", "message", "resolution"},实测三例:

场景实测响应HTTP 码
未带凭据{"error":"Forbidden","code":"FORBIDDEN","message":"Forbidden","resolution":"Use a credential with the required scope and Site or Organization access."}403
路径不存在{"error":"No API route matches GET /api/sites/1/top-pages.","code":"API_ROUTE_NOT_FOUND","message":"...","resolution":"Read https://rybbit.com/openapi.json and choose a documented operation."}404
metric 缺 parameter{"error":"Failed to fetch undefined","code":"INTERNAL_ERROR","message":"...","resolution":"Retry with exponential backoff..."}500(v2.9.2 缺参即 500,见 7.4)

五、各 API 域详解

5.1 事件上报域:POST /api/track

公开端点(tracker 脚本的底层通道),payload 按 type 判别(v2.9.2 zod schema 实录):

type必填特有字段用途
pageviewsite_idpathname/hostname/page_title/referrer/screenWidth/screenHeight/language/anonymous_id/user_id/tag/feature_flags页面浏览
custom_eventsite_id+event_nameproperties(JSON 字符串,≤2048)自定义行为
performancesite_idlcp/cls/inp/fcp/ttfb(可空)Web Vitals
outboundsite_idevent_name、properties(外链 URL)出站点击

pageview 上报实测(完整请求与回显):

curl -s -X POST http://127.0.0.1:8129/api/track \
  -H 'Content-Type: application/json' \
  -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 Chrome/140.0 Safari/537.36' \
  -d '{"type":"pageview","site_id":"2c0b9eb7c6a2","hostname":"demo.example.com","pathname":"/posts/hello-1","page_title":"测试文章","screenWidth":1920,"screenHeight":1080,"language":"zh-CN","anonymous_id":"visitor-1"}'
{"success":true}

custom_event 上报实测:

curl -s -X POST http://127.0.0.1:8129/api/track \
  -H 'Content-Type: application/json' \
  -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 Chrome/140.0 Safari/537.36' \
  -d '{"type":"custom_event","site_id":"2c0b9eb7c6a2","event_name":"signup_click","properties":"{\"button\":\"hero\"}","hostname":"demo.example.com","pathname":"/posts/hello-1","anonymous_id":"visitor-1"}'
{"success":true}

注意事项(实测结论):site_id 用站点短 id(2c0b9eb7c6a2)而非数字 siteId;服务端模拟请求若站点开启 blockBots 会被转存 bot_events 表(接口仍返回 success),服务端集成场景需先关闭该开关(实测排障详见部署篇 10.4);properties 必须是合法 JSON 字符串,非法值被 zod 拒绝返回 400 {"success":false,"error":"Invalid payload",...}。

5.2 总览域:GET /api/sites/:siteId/overview

参数取值说明
period1h/24h/7d/30d/last_24_hours/this_week 等默认时间窗,实测 24h
timezoneIANA 时区名按时区聚合
过滤器country=CN&browser=Chrome 等同名查询参数叠加

实测:?period=24h 返回 {"data":{"sessions":3,"pages_per_session":1.6667,"bounce_rate":33.33,"session_duration":0,"pageviews":5,"users":3}}。时间序列子端点 overview/time-series 返回按桶聚合的曲线数据。

5.3 维度统计域:GET /api/sites/:siteId/metric

多维通用端点,type 选维度、parameter 选细分字段(缺 parameter 实测 500):

typeparameter 示例返回
pagespathname页面 TOP
eventsevent_name事件 TOP
browser / os / device / country / region / city / language / referrer / channel / entry_page / exit_page / hostname对应值分布

实测一(页面 TOP,type=pages&parameter=pathname&limit=5,节选):

{"data":{"data":[{"value":"/posts/hello-1","hostname":"demo.example.com","count":1,"percentage":20,"pageviews":1,"pageviews_percentage":20,"time_on_page_seconds":0,"bounce_rate":0},{"value":"/posts/hello-2",...}...

实测二(事件 TOP,type=events&parameter=event_name&limit=5,补发 signup_click 后):

{"data":{"data":[{"value":"signup_click","count":1,"percentage":100}],"totalCount":1}}

5.4 会话与事件明细域

sessions 实测回显(节选,一条会话的完整画像):

{"data":[{"session_id":"NoLWB_zQMv37OF","user_id":"9313ec3c9872","identified_user_id":"","country":"\u0000\u0000","region":"","city":"","language":"zh-CN","device_type":"Desktop","browser":"Chrome","browser_version":140,"operating_system":"Linux",...

events 实测回显(节选):

{"data":[{"timestamp":"2026-10-30 03:19:10","event_name":"","properties":"{}","session_id":"IltCWTPuwaoTnS","user_id":"d7e8324502e5",...,"pathname":"/posts/hello-4",...,"page_title":"测试文章 4","browser":"Chrome","browser_version":140,"operating_system":"Linux",...

明细域统一支持游标分页:响应尾部的 "cursor":{"hasMore":true/false,"oldestTimestamp":...},翻页时把 cursor 值作为 ?cursor= 传入。

5.5 错误跟踪域

  • GET /api/sites/:siteId/errors/names:错误名聚合(错误跟踪功能需前端接入 error 采集脚本后产生数据);
  • GET /api/sites/:siteId/errors/events:错误事件明细,支持过滤;
  • GET /api/sites/:siteId/errors/time-series:错误趋势。

5.6 管理域

# 建站(组织管理员权限)
curl -s -b /opt/rybbit/cookies.txt -X POST \
  http://127.0.0.1:8129/api/organizations/lL3zKTX9RuNjYrSN1ahjXeAXBXfHiJzU/sites \
  -H 'Content-Type: application/json' -H 'Origin: http://192.168.1.200:8129' \
  -d '{"name":"Demo Site","domain":"demo.example.com"}'

实测回显(节选):{"id":"2c0b9eb7c6a2","siteId":1,...}。站点配置更新走 PUT /api/sites/:siteId/config(全字段覆盖,实测 {"blockBots":false} 回显 "message":"Site configuration updated successfully",全字段清单见配置篇 5.4)。

六、分页/过滤/排序通用约定

  1. 时间窗:全查询域以 period 为轴,另有 start_date/end_date 精确区间(API Playground 可直接生成对应参数串,官方文档口径);
  2. 过滤:维度名作查询参数直接叠加(?country=US&browser=Firefox),多值用逗号;B2B 场景的 org 级过滤同构;
  3. 排序与限额:limit(默认 100 级别,metric 端点实测支持 limit=5)+ page;
  4. 明细游标:sessions/events 列表用 cursor(hasMore + oldestTimestamp)向后翻页,适合增量导出任务(官方「Export Events to a Warehouse」指南即用此模式);
  5. 时区:所有聚合可传 timezone,缺省按站点配置/UTC。

七、常见问题

7.1 自托管有没有限流? 没有。官方文档明确自托管实例两个限流层级都不适用、也不发送 X-RateLimit-* 头(实测响应头确认无线流字段)。云版才有 burst + daily quota 双层限流。

7.2 API Key 忘记保存怎么办? 无法找回(服务端只存哈希),只能删除重建:DELETE /api/user/api-keys/:id(或看板 Settings → Account → Personal API Keys 删除)。本篇实测键在文档发布前已在实验实例中置为失效,不构成安全风险。

7.3 请求带对 Key 仍 403? 按顺序排查:① Key 是否个人键/组织键与站点归属匹配(组织键只能查本组织站点);② 创建时是否做了权限收窄(scoped 键被目标端点拒绝);③ 请求经反代时 Origin/Referer 头是否被改写(Better Auth 对会话凭据校验 Origin,纯 API Key 不受影响——实测 Bearer 调用不携带 Origin 也成功)。

7.4 metric 端点 500 是 bug 吗? v2.9.2 实测缺 parameter 参数时后端抛空指针返回 500(Cannot read properties of undefined (reading 'startsWith'),日志实测复现),补齐 type+parameter 即恢复。该错误结构仍是标准五字段 JSON,自动化集成可按 code=INTERNAL_ERROR 兜底重试或告警。

7.5 track 返回 success 但查询不到数据? 三条实测验证过的路径:① 事件进了 bot_events(站点 blockBots=true 且请求无浏览器 bot 信号,查 ClickHouse SELECT count() FROM analytics.bot_events 实锤);② 写入延迟(端到端约 6 秒:应用队列 1 秒 flush + ClickHouse 异步插入);③ 查询 period 早于事件时间(服务器时区与 timezone 参数口径)。

7.6 有官方 SDK 吗? tracker 脚本(/api/script.js,实测 33968 字节)覆盖浏览器场景;服务端/桌面端直接用 REST;移动端有 react-native SDK(源码 react-native/ 目录);AI 场景走内置 MCP 服务端(server/src/mcp,OAuth 认证与个人键共享限额)。

八、参考链接

  1. 官方 API 文档(v2.9.2 源码包 docs/content/docs/api/,含 20+ 域逐端点规范)
  2. OpenAPI 规范:v2.9.2 源码包 docs/src/app/openapi.json;云端版 https://rybbit.com/openapi.json
  3. API Playground:看板任意站点侧边栏 → API Playground
  4. 本专栏部署篇:《Rybbit Docker Compose 部署指南》(Origin/BlockBots 排障实录)
  5. 本专栏配置篇:《Rybbit 2.9.2 配置参数详解》
  6. 本专栏选型篇:《Rybbit 介绍与选型指南》
  7. 同类方案 API 参考:《Plausible API 使用详解》、《Umami 3.4 API 使用详解》