Litlyx API 使用详解

Litlyx 0.0.19 两套 API 实测详解:producer 采集端点(/event /visit /keep_alive,无认证+Shields 防护)与 dashboard 管理 API(会话登录/项目列表/统计/实时在线),请求字段表、实测响应回显、错误码与静默丢弃行为全记录。

LitlyxLitlyx网站分析产品分析2026/10/30

Litlyx API 使用详解

目标:讲清 Litlyx 0.0.19 的两套 API——producer 数据采集 API(/event、/visit、/keep_alive,无认证公开端点)与 dashboard 管理 API(登录会话 + 项目/统计接口),全部请求与响应均在本站五容器自托管栈上逐条 curl 实测,响应为实测回显。

一、环境信息

  • 操作系统:Ubuntu(x86_64);Docker 27 + Compose v2,五服务栈(部署见 《Litlyx Docker Compose 部署指南》)
  • Litlyx 版本:0.0.19(官方 litlyx/*:latest 镜像)
  • API 端点分布:
    • 采集 API:producer 服务,容器内 3001,宿主机映射 http://localhost:8135;
    • 管理 API:dashboard 服务(Nuxt 3/Nitro),容器内 3000,宿主机映射 http://localhost:8134,路由前缀 /api;
  • 测试项目:Doc Demo Site,项目 ID(pid)实测值 6ae4267da0064c0b9a6c9546;
  • 客户端工具:curl 8.x;管理员账号 admin@litlyx.local(自托管引导账号)。

二、前置条件

  1. 五服务栈运行中,dashboard 日志出现 [SELFHOSTED] Admin account OK、consumer 日志出现 Start reading loop;
  2. 已登录 dashboard 创建项目并取得 pid(项目详情页可见,或查 Mongo projects 集合 _id);
  3. curl 与 jq 可用;
  4. 明确两类端点的认证差异(见下一节),避免用管理 API 的会话去调采集端点(不需要)。

三、API 总览

域协议/形态认证方式端点
数据采集(producer)HTTP POST + JSON,请求/响应极简(无 body 成功响应)无认证(防滥用靠内置 Shields:IP 黑名单、600+ Bot UA 模式、域名白名单)POST /event、POST /visit、POST /keep_alive;兼容旧版 POST /v1/metrics/push、POST /v1/keep_alive
管理(dashboard)HTTP + JSON,Nitro 服务端路由nuxt-session Cookie(登录后下发,HttpOnly,7 天有效)POST /api/auth/login、GET /api/project/list、GET /api/project/stats、GET /api/project/live_users 等

请求处理约定(源码口径,实测验证):

  • 采集端点接收 JSON body 后不直接落库,而是压入 Redis Stream(LITLYX_STREAM),由 consumer 异步消费解析——因此 producer 返回 200 只代表消息入队成功,不代表落库成功;
  • 请求体大小限制 25KB;
  • 成功响应为空 body 的 200;被 Shields 拦截(IP 黑名单/Bot UA/域名不在白名单)返回 400 空响应;
  • 访客 IP 取请求头 X-Real-IP 或 X-Forwarded-For(按序),都缺省记 0.0.0.0——反代场景必须转发该头;
  • 会话标识由服务端计算:MD5(当日日期(it-IT 格式) + website + IP + userAgent),原始 IP 不落库(隐私设计)。

四、认证与首次调用

4.1 管理端登录(实测)

$ curl -s -D - -o /dev/null -X POST http://localhost:8134/api/auth/login \
    -H 'Content-Type: application/json' \
    -d '{"email":"admin@litlyx.local","password":"Q1w2E3r4T!"}'
HTTP/1.1 204 No Content
set-cookie: nuxt-session=Fe26.2**8b3bf6ff73b58945f8f905866aeca3b49222f80efd3cb0529f1f39add9006504*VylOabCFzJ81YQF*…; Path=/; Expires=Fri, 06 Nov 2026 06:43:45 GMT; HttpOnly; Secure; SameSite=Lax
  • 成功:204 No Content + nuxt-session Cookie(Fe26.2** 前缀为 @hapi/iron 加密格式);
  • 失败:400,响应体 {"statusCode":400,"message":"Email or Password wrong"};
  • 后续管理 API 全部用 -b cookies.txt 携带 Cookie(curl -c 保存、-b 回放)。

4.2 采集端首次调用(无需登录,实测)

$ curl -s -o /dev/null -w '%{http_code}\n' -X POST http://localhost:8135/event \
    -H 'Content-Type: application/json' \
    -d '{"pid":"6ae4267da0064c0b9a6c9546","website":"doc-demo.example.com","userAgent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 Chrome/126.0 Safari/537.36","name":"testEvent1","metadata":"{\"test\":\"something\"}"}'
200

五、数据采集 API 详解(producer)

5.1 POST /event(自定义事件)

参数类型必填说明
pidstring✅项目 ID
namestring✅(consumer 落库校验)事件名,如 click_on_buy_item
websitestring✅触发站点域名
userAgentstring✅访客 UA(服务端解析浏览器/OS/设备)
metadatastring可选JSON 字符串(非对象),如 "{\"price\":\"1.50\"}"

实测(含响应回显与落库验证):

$ curl -s -o /dev/null -w 'event:%{http_code}\n' -X POST http://localhost:8135/event \
    -H 'Content-Type: application/json' \
    -d '{"pid":"6ae4267da0064c0b9a6c9546","website":"doc-demo.example.com","userAgent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 Chrome/126.0 Safari/537.36","name":"click_download","metadata":"{}"}'
event:200

落库结果(MongoDB events 集合实测回显,session/flowHash 为服务端计算的匿名哈希):

{
  "_id": ObjectId('6ae43d03e2dcaafdd48a648e'),
  "project_id": ObjectId('6ae4267da0064c0b9a6c9546'),
  "name": "click_download",
  "session": "676bde550d1b4aa71b51400ba82c95b1",
  "flowHash": "efeb74ad83e1b42dd0ab77f67b1bb451",
  "website": "doc-demo.example.com",
  "created_at": ISODate('2026-10-30T06:45:23.576Z')
}

5.2 POST /visit(页面访问)

参数类型必填说明
pid / website / userAgentstring✅同上
browser / osstring✅(consumer 落库校验)浏览器/操作系统名(官方 litlyx.js 自动填充;自编集成必须传)
pagestring✅(同上)页面路径
referrerstring✅(同上)来源(可为空字符串,不可缺字段)
devicestring可选设备类型(desktop/mobile)
screenWidth / screenHeight / languagestring可选一律字符串,数字类型触发 500(见 5.5)

实测:

$ curl -s -o /dev/null -w 'visit:%{http_code}\n' -X POST http://localhost:8135/visit \
    -H 'Content-Type: application/json' \
    -d '{"pid":"6ae4267da0064c0b9a6c9546","website":"doc-demo.example.com","userAgent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 Chrome/126.0 Safari/537.36","browser":"Chrome","os":"Linux","device":"Desktop","page":"/docs/getting-started","referrer":"https://www.google.com/","screenWidth":"1920","screenHeight":"1080","language":"zh-CN"}'
visit:200

落库结果(MongoDB visits 集合实测回显;注意官方脚本上报时 referrer 只保留域名部分):

{
  "_id": ObjectId('6ae43d03e2dcaafdd48a6485'),
  "project_id": ObjectId('6ae4267da0064c0b9a6c9546'),
  "browser": "Chrome",
  "os": "Linux",
  "session": "676bde550d1b4aa71b51400ba82c95b1",
  "flowHash": "efeb74ad83e1b42dd0ab77f67b1bb451",
  "device": "desktop",
  "website": "doc-demo.example.com",
  "page": "/docs/getting-started",
  "referrer": "www.google.com",
  "created_at": ISODate('2026-10-30T06:45:23.529Z')
}

5.3 POST /keep_alive(在线心跳)

用于实时在线用户统计:心跳窗口 5 分钟,consumer 侧聚合出「实时在线」数。

$ curl -s -o /dev/null -w 'keep_alive:%{http_code}\n' -X POST http://localhost:8135/keep_alive \
    -H 'Content-Type: application/json' \
    -d '{"pid":"6ae4267da0064c0b9a6c9546","website":"doc-demo.example.com","userAgent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 Chrome/126.0 Safari/537.36","instant":"true"}'
keep_alive:200

instant 字段同样以字符串传输(官方脚本传布尔值经 SDK 序列化,手工集成传 "true"/"false")。

5.4 兼容端点(v1,deprecated)

源码 producer/src/deprecated.ts 保留旧版路由,功能等价、字段形态偏旧(type: 0 为访问、其余为事件):

  • POST /v1/keep_alive
  • POST /v1/metrics/push

新集成一律使用 5.1–5.3 的现行端点。

5.5 错误码与静默丢弃行为(实测)

现象实测回显根因与处置
正常上报200(空 body)入队成功,稍后落库
被 Shields 拦截(IP 在黑名单 / 开启 Bot 拦截且 UA 命中 600+ 模式 / 域名白名单不匹配)400(空 body)producer 主动拒绝,不入队
请求体含数字类型值500,body {"error":"Invalid argument type"}Redis Stream 只收字符串,把 screenWidth:1920 改为 "1920"
字段名错误(如 eventName 代替 name)或缺必填字段、pid 无效producer 仍 200,但 consumer 校验失败静默丢弃consumer 日志出现 events validation failed(缺 name)或 cast 失败;实测无效 pid 与缺 name 消息均未落库(visits/events 集合计数不变)

采集端「宽松入队、消费端严格校验」是排查「上报 200 但看板无数据」的关键:先看 consumer 日志,再核对 Mongo 集合计数。

六、Dashboard 管理 API 详解

6.1 GET /api/project/list(项目列表)

$ curl -s -b cookies.txt http://localhost:8134/api/project/list
[{"_id":"6ae4267da0064c0b9a6c9546","owner":"6ae426011d60609133f012f1","name":"Doc Demo Site","created_at":"2026-10-30T05:09:17.270Z","__v":0}]
  • 未携带有效会话:401,响应 {"error":true,"statusCode":401,"message":"Unauthorized"};
  • 返回数组按创建时间排列,无分页参数(自托管项目量小,全量返回)。

6.2 GET /api/project/stats(流量趋势)

$ curl -s -b cookies.txt 'http://localhost:8134/api/project/stats?pid=6ae4267da0064c0b9a6c9546'
{"chart":{"labels":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],"data":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,1]}}
  • 查询参数:pid(项目 ID);
  • 固定返回最近 24 小时按小时切片的访问计数(labels 为时间刻度、data 为计数,实测上报的 4 次 visit + 1 次 keep_alive 触发的访问计入末位);
  • pid 非本人项目时返回空(服务端按 owner 过滤)。

6.3 GET /api/project/live_users(实时在线)

$ curl -s -b cookies.txt -H 'x-pid: 6ae4267da0064c0b9a6c9546' \
    'http://localhost:8134/api/project/live_users?pid=6ae4267da0064c0b9a6c9546'
1
  • 同时需要两处传 pid:查询串 ?pid= 与请求头 x-pid(缺头实测报 400,message x-pid is required);
  • 返回数字:最近 5 分钟内有心跳/访问的去重会话数(实测上报后立即查询返回 1)。

6.4 其他管理端点

/api 前缀下另有 domains(域名白名单)、shields(防护配置)、timeline(明细)、snapshot、members(成员)、raw(导出)等路由组(源码 dashboard/server/api/ 目录)。自托管实践中以看板 UI 操作为主,本文覆盖的登录/项目/统计/实时四组为集成常用最小集。

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

  • 管理 API 无统一分页参数:/api/project/list 全量返回;stats 固定 24 小时窗口;明细数据在看板内通过 timeline 路由组按 pid + 时间范围查询;
  • 过滤维度(浏览器/OS/国家/页面等)在看板端聚合完成,管理 API 层不暴露;
  • 大批量数据获取建议直接读 MongoDB(只读账号):核心集合 visits/events/sessions/aggregations,按 project_id + created_at 索引查询(索引定义见源码 schema)。

八、常见问题

一、上报一直 200 但看板没数据

按序排查:① STREAM_NAME 两侧一致性;② consumer 是否存活(Start reading loop);③ consumer 日志有无 events validation failed(字段名/类型错误,见 5.5);④ Mongo 集合计数比对。配置核对方法见 《Litlyx v0.0.19 配置参数详解》。

二、cURL 模拟上报返回 500 Invalid argument type

请求体有数字/布尔类型值。Redis Stream 只接受字符串,所有值一律加引号(实测案例见部署篇常见问题五)。

三、采集端点没有认证,安全吗

设计如此:公开端点 + 无 Cookie 方案(否则无法免同意横幅)。防滥用依赖 Shields(IP 黑名单、Bot 拦截、域名白名单,看板内配置)。暴露公网时建议反代限流,并仅放行 /event、/visit、/keep_alive 路径。

四、实时在线数一直是 0

live_users 只统计最近 5 分钟有 visit 或 keep_alive 的会话;确认上报侧 UA 未命中 Bot 拦截、且查询时带了 x-pid 请求头。

五、管理 API 返回 401

会话 Cookie 缺失或失效(7 天过期 / NUXT_SESSION_PASSWORD 被更换)。重新登录获取即可,登录方式见第四章。

九、参考链接

  1. 官方 README 采集 API 示例(cURL 直报):https://github.com/litlyx/litlyx
  2. 官方文档站 SDK 文档:https://docs.litlyx.com
  3. 采集端点源码:https://github.com/litlyx/litlyx(`producer/src/index.ts`、`producer/src/deprecated.ts`)
  4. 部署与环境准备:本专栏 《Litlyx Docker Compose 部署指南》
  5. 产品认知与版本背景:本专栏 《Litlyx 介绍与选型指南》
  6. 同类平台 API 参照:《Swetrix API 使用详解》