Wakapi 2.18.2 API 使用详解
Wakapi 2.18.2 REST API 实测详解:Basic/API Key 认证、heartbeats 上报(单条与批量)、summaries/stats/durations 统计查询、徽章与指标端点,全部 curl 命令附真实响应。
Wakapi 2.18.2 API 使用详解
目标:用 curl 实测 Wakapi 2.18.2 的核心 API——认证、心跳上报、统计查询、徽章与指标,让读者能独立对接自有脚本或排查客户端接入问题。本文已在 Ubuntu 22.04 的 Wakapi 2.18.2(SQLite)实例上逐条实测通过。
说明:Wakapi 服务端二进制仅有
-config/-version两个命令行参数(实测--help输出仅此两项),不存在独立的 CLI 子命令体系,其全部能力以 HTTP API 暴露,故本专题按「API 使用详解」组织。
一、环境信息
- 服务端:Wakapi 2.18.2,监听
0.0.0.0:3000,SQLite 存储 - 演示账号:
admin/q1w2e3r4(Web 注册创建) - 演示 API Key:
51eb5817-e0e9-44ef-9644-43999eb962b3(Settings 页获取) - 客户端工具:curl 7.81.0(Ubuntu 22.04 自带)
- 官方 Swagger 文档:https://wakapi.dev/swagger-ui
二、前置条件
- Wakapi 2.18.2 已运行且
curl http://127.0.0.1:3000/api/health返回 200(部署见《Ubuntu 22.04 安装 Wakapi 2.18.2 指南》); - 已注册账号并取得 API Key(登录 Web → Settings 页展示)。
三、API 总览
Wakapi 的 API 分两层:
| 层 | 路径前缀 | 说明 |
|---|---|---|
| 自有 API | /api/* | Wakapi 原生能力(健康、徽章、指标、心跳等) |
| WakaTime 兼容 API | /api/compat/wakatime/v1/* | 协议兼容 WakaTime 官方 API,供 wakatime-cli 及第三方工具直接对接 |
认证方式(三种,实测以第一种为主):
- Basic + Base64(API Key):
Authorization: Basic <base64(api_key)>,WakaTime 同款,最常用; - Query 参数:
?api_key=<明文 API Key>,适合快速调试; - Cookie:Web 登录后的
wakapi_session/wakapi_authCookie,仅限浏览器场景。
⚠️ 注意:自 2.18.0 起 API Key 仅对
/api前缀路由有效(官方安全修复,breaking change),不能再拿 API Key 访问 Web 页面路由。
生成认证头:
echo -n 51eb5817-e0e9-44ef-9644-43999eb962b3 | base64
实测回显:
NTFlYjU4MTctZTBlOS00NGVmLTk2NDQtNDM5OTllYjk2MmIz
四、认证与首次调用
健康检查(无需认证):
curl -s -o /dev/null -w 'HTTP %{http_code}\n' http://127.0.0.1:3000/api/health
curl -s http://127.0.0.1:3000/api/health
实测回显:
HTTP 200
app=1
db=1
app=1 db=1 表示应用与数据库均可用;db=0 时表示数据库连接异常。
查询当前用户(WakaTime 兼容层):
curl -s -H "Authorization: Basic NTFlYjU4MTctZTBlOS00NGVmLTk2NDQtNDM5OTllYjk2MmIz" \
http://127.0.0.1:3000/api/compat/wakatime/v1/users/current
实测回显(节选):
{"data":{"id":"admin","display_name":"admin","full_name":"","email":"admin@example.org","is_email_public":false,"is_email_confirmed":false,"timezone":"UTC","last_heartbeat_at":"0001-01-01T00:00:00Z","last_project":"","last_plugin_name":"","username":"admin","website":"","created_at":"2026-10-25T01:38:21.784Z","modified_at":"2026-10-25T01:38:21.784Z","photo":"http://10.89.62.10:3000/api/avatar/21232f297a57a5a743894a0e4a801fc3.svg"}}
能拿到用户 JSON 即说明认证链路通了。
五、各 API 域详解
5.1 上报心跳(单条)
心跳是 Wakapi 的核心数据:客户端每次编辑动作上报一条。端点为 POST /api/heartbeat(自有层):
NOW=$(date +%s)
curl -s -o /dev/null -w 'hb %{http_code}\n' -X POST http://127.0.0.1:3000/api/heartbeat \
-H "Authorization: Basic NTFlYjU4MTctZTBlOS00NGVmLTk2NDQtNDM5OTllYjk2MmIz" \
-H 'Content-Type: application/json' \
-d '{"entity":"/home/admin/projects/demo/main.go","type":"file","category":"coding","time":'"$NOW"'.0,"project":"demo-project","language":"Go","editor":"vscode","operating_system":"linux","machine":"devbox","is_write":true}'
实测回显:hb 201(每条创建成功返回 201)。
字段说明:entity 文件路径、type 固定 file、category 如 coding、time 为 Unix 秒(浮点)、project/language/editor/operating_system/machine 为统计维度、is_write 表示是否真实写入(区别于只读浏览)。注意 app.heartbeat_max_age 默认 4320h,超龄心跳会被拒收。
5.2 上报心跳(批量,WakaTime 兼容层)
wakatime-cli 实际使用的是批量端点 heartbeats.bulk:
NOW=$(date +%s)
curl -s -w '\nHTTP %{http_code}\n' -X POST \
'http://127.0.0.1:3000/api/compat/wakatime/v1/users/current/heartbeats.bulk' \
-H "Authorization: Basic NTFlYjU4MTctZTBlOS00NGVmLTk2NDQtNDM5OTllYjk2MmIz" \
-H 'Content-Type: application/json' \
-d '[{"entity":"/home/admin/projects/demo/util.py","type":"file","category":"coding","time":'"$((NOW-300))"'.0,"project":"demo-project","language":"Python","editor":"vscode","operating_system":"linux","machine":"devbox","is_write":true},{"entity":"/home/admin/projects/demo/util.py","type":"file","category":"coding","time":'"$((NOW-240))"'.0,"project":"demo-project","language":"Python","editor":"vscode","operating_system":"linux","machine":"devbox","is_write":true}]'
实测回显:
{"responses":[[{"data":null,"error":null},201],[{"data":null,"error":null},201]]}
HTTP 201
responses 数组与请求数组一一对应,每条内部为 [{data,error}, 状态码]。
5.3 查询心跳明细
curl -s -H "Authorization: Basic NTFlYjU4MTctZTBlOS00NGVmLTk2NDQtNDM5OTllYjk2MmIz" \
"http://127.0.0.1:3000/api/compat/wakatime/v1/users/current/heartbeats?date=$(date +%F)"
实测回显(节选,展示第 1 条):
{"data":[{"id":"1","branch":"","category":"coding","entity":"/home/admin/projects/demo/main.go","is_write":true,"language":"Go","project":"demo-project","time":1792891735,"type":"file","user_id":"admin","machine_name_id":"devbox","user_agent_id":"curl/7.81.0","lines":0,"lineno":0,"cursorpos":0,"line_deletions":0,"line_additions":0,"created_at":"2026-10-25T01:38:55.611Z","ai_line_changes":0,...}]}
记录包含 WakaTime 标准字段外,还含 Wakapi 2.18 新增的 AI 编程相关字段(ai_line_changes、ai_input_tokens 等)。
5.4 日汇总(summaries)
按天聚合的多维统计(仪表盘的数据源):
curl -s -H "Authorization: Basic NTFlYjU4MTctZTBlOS00NGVmLTk2NDQtNDM5OTllYjk2MmIz" \
"http://127.0.0.1:3000/api/compat/wakatime/v1/users/current/summaries?start=$(date +%F)&end=$(date +%F)"
实测回显(节选):
{"data":[{"categories":[{"digital":"0:4:0","hours":0,"minutes":4,"name":"coding","percent":100,"seconds":0,"text":"0 hrs 4 mins","total_seconds":240}],"editors":[...],"languages":[{"digital":"0:4:0","name":"Go","percent":100,...}],"machines":[{"name":"devbox",...}],"projects":[{"digital":"0:4:0","name":"demo-project","percent":100,...}],"grand_total":{"digital":"0:4","hours":0,"minutes":4,"text":"0 hrs 4 mins","total_seconds":240},"range":{"date":"2026-10-25T01:39:10Z","start":"2026-10-25T00:00:00Z","timezone":"UTC"}}]}
data[] 每天一项,内含 categories/editors/languages/machines/operating_systems/projects 六个维度的时长拆分。
5.5 区间统计(stats)
curl -s -H "Authorization: Basic NTFlYjU4MTctZTBlOS00NGVmLTk2NDQtNDM5OTllYjk2MmIz" \
"http://127.0.0.1:3000/api/compat/wakatime/v1/users/current/stats/last_7_days"
实测回显(节选):
{"data":{"username":"admin","user_id":"admin","status":"ok","total_seconds":240,"range":"last_7_days","human_readable_range":"Last 7 Days","human_readable_total":"0 hrs 4 mins","editors":[...],"languages":[{"name":"Go","percent":100,...}],...}}
区间取值与 WakaTime 一致:last_7_days、last_30_days、last_6_months、last_year、all_time。
5.6 累计编码时长(all_time_since_today)
curl -s -H "Authorization: Basic NTFlYjU4MTctZTBlOS00NGVmLTk2NDQtNDM5OTllYjk2MmIz" \
http://127.0.0.1:3000/api/compat/wakatime/v1/users/current/all_time_since_today
实测回显:
{"data":{"total_seconds":300,"text":"0 hrs 5 mins","is_up_to_date":true,"range":{"end":"2026-10-25T01:47:38Z","end_date":"2026-10-25","start":"2026-10-25T01:28:55Z","start_date":"2026-10-25","timezone":"UTC"}}}
5.7 徽章(badge)
生成可嵌入 README 的 SVG 徽章:
curl -s -o /dev/null -w '%{http_code} %{content_type}\n' \
'http://127.0.0.1:3000/api/badge/admin/interval:today'
实测回显(未开启公开分享时):
403 text/plain; charset=utf-8
徽章要求用户在 Settings 中公开对应统计维度,否则返回 403;开启后返回 image/svg+xml。
5.8 Prometheus 指标
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:3000/api/metrics
默认实测回显:404——需配置 security.expose_metrics: true(或 WAKAPI_EXPOSE_METRICS=true)并重启后开放。
六、分页/过滤/排序通用约定
- 心跳明细按
date(YYYY-MM-DD)过滤;汇总类按start/end日期区间过滤; - WakaTime 兼容层响应统一包在
{"data": ...}内,错误时返回对应 HTTP 状态码与error字段; - 限流:注册/登录/密码重置有固定速率(实测注册响应头
X-Ratelimit-Limit: 5、X-Ratelimit-Remaining: 4),数据 API 默认不限流。
七、客户端接入示例(wakatime-cli)
编辑器插件统一读 ~/.wakatime.cfg:
[settings]
api_url = http://10.89.62.10:3000/api
api_key = 51eb5817-e0e9-44ef-9644-43999eb962b3
想让 WakaTime 官方与 Wakapi 同时接收数据(双写),用 [api_urls] 段配置多目标(规则见 wakatime-cli 的 USAGE 文档);Wakapi 侧 Settings → Integrations 也支持服务端 relay 转发到 WakaTime。
八、常见问题
Q1:调用返回 401 Unauthorized?
先确认 header 里是 Base64 后的 API Key(不是明文);再确认路径在 /api 前缀下——2.18.0 起 API Key 对 Web 路由一律无效。
Q2:上报返回 201 但仪表盘没数据?
仪表盘读的是汇总(summary)数据,聚合任务定时执行(默认凌晨 2:15,见配置详解 aggregation_time)。可通过 summaries 接口确认数据是否已聚合;grand_total 有值即正常。
Q3:心跳被拒收?
检查 time 字段是否为 Unix 秒(不是毫秒)且未超过 app.heartbeat_max_age(默认 180 天)。
Q4:自有 API 和兼容 API 用哪个?
对接 wakatime-cli/第三方工具用兼容层;自研脚本两者皆可,兼容层字段与 WakaTime 官方文档对齐,资料更多。
九、参考链接
- Wakapi Swagger 交互式 API 文档:https://wakapi.dev/swagger-ui
- WakaTime API 官方文档(兼容层协议基准):https://wakatime.com/developers
- Wakapi 仓库 README(认证机制与集成):https://github.com/muety/wakapi
- wakatime-cli 配置参考:https://github.com/wakatime/wakatime-cli/blob/develop/USAGE.md