公共 API & API 密钥
以编程方式访问工作区 — 读取项目、会话、自定义事件与细分,并为会话附加客户 ID — 通过限定工作区范围的 API 密钥保护。
1. 概览
MousePlayer API 可将工作区数据获取到自有仪表板、数据仓库或内部工具。除为会话附加客户 ID(identify,需要写入范围的密钥,见“密钥范围”)外,它是 只读的:无法通过 API 修改或删除数据。
- 基础 URL:
https://www.mouseplayer.com/api/v1/ - 所有响应均为 JSON。
- 每个请求均通过 API 密钥认证,并自动限定为该密钥所属工作区 — 某个工作区的密钥绝不可能看到其他工作区的数据,即使误操作也不会。
- 完整会话回放录制(鼠标移动、DOM 快照) 不会 通过 API 提供。可获取会话元数据、页面浏览、自定义事件与细分 — 足以构建报告和仪表板,无需传送原始回放载荷。
2. 认证
在账户菜单中的 API 密钥 (/api-keys)下创建和管理密钥。仅工作区所有者与管理员可以创建或撤销密钥。
请对密钥保密。 它授予工作区全部内容的读取权限。完整密钥仅在创建后显示一次 — 请存入密码管理器或密钥保管库。丢失后,请撤销并新建。
每个请求都应在 Authorization 请求头中以 Bearer 令牌发送密钥:
缺失、格式错误或已撤销的密钥将收到 401 响应:
套餐要求
REST API 属于 Business 和 Enterprise 套餐。套餐以工作区 所有者 为准,因此受邀团队成员继承该套餐。检查会在 每个请求执行,而非仅在创建密钥时执行 — 工作区降级后,现有密钥停止工作并返回 403。
密钥范围
每个密钥的前缀都携带范围,因此只需看一眼,就能在 .env、工单或终端中判断其能力。
| 前缀 | 含义 |
|---|---|
mp_ro_ | 只读。 读取项目、会话、事件与细分,不能更改任何内容。 |
mp_rw_ | 读取与写入。 包含上述全部功能,还可通过 identify 端点附加客户 ID。 |
403 ,消息会说明密钥具备什么范围、端点需要什么范围。范围此后不能更改 — 请新建密钥并撤销旧密钥。3. 速率限制
每个 API 密钥限制为 每分钟 60 个请求,采用滚动窗口计数。超限后,请求会收到 429 响应,直到窗口释放:
开发的功能需要更高上限?请通过 支持 联系我们,说明使用场景。
4. 端点
GET/api/v1/projects
列出工作区内全部项目(已跟踪媒体资源)。
GET/api/v1/projects/{channelid}/sessions
列出项目中录制的访客会话,最新优先,支持分页。
| 查询参数 | 说明 |
|---|---|
page | 页码,默认 1。 |
per_page | 每页结果数,默认 25,最大 100。 |
since | 仅包含于此日期或之后开始的会话(YYYY-MM-DD)。 |
until | 仅包含于此日期或之前开始的会话。 |
GET/api/v1/sessions/{session_id}
单次会话的元数据及其页面浏览。刻意不包含完整回放载荷 — 请使用仪表板的播放器查看。
GET/api/v1/sessions/{session_id}/events
会话期间触发的自定义事件(即通过 mp('event', ...)发送的同一批事件),包含其参数。
GET/api/v1/projects/{channelid}/segments
列出为项目定义的访客细分(包括项目专属与工作区范围的细分)。
5. 从后端附加客户 ID
浏览器往往不知道使用者是谁。B2B 产品的身份在登录后于后端确定 — 商店则在订单确认时确定。此端点正是为那一刻准备的。
POST /api/v1/sessions/{session_id}/identify
Authorization: Bearer mp_live_xxxxxxxxxxxx
Content-Type: application/json
{"user_id": "customer-4711"}
// 200 OK
{"data": {"session_id": "s_a1b2c3", "user_id": "customer-4711",
"changed": true, "previous": null, "webhook_queued": true}}ID 随后显示在会话列表中且可搜索,同时触发 session_identified Webhook — 从而传入 CRM。
"changed": false ,且不发送 Webhook。重复订单不会创建第二条潜在客户记录。| 状态 | 情况 |
|---|---|
400 | 字段缺失、 user_id 超过 128 个字符,或含控制字符。我们拒绝而非截断 — 悄悄缩短的 ID 在 CRM 中什么也匹配不到,却仍看起来像成功。 |
404 | 会话不存在 或 不属于您的工作区。两者刻意返回相同答复。 |
403 | 工作区套餐不包含 API。 |
6. Webhook:验证签名
Webhook 按项目在 集成下配置,签名密钥也在其中。每次投递都携带以下请求头:
| 请求头 | 含义 |
|---|---|
X-MousePlayer-Event | 事件名称,例如 session_identified |
X-MousePlayer-Timestamp | Unix 秒数 — 属于签名文本的一部分 |
X-MousePlayer-Attempt | 首次尝试为 1,重试时递增 |
X-MousePlayer-Signature | sha256=<hex> |
签名是针对 timestamp + "." + raw body计算的 HMAC-SHA256,以项目签名密钥为键。
// PHP $erwartet = 'sha256=' . hash_hmac('sha256', $timestamp . '.' . $rawBody, $secret); if (!hash_equals($erwartet, $signature)) { http_response_code(401); exit; } // Node const expected = 'sha256=' + crypto.createHmac('sha256', secret) .update(timestamp + '.' + rawBody).digest('hex');
投递与重试
投递失败后,将在 1 分钟、5 分钟、15 分钟、1 小时和 6 小时后重试,随后放弃。 4xx 响应中,除 408 和 429 以外的均 不会 重试 — 它们表示 "不能这样请求",而非 "暂时不能请求"。请快速返回 2xx ,再处理工作;投递会在 10 秒后超时。
可用事件
| 事件 | 触发时机 |
|---|---|
session_identified | 会话首次获得客户 ID 时 — 无论来自浏览器还是 API |
session_ended | 会话关闭时,一次 |
goal_reached | 自定义事件达成某个目标时,每次会话一次。 仅限“事件”类型目标 — 不评估 URL、时长、页面浏览或漏斗目标。携带 goal_id、 goal_name、 goal_value 和 currency。 |
high_value_session | 访客在某一天首次超过此项目的价值阈值时。阈值 源自您自己的评分分布 (最近 90 天的第 90 百分位),而非固定值;至少有 20 名访客获得评分后才存在。携带 visitor_id、 value_score、 threshold 以及当天最值得观看的会话。 |
funnel_dropoff | 会话进入某个漏斗却未完成时,在会话结束时触发。标明停止的步骤(dropped_at)。流失意味着缺少事件,因此只能在会话结束后确定。从未进入漏斗的会话不属于流失,不会触发。 |
high_friction_session | 每次会话中,摩擦评分首次达到阈值(默认 100 分中的 60 分)时触发一次。携带 friction_score、其背后的信号(reasons)以及越过阈值的信号(trigger)。 |
element_broken | 跟踪的元素连续数日在所有已检查页面浏览中均未找到匹配时,触发一次 — 通常发生在网站改版后。只有标记再次匹配、然后再次失效,才会重新触发。此事件 不属于任何会话: session_id 和 session_url 为 null, link_url 改为打开标记,而 subject_id 标识该标记 — 所有版本相同,因此新选择器再次失效时会关联到尚未解决的同一事件。携带 rule_id、 rule_name、 selector、 page、 checked_page_views、 window_days 和 last_matched。不含访客数据。 |
element_recovered | 以下事件的恢复通知: element_broken:标记确实再次找到元素时触发 — 页面浏览太少不算恢复。仅当 element_broken 已经通过 Webhook 发出时才发送,且没有单独开关:订阅 element_broken 即包含它。使用相同的 subject_id,使 PagerDuty 解决事件、Opsgenie 关闭警报。另携带 matched_page_views 和 checked_page_views 。 |
anomaly_detected | 当昨天与此前 28 天明显不同时,每天一次:会话显著减少或增加、目标达成率下降、存在摩擦或 JS 错误的会话增多。同一指标与方向会静默一周(可调整)。此事件 不属于任何会话: session_id 和 session_url 为 null, link_url 打开项目概览,而 subject_id 标识指标、方向与日期。携带 metric (sessions、 goal_rate、 friction_rate、 js_error_rate、 lcp_p75、 inp_p75、 cls_p75)、 direction、 day、 value、 expected、 sessions、 robust_z、 z_score 以及可读的 summary 和 hint。不含访客数据。对于 Web Vitals, measurements 替代 sessions,而 page (整个站点时为空)与 device (desktop 或 mobil)说明发生位置; link_url 此时打开 Web Vitals 标签页。 |
rage_click | 检测到愤怒点击时 |
error_detected | 发生前端异常时 |
ce | 对您自己的自定义事件进行统一订阅。它 不 包含上述事件 — 那些事件有各自的开关。 |
7. 错误 & 状态码
| 状态 | 含义 |
|---|---|
200 | 成功。 |
401 | API 密钥缺失、格式错误或已撤销。 |
404 | 请求的项目或会话不存在,或不属于您的工作区。 |
429 | 超出速率限制 — 此密钥每分钟发送超过 60 个请求。 |
403 | 工作区套餐不包含 REST API。消息会列出所需套餐和当前套餐。 |
8. 安全说明
- 只读密钥(mp_ro_)不能更改任何内容。写入密钥(mp_rw_)只能附加客户 ID;任何密钥都无法删除数据或导出原始回放数据。
- 每个请求自动限定在密钥所属工作区 — 无法传入其他工作区 ID 查看他人数据。
- 可随时在 /api-keys撤销密钥,立即生效。
- 将 API 密钥视作密码。如果意外提交到公共仓库,请立即撤销并新建。
有界事件分页(API v1,2026 年 10 月 14 日)
GET /api/v1/sessions/{session_id}/events 默认最多返回 100 个事件。将 per_page 设置为 1 至 100 的整数。按照 pagination.next_cursor 翻页,在下一个请求中原样发送 cursor,保持同一会话与工作区。事件按 created_at 和 event_id 排序。游标经签名并绑定该会话与工作区。不返回总数或数字页码。
现有 data 数组与 params 映射保持可用。pagination.returned 是实际返回数量;pagination.has_more 表示还有下一页。完成时 next_cursor 为 null。响应上限为 524288 字节,因此一页的事件数可能少于 per_page。每个事件最多返回 128 条参数记录;存在更多参数时 params_truncated 为 true。单个字符串参数仍遵守数据库的 255 字符限制。截断的参数无法通过此端点获取。减少 per_page 不会提高参数上限。
无效页大小、被篡改的游标,以及属于其他会话/工作区的游标,均返回 400。单个事件数据过大返回 413。现有访问检查仍按情况返回 401、403、404 或 409。
上限仍为每个 API 密钥每分钟 60 个已认证请求。耗尽时返回 429,并附 Retry-After: 60。如果 Redis 或限流器不可用,请求返回 503,并附 Retry-After: 5;绝不会无限制放行。请遵守 Retry-After,并增加随机退避;不要紧密循环重试。事件数据库故障也返回 503。游标不会冻结快照:并发插入较早时间戳的数据可能需要重新扫描。
GET /api/v1/sessions/s_example/events?per_page=25 GET /api/v1/sessions/s_example/events?per_page=25&cursor=SIGNED_CURSOR
/api/v1/native 是原生 SDK 预览的仅 Dev 后端控制路径,在生产环境仍被禁用。后端 Bearer 密钥对 list/replay 需要读取范围,对 register/grant/delete/disable 需要写入范围。另有原生预览可用性检查。绝不要将永久工作区 API 密钥嵌入移动应用。