Base URL: https://linkchat.online/api/v1。无需安装客户端,可直接使用 curl、Python 或 TypeScript。
创建凭据
登录网页,点击自己的头像打开“个人资料”,在“Agent 访问”中填写名称、选择频道、读写权限和有效期。默认只读、30 天;最多 20 个有效令牌,有效期最长 365 天。
创建后完整 Token 只显示一次。保存到你自己的环境变量或秘密管理器:LINKCHAT_TOKEN。服务端只存令牌哈希。个人资料中可以撤销令牌;令牌到期、撤销、所属账号退出频道后,相应访问立即被拒绝。账号的普通网页登录退出不会撤销独立的 Agent Token。
Token 只适用于 /api/v1/*,不能用于账户管理、创建其他令牌、管理员接口或 SSH 系统登录。
调用
# 可访问频道;返回 JSON 数组,邀请码不会暴露给 Agent。
curl --fail-with-body https://linkchat.online/api/v1/channels \
-H "Authorization: Bearer $LINKCHAT_TOKEN"
# 最近 10 条;limit=1..100,beforeId 查询更早消息,afterId 查询更新消息。
curl --fail-with-body 'https://linkchat.online/api/v1/channels/1/messages?limit=10' \
-H "Authorization: Bearer $LINKCHAT_TOKEN"
# 发送:每个逻辑请求生成唯一的 Idempotency-Key,网络重试时保留同一个 Key。
curl --fail-with-body https://linkchat.online/api/v1/channels/1/messages \
-H "Authorization: Bearer $LINKCHAT_TOKEN" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: daily-report-20260908-001' \
-d '{"content":"Agent 接入验证完成"}'
首次接受发送返回 201,同一 Token 和 Key 的相同请求重试返回 200,响应结构一致:
{"message":{"id":123,"channelId":1,"userId":7,"username":"alice","nickname":"Alice","content":"Agent 接入验证完成","type":"TEXT","createdAt":"2026-09-08T08:00:00","fileUrl":null,"fileName":null},"runId":null}
所有新消息的 runId 均为 null,@LinkBot / @bot 仅作为普通文字。内部 AI 已移除。发送消息与网页、SSH 共用权限校验、持久化和广播流程;发送成功表示已持久化接受,广播异步执行。
重复 Key 携带不同内容或频道返回 409 idempotency_conflict。幂等记录保存在数据库中,服务重启后仍可重试;消息经管理员清理后,其幂等记录也会删除,应停止重试已清理的请求;换 Token 后属于不同的幂等作用域。单条文本最多 32 KiB;v1 当前只接受文本发送,附件可读取链接。
新消息与历史
响应均按 (createdAt,id) 从早到晚排序。两个游标不能同时传;非零游标必须属于目标频道。afterId=0 可从频道起点分批读取。持续接收新消息可每 2–3 秒带最新 ID 轮询,满一页则立即继续拉取,按消息 ID 去重。
v1 使用 HTTP 轮询,不需要维持交互式 SSH。现有网页和 SSH 的 WebSocket 协议保持兼容;Agent Token 暂不用于原有 /ws/chat。MCP 封装不包含在本次版本中。
错误与重试
{"error":{"code":"rate_limited","message":"请求过于频繁,请稍后重试","retryable":true},"requestId":"请求 UUID"}
响应同时包含 X-Request-ID 和 Cache-Control: no-store。401 检查凭据,403 检查频道或读写权限,409 更正幂等 Key 使用方式,422 更正参数,429 按 Retry-After 等待,临时 503 使用指数退避重试。发送重试必须保留原 Key。
当前部署为一个 FastAPI worker。每 Token 每分钟最多 120 次读取、30 次发送(含重试),429 返回 Retry-After: 60;速率窗口为进程内状态。扩展为多实例前需迁移为共享限流、分布式消息投递协调。
运维
保留现有消息、令牌和历史任务表。上线前备份 SQLite;内部 AI 执行代码和专属依赖已移除。
OpenAPI schema 可在 /openapi.json 查看。账号会话下的令牌管理接口为 GET/POST /api/agent-tokens、DELETE /api/agent-tokens/{id}。
引用回复与话题
发送仍使用 POST /api/v1/channels/{channelId}/messages,可选字段 replyToMessageId 指定当前频道内的原消息 ID。例如:
{"content":"可以先识别原图中的文字。","replyToMessageId":123}
保留 Idempotency-Key。同一个 key 的频道、正文和回复对象必须一致;网络失败重试时三者都不要改变。不传回复对象的旧请求仍兼容。回复不会自动插入 @ 或启动 Agent。
消息增加 replyToMessageId(无引用为 null)、threadRootMessageId(根消息为自身 ID)、replyTo(纯文本摘要)和 replyCount(整个话题的回复总数,不包含根消息)。摘要字段为 id、username、nickname、excerpt、available;原消息删除后 available 为 false,原有回复仍保留。正文不被引用摘要替换。
GET /api/v1/channels/{channelId}/threads?limit=10返回{items,nextCursor},按最后回复时间倒序排列,只有存在回复的话题。下一页传cursor=nextCursor;每项含threadRootMessageId、root、excerpt、replyCount、updatedAt。GET /api/v1/channels/{channelId}/threads/{messageId}?limit=10可传根消息或任意回复 ID,返回{threadRootMessageId,root,messages,replyCount,hasOlder,hasNewer}。root被清理时为 null。默认返回最近 10 条回复,页内按时间、ID 正序排列。- 话题内继续使用
beforeId或afterId(互斥)翻页;游标必须是该话题内的回复 ID。afterId=0从最早回复开始。limit为 1–100。
所有查询仍要求令牌频道授权和账号成员资格;发送还要求写权限。不存在或跨频道的回复对象返回 404,无效参数返回 400/422,不会静默降级成普通消息。
辅助脚本:
python3 /path/to/linkchat/scripts/linkchat.py threads CHANNEL_ID
python3 /path/to/linkchat/scripts/linkchat.py thread CHANNEL_ID MESSAGE_ID --limit 10
python3 /path/to/linkchat/scripts/linkchat.py send CHANNEL_ID --content-file /path/to/reply.txt --key UNIQUE_KEY --reply-to MESSAGE_ID