Artalk REST API 使用详解(v2.10.0)

Artalk v2.10.0 REST API 使用详解:基于官方 OpenAPI 规范梳理全部 44 个端点,以 curl 实测打通认证、评论增删改查与回复嵌套、分页列表、页面与站点管理、用户权限、通知与统计、验证码与缓存接口,完整收录缺字段、未授权、不存在、需验证码等错误场景的逐字回显,附错误码速查表与排障要点。

Artalk2026/10/19

二、前置条件

目标: 用 curl 打通 Artalk v2.10.0 的 REST API 全流程:匿名评论提交、回复嵌套、分页列表、管理员登录与鉴权、页面/站点/用户管理、通知与统计,并把每个错误场景(缺字段、未授权、不存在、需验证码)的原始回显完整实录,作为二开与自动化的对接手册。组件定位见Artalk v2.10.0 介绍与选型指南,服务部署见Artalk Docker Compose 部署实战(v2.10.0),参数含义见Artalk 配置参数详解(v2.10.0)。

‍‍​​‌​# 一、环境信息

项目内容
服务版本Artalk v2.10.0(commit 1bf2140,GET /api/v2/version 实测确认)
服务地址http://127.0.0.1:8119(本环境监听端口;二进制默认 23366,按部署方案而定)
API 前缀/api/v2(所有接口挂载在该前缀下)
接口规范官方 OpenAPI 文档 https://artalk.js.org/http-api.html ,共 44 个端点
实测客户端curl/7.81.0(响应中 ua 字段如实记录)
管理员账号admin@example.com / 口令 q1w2e3r4(部署时创建)
默认站点「Artalk 的博客」(站点 URL http://192.168.146.128:8119)
实测日期2026-10-19
  1. 服务已启动且版本接口可达:
$ curl -s http://127.0.0.1:8119/api/v2/version
{"app":"artalk","version":"2.10.0","commit_hash":"1bf2140"}
[HTTP 200]
  1. 管理员账户已创建(部署篇第四节);
  2. 验证码注意:默认配置 captcha.enabled: true 且同一客户端连续 3 次写操作(action_limit: 3)后会强制验证码,API 直调同样命中(实测见第五节)。脚本化压测前可临时关闭;
  3. 多数写操作(评论/页面 PV 等)要求携带 Origin 头且为已信任域名(trusted_domains),本环境将 http://192.168.146.128:8119 配为可信域,故统一加 -H 'Origin: http://192.168.146.128:8119'。

三、API 总览

以下 44 个端点按功能域归组(与官方 OpenAPI 规范一致):

功能域端点鉴权
系统GET /version、GET /settings、GET /conf、GET /conf/domainversion/conf 公开;settings 需管理员
认证POST /auth/email/login、POST /auth/email/register、POST /auth/email/apply_code、POST /auth/emails/...、GET /auth/providers、GET /auth/{provider}、GET /auth/{provider}/callback登录/注册公开
用户GET /user、POST /user/access_token、GET /users/{type}、POST /users、PUT /users/{id}读取登录态/管理员
评论GET /comments、POST /comments、GET /comments/{id}、PUT /comments/{id}、DELETE /comments/{id}、GET /comments/{id}/vote/{up_or_down}、POST /comments/{id}/vote/{up_or_down}、GET /pages/{id}/vote/{up_or_down}、POST /pages/{id}/vote/{up_or_down}读公开;写需登录/管理员
页面GET /pages、GET /pages/{id}、PUT /pages/{id}、DELETE /pages/{id}、POST /pages/fetch、POST /pages/sync、POST /pages/pv管理员(pv 公开)
站点GET /sites、POST /sites、GET /sites/{id}、PUT /sites/{id}、DELETE /sites/{id}列表公开,管理需管理员
通知GET /notifies、POST /notifies/read需登录
统计GET /stats/{type}公开
验证码GET /captcha、GET /captcha/status、POST /captcha/verify、GET /captcha/preset公开(按配置)
缓存GET /cache/status、POST /cache/warm_up、POST /cache/flush管理员
迁移/上传POST /transfer、POST /upload管理员/公开

统计接口 type 取值:latest_comments、latest_pages、pv_most_pages、comment_most_pages、page_pv、site_pv、page_comment、site_comment、rand_comments、rand_pages。

四、认证与首次调用

1. 邮箱登录获取令牌

$ curl -s -X POST http://127.0.0.1:8119/api/v2/auth/email/login \
    -H 'Content-Type: application/json' \
    -d '{"email":"admin@example.com","password":"q1w2e3r4"}'

响应携带 JWT(实测长度 144 字符,形如 eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoxLCJleHAi...)。之后所有鉴权请求带 Authorization: Bearer <token>。

2. 获取当前登录态(三种状态实录)

$ curl -s http://127.0.0.1:8119/api/v2/user -H "Authorization: Bearer $TOKEN"
{"user":{"id":1,"name":"admin","email":"admin@example.com","link":"","badge_name":"管理员","badge_color":"#0083FF","is_admin":true,"receive_email":true},"is_login":true,"notifies":[{"id":1,"user_id":1,"comment_id":1,"is_read":false,"is_emailed":false,"read_link":"http://192.168.146.128:8119/post/hello.html?atk_comment=1&atk_notify_key=H4YAO"},{"id":2,"user_id":1,"comment_id":2,"is_read":false,"is_emailed":false,"read_link":"http://192.168.146.128:8119/post/hello.html?atk_comment=2&atk_notify_key=1WAJE"}],"notifies_count":2}
[HTTP 200]

不带 token 与携带非法 token 的回显完全相同(注意:HTTP 状态码仍是 200,需要检查 is_login 字段而不是状态码):

$ curl -s http://127.0.0.1:8119/api/v2/user
{"user":null,"is_login":false,"notifies":[],"notifies_count":0}
[HTTP 200]
$ curl -s http://127.0.0.1:8119/api/v2/user -H 'Authorization: Bearer invalid.token.here'
{"user":null,"is_login":false,"notifies":[],"notifies_count":0}
[HTTP 200]

3. 长期访问令牌

$ curl -s -X POST http://127.0.0.1:8119/api/v2/user/access_token \
    -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
    -d '{"email":"admin@example.com","password":"q1w2e3r4"}'
{"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoxLCJleHAiOjE3OTI2NTU5ODEsImlhdCI6MTc5MjM5Njc4MX0.xjA3G0rf6dzffS5cpxC6R-lhJPc4UNQk3HcYk2gQDek","user":{"id":1,"name":"admin","email":"admin@example.com","link":"","badge_name":"管理员","badge_color":"#0083FF","is_admin":true,"receive_em..."}
[HTTP 200]

(exp 为长期过期时间,适合脚本常驻;缺 email 字段时报 {"msg":"邮箱必须填写"}。)

五、评论域详解

1. 提交评论(匿名)

$ curl -s -X POST http://127.0.0.1:8119/api/v2/comments \
    -H 'Content-Type: application/json' \
    -H 'Origin: http://192.168.146.128:8119' \
    -d '{"page_key":"/post/hello.html","page_title":"你好 Artalk","name":"张三","email":"zhangsan@example.com","content":"这是 Artalk 的第一条测试评论!","site_name":"Artalk 的博客"}'
{"id":12,"content":"这是 Artalk 的第一条测试评论!","content_marked":"\u003cp\u003e这是 Artalk 的第一条测试评论!\u003c/p\u003e\n","user_id":2,"nick":"张三","email_encrypted":"55370d314c3ba8e628a5cc44f26470a9d3b1e29163779513636e58ca926eb55e","link":"","ua":"curl/7.81.0","date":"2026-10-19 15:54:46","is_collapsed":false,"is_pending":false,"is_pinned":false,"is_allow_reply":true,"is_verified":false,"rid":0,"badge_name":"","badge_color":"","visible":true,"vote_up":0,"vote_down":0,"page_key":"/post/hello.html","page_url":"http://192.168.146.128:8119/post/hello.html","site_name":"Artalk 的博客"}
[HTTP 200]

要点:page_key 为页面唯一键;不存在的页面/站点会按需自动创建(站点名必须已存在或为默认站点);email 会加密哈希后回显(email_encrypted);content_marked 为服务端渲染后的 HTML。

2. 回复评论(rid,不是 reply_id)

回复关系字段为 rid(父评论 id)。首次实测误用 reply_id 字段时评论创建成功但 rid 恒为 0(不报错),换 rid 后回显正确建立关系:

$ curl -s -X POST http://127.0.0.1:8119/api/v2/comments \
    -H 'Content-Type: application/json' -H 'Origin: http://192.168.146.128:8119' \
    -d '{"page_key":"/post/hello.html","name":"李四","email":"lisi@example.com","content":"欢迎欢迎,回复楼上的评论","rid":12,"site_name":"Artalk 的博客"}'
{"id":13,"content":"欢迎欢迎,回复楼上的评论","content_marked":"\u003cp\u003e欢迎欢迎,回复楼上的评论\u003c/p\u003e\n","user_id":3,"nick":"李四","email_encrypted":"49dd404cd6076f6ad6c58624b8159654da6105777072448473921a02878759b5","link":"","ua":"curl/7.81.0","date":"2026-10-19 15:55:04","is_collapsed":false,"is_pending":false,"is_pinned":false,"is_allow_reply":true,"is_verified":false,"rid":12,"badge_name":"","badge_color":"","visible":true,"vote_up":0,"vote_down":0,"pa...
[HTTP 200]

GET /comments/{id} 详情接口同时返回 reply_comment(父评论对象,顶层评论时为 null)。

3. 评论列表与分页

page_key 为必填参数,缺失即 400:

$ curl -s http://127.0.0.1:8119/api/v2/comments
{"msg":"Page_key必须填写"}
[HTTP 400]

嵌套模式(默认,limit=1 实测,返回最新根评论与页面信息):

$ curl -s "http://127.0.0.1:8119/api/v2/comments?site_name=Artalk%20%E7%9A%84%E5%8D%9A%E5%AE%A2&page_key=/post/hello.html&limit=1"
{"comments":[{"id":12,"content":"这是 Artalk 的第一条测试评论!","content_marked":"...","user_id":2,"nick":"张三",...,"rid":0,...}],"count":3,"roots_count":3,"page":{"id":1,"admin_only":false,"key":"/post/hello.html","url":"http://192.168.146.128:8119/post/hello.html","title":"你好 Artalk(标题已改)","site_name":"Artalk 的博客","vote_up":0,"vote_down":0,"pv":1,"date":"2026-10-19 15:09:04"}}
[HTTP 200]

平铺模式(flat_mode=true,全部评论按时间倒序一条数组返回,便于脚本处理):

$ curl -s "http://127.0.0.1:8119/api/v2/comments?site_name=Artalk%20%E7%9A%84%E5%8D%9A%E5%AE%A2&page_key=/post/hello.html&flat_mode=true&limit=10&page=0"
{"comments":[{"id":12,...},{"id":2,...}],"count":2,"roots_count":2,"page":"你好 Artalk",...}
[HTTP 200]

分页语义实测:page 从 0 开始,limit 控制每页条数(如 limit=1 每页一条);响应 count/roots_count 为总数(评论数/根评论数),可用于客户端翻页。

4. 编辑评论(管理员,必须携带全部字段)

先给两个真实的缺字段报错——site_name 与 is_collapsed 缺一即 400:

$ curl -s -X PUT http://127.0.0.1:8119/api/v2/comments/13 -H "Authorization: Bearer $TOKEN" \
    -H 'Content-Type: application/json' \
    -d '{"content":"欢迎欢迎(管理员已修正内容)","nick":"李四","email":"lisi@example.com"}'
{"msg":"Site_name必须填写"}
[HTTP 400]
$ curl -s -X PUT http://127.0.0.1:8119/api/v2/comments/13 -H "Authorization: Bearer $TOKEN" \
    -H 'Content-Type: application/json' \
    -d '{"content":"欢迎欢迎(管理员已修正内容)","nick":"李四","email":"lisi@example.com","site_name":"Artalk 的博客","page_key":"/post/hello.html","rid":12}'
{"msg":"Is_collapsed必须填写"}
[HTTP 400]

补齐全部字段(content/nick/email/site_name/page_key/rid/is_pinned/is_collapsed/is_pending)后成功:

$ curl -s -X PUT http://127.0.0.1:8119/api/v2/comments/13 -H "Authorization: Bearer $TOKEN" \
    -H 'Content-Type: application/json' \
    -d '{"content":"欢迎欢迎(管理员已修正内容)","nick":"李四","email":"lisi@example.com","site_name":"Artalk 的博客","page_key":"/post/hello.html","rid":12,"is_pinned":false,"is_collapsed":false,"is_pending":false}'
{"id":13,"content":"欢迎欢迎(管理员已修正内容)","content_marked":"...","user_id":3,"nick":"李四",...,"is_collapsed":false,"is_pending":false,"is_pinned":false,...}
[HTTP 200]

is_pending 即审核状态位:配合Artalk 配置参数详解(v2.10.0)的 pending_default,先用 POST 拿到 is_pending: true 的待审评论,再以此 PUT 放行,可完全用 API 实现「先审后放」流水线。

5. 删除评论(管理员)

$ curl -s -X DELETE http://127.0.0.1:8119/api/v2/comments/12 -H "Authorization: Bearer $TOKEN"
{"msg":"Success"}
[HTTP 200]
$ curl -s -X DELETE http://127.0.0.1:8119/api/v2/comments/14 -H "Authorization: Bearer $TOKEN"
{"msg":"评论未找到"}
[HTTP 404]
$ curl -s -X DELETE http://127.0.0.1:8119/api/v2/comments/12
{"msg":"需要管理员权限","need_login":true}
[HTTP 403]

删除成功回显 {"msg":"Success"};目标不存在返回 404「评论未找到」(与 GET 详情的 404 一致:GET /api/v2/comments/99999 → {"msg":"评论未找到"} [HTTP 404]);无凭据返回 403 且响应体带 need_login:true。

六、页面与站点管理

1. 页面列表与编辑

$ curl -s "http://127.0.0.1:8119/api/v2/pages?site_name=Artalk%20%E7%9A%84%E5%8D%9A%E5%AE%A2" -H "Authorization: Bearer $TOKEN"
{"count":1,"pages":[{"id":1,"admin_only":false,"key":"/post/hello.html","url":"http://192.168.146.128:8119/post/hello.html","title":"你好 Artalk(标题已改)","site_name":"Artalk 的博客","vote_up":0,"vote_down":0,"pv":1,"date":"2026-10-19 15:09:04"}]}
[HTTP 200]
$ curl -s -X PUT http://127.0.0.1:8119/api/v2/pages/1 -H "Authorization: Bearer $TOKEN" \
    -H 'Content-Type: application/json' \
    -d '{"title":"你好 Artalk(标题已改)","key":"/post/hello.html","site_name":"Artalk 的博客","admin_only":false}'
{"id":1,"admin_only":false,"key":"/post/hello.html","url":"http://192.168.146.128:8119/post/hello.html","title":"你好 Artalk(标题已改)","site_name":"Artalk 的博客","vote_up":0,"vote_down":0,"pv":1,"date":"2026-10-19 15:09:04"}
[HTTP 200]

2. 页面 PV 上报

$ curl -s -X POST http://127.0.0.1:8119/api/v2/pages/pv \
    -H 'Content-Type: application/json' -H 'Origin: http://192.168.146.128:8119' \
    -d '{"page_key":"/post/hello.html","page_title":"你好 Artalk","site_name":"Artalk 的博客"}'
{"pv":2}
[HTTP 200]

3. 站点增删改查

$ curl -s http://127.0.0.1:8119/api/v2/sites -H "Authorization: Bearer $TOKEN"
{"sites":[{"id":1,"name":"Artalk 的博客","urls":["http://192.168.146.128:8119"],"urls_raw":"http://192.168.146.128:8119","first_url":"http://192.168.146.128:8119"},{"id":2,"name":"Docs 站点(已更名)","urls":["https://docs.example.com","https://wiki.example.com"],"urls_raw":"https://docs.example.com,https://wiki.example.com","first_url":"https://docs.example.com"}],"count":2}
[HTTP 200]
$ curl -s -X POST http://127.0.0.1:8119/api/v2/sites -H "Authorization: Bearer $TOKEN" \
    -H 'Content-Type: application/json' \
    -d '{"name":"Docs 站点","urls":["https://docs.example.com"]}'
{"id":3,"name":"Docs 站点","urls":["https://docs.example.com"],"urls_raw":"https://docs.example.com","first_url":"https://docs.example.com"}
[HTTP 200]
$ curl -s -X PUT http://127.0.0.1:8119/api/v2/sites/2 -H "Authorization: Bearer $TOKEN" \
    -H 'Content-Type: application/json' \
    -d '{"name":"Docs 站点(已更名)","urls":["https://docs.example.com","https://wiki.example.com"]}'
{"id":2,"name":"Docs 站点(已更名)","urls":["https://docs.example.com","https://wiki.example.com"],"urls_raw":"https://docs.example.com,https://wiki.example.com","first_url":"https://docs.example.com"}
[HTTP 200]

多站点的域名与信任判定用 GET /conf/domain:携带可信 Origin 时返回 {"origin":"http://192.168.146.128:8119","is_trusted":true};不带 Origin 时返回 {"origin":"://","is_trusted":false} [HTTP 200]。

七、用户与权限

1. 创建用户与重复校验

$ curl -s -X POST http://127.0.0.1:8119/api/v2/users -H "Authorization: Bearer $TOKEN" \
    -H 'Content-Type: application/json' \
    -d '{"name":"editor02","email":"editor02@example.com","password":"q1w2e3r4","is_admin":false,"receive_email":true,"badge_name":"编辑","badge_color":"#00a2ff"}'
{"id":14,"name":"editor02","email":"editor02@example.com","link":"","badge_name":"编辑","badge_color":"#00a2ff","is_admin":false,"receive_email":true,"last_ip":"","last_ua":"","is_in_conf":false,"comment_count":0}
[HTTP 200]
$ curl -s -X POST http://127.0.0.1:8119/api/v2/users -H "Authorization: Bearer $TOKEN" \
    -H 'Content-Type: application/json' \
    -d '{"name":"editor01","email":"editor01@example.com","password":"q1w2e3r4","is_admin":false,"receive_email":true,"badge_name":"编辑","badge_color":"#00a2ff"}'
{"msg":"用户已存在"}
[HTTP 400]

2. 用户列表与越权访问

$ curl -s "http://127.0.0.1:8119/api/v2/users/all" -H "Authorization: Bearer $TOKEN"
{"count":13,"users":[{"id":13,"name":"验证码测试","email":"captcha@example.com","link":"","badge_name":"","badge_color":"","is_admin":false,"receive_email":true,"last_ip":"10.89.44.1","last_ua":"curl/7.81.0","is_in_conf":false,"comment_count":1},...]}
[HTTP 200]
$ curl -s "http://127.0.0.1:8119/api/v2/users/all"
{"msg":"需要管理员权限","need_login":true}
[HTTP 403]

用户记录含 last_ip、last_ua、comment_count(冗余计数)等运营字段;is_in_conf 表示是否来自配置文件声明。系统设置原文(YAML)可由 GET /settings 获取(需管理员),节选:

$ curl -s http://127.0.0.1:8119/api/v2/settings -H "Authorization: Bearer $TOKEN"
{"yaml":"# 服务器地址\nhost: \"0.0.0.0\"\n\n# 服务器端口\nport: 23366\n\n# 加密密钥\napp_key: \"atk-prod-key-2026-0918\"\n\n# 调试模式\ndebug: false\n\n# 语言 [\"en\", \"zh-CN\", \"zh-TW\", \"ja\", \"fr\", \"ko\", \"ru\"]\nlocale: zh-CN\n..."}
[HTTP 200]

八、通知、统计、验证码与缓存

1. 站内通知

$ curl -s http://127.0.0.1:8119/api/v2/notifies -H "Authorization: Bearer $TOKEN"
{"notifies":[],"count":0}
[HTTP 200]
$ curl -s -X POST http://127.0.0.1:8119/api/v2/notifies/read -H "Authorization: Bearer $TOKEN" \
    -H 'Content-Type: application/json' -d '{}'
{"msg":"名称必须填写"}
[HTTP 400]
$ curl -s -X POST http://127.0.0.1:8119/api/v2/notifies/read -H "Authorization: Bearer $TOKEN" \
    -H 'Content-Type: application/json' -d '{"name":"admin","email":"admin@example.com"}'
{"msg":"Success"}
[HTTP 200]

通知的网页落地链接形如 ...?atk_comment=<id>&atk_notify_key=<key>(atk_notify_key 由 app_key 派生,见Artalk 配置参数详解(v2.10.0))。

2. 统计接口

$ curl -s "http://127.0.0.1:8119/api/v2/stats/page_pv?site_name=Artalk%20%E7%9A%84%E5%8D%9A%E5%AE%A2"
{"data":{}}
[HTTP 200]
$ curl -s "http://127.0.0.1:8119/api/v2/stats/pv_most_pages?site_name=Artalk%20%E7%9A%84%E5%8D%9A%E5%AE%A2&limit=5"
{"data":[{"id":1,"admin_only":false,"key":"/post/hello.html","url":"http://192.168.146.128:8119/post/hello.html","title":"你好 Artalk(标题已改)","site_name":"Artalk 的博客","vote_up":0,"vote_down":0,"pv":2,"date":"2026-10-19 15:09:04"}]}
[HTTP 200]
$ curl -s "http://127.0.0.1:8119/api/v2/stats/latest_comments?site_name=Artalk%20%E7%9A%84%E5%8D%9A%E5%AE%A2&limit=2"
{"data":[{"id":15,"content":"这条应被验证码拦截",...,"nick":"验证码测试",...},...]}
[HTTP 200]

(page_pv 聚合键为「页面 key」,本环境 PV 都在 /post/hello.html 上但返回空——不同 type 的聚合口径不同,pv_most_pages / latest_comments 数据直观可用;对接前建议逐 type 核对回显。)

3. 验证码

captcha.enabled: false 时查询直接 404:

$ curl -s "http://127.0.0.1:8119/api/v2/captcha/status?page_key=/post/hello.html&site_name=Artalk%20%E7%9A%84%E5%8D%9A%E5%AE%A2"
{"msg":"Captcha disabled"}
[HTTP 404]

启用后(enabled: true):无需验证码时 {"is_pass":true} [HTTP 200];always: true 时为 {"is_pass":false}。此时提交评论被拦截,403 响应体实录(base64 图片数据共 5282 字符,此处截取前缀):

$ curl -s -X POST http://127.0.0.1:8119/api/v2/comments -H 'Content-Type: application/json' \
    -H 'Origin: http://192.168.146.128:8119' \
    -d '{"page_key":"/post/hello.html","name":"验证码测试","email":"captcha@example.com","content":"这条应被验证码拦截","site_name":"Artalk 的博客"}'
{"img_data":"data:image/png;base64,iVBORw0KGgoAAAANSU...(base64 图片数据, 共 5282 字符)","msg":"需要验证码","need_captcha":true}
[HTTP 403]

流程:GET /captcha 取图 → POST /captcha/verify 校验 → 重新提交评论。默认 action_limit: 3 的含义:不设 always 时,同一客户端连续 3 次写操作后的下一次才要求验证码。

4. 缓存管理

$ curl -s -X POST http://127.0.0.1:8119/api/v2/cache/warm_up -H "Authorization: Bearer $TOKEN"
{"msg":"cache disabled"}
[HTTP 400]

(cache.enabled: false 时返回 400「cache disabled」;启用后 warm_up 与 flush 均回显 {"msg":"任务已开始在后台执行,请稍后..."} [HTTP 200],属异步任务接口。)

九、错误码与回显速查表

实测汇总(状态码为 HTTP 状态码,msg 为响应体原文):

场景状态码响应体
GET /comments 缺 page_key400{"msg":"Page_key必须填写"}
PUT /comments/{id} 缺 site_name400{"msg":"Site_name必须填写"}
PUT /comments/{id} 缺 is_collapsed400{"msg":"Is_collapsed必须填写"}
POST /users 用户已存在400{"msg":"用户已存在"}
POST /notifies/read 缺名称400{"msg":"名称必须填写"}
缓存接口在 cache disabled 时调用400{"msg":"cache disabled"}
需要验证码时提交评论403{"img_data":"data:image/png;base64,...","msg":"需要验证码","need_captcha":true}
无凭据执行管理员操作403{"msg":"需要管理员权限","need_login":true}
评论/页面不存在(GET)404{"msg":"评论未找到"}
删除不存在的评论404{"msg":"评论未找到"}
验证码已禁用时查询状态404{"msg":"Captcha disabled"}
无 token / 非法 token 读 /user200{"user":null,"is_login":false,"notifies":[],"notifies_count":0}(务必检查 is_login)
未配置站点名或参数错误(写入)400以「Xxx必须填写」模式回显缺失字段名

规律:校验失败统一 400 + 中文提示(提示词即缺失字段名的 PascalCase);权限问题统一 403 + need_login 标记;资源不存在统一 404;错误信息语言跟随 locale,但校验类提示词实测不随 locale 变化(locale: en 下仍为中文,见配置篇实测)。

十、常见问题

  1. 回复没有嵌套关系:字段名用错了——必须是 rid,reply_id 会被静默忽略(评论照常创建但 rid:0,实测复现两次)。
  2. PUT 编辑总是 400:该接口要求全字段提交(含 is_pinned/is_collapsed/is_pending),先 GET 详情取原值再合并提交。
  3. 脚本里判断登录态别只看状态码:/user 对无效 token 也返回 200,判定以 is_login 字段为准。
  4. 连续操作被 403:默认验证码策略(3 次写操作后),脚本场景临时 captcha.enabled: false 或等待 action_reset: 60 秒计数重置。
  5. 跨域调不通:服务端日志正常但浏览器报 CORS,检查 trusted_domains 是否包含前端 Origin(该配置只影响响应头,不影响 curl;详见配置篇实测)。
  6. 想对接自建系统:Webhook 推送报文结构见配置篇第 9 节实录;配合本文的评论/用户接口可完成「评论同步 + 自动化处理」闭环。
  7. 二开建议:以官方 OpenAPI 规范为准(https://artalk.js.org/http-api.html ),本文全部请求/响应对 v2.10.0 实测可复现,版本升级后建议先重跑第九节速查表核对。

参考链接

  1. Artalk HTTP API 官方文档(OpenAPI):https://artalk.js.org/http-api.html
  2. Artalk GitHub 仓库:https://github.com/ArtalkJS/Artalk
  3. v2.10.0 Release:https://github.com/ArtalkJS/Artalk/releases/tag/v2.10.0
  4. 官方文档首页:https://artalk.js.org