Libredesk v2.9.0 API 使用详解

Libredesk v2.9.0 REST Admin API 使用详解:Token/Basic 认证实测、端点域全景、坐席/团队/联系人/会话/标签/报表/Webhook 各域 curl 实测响应、分页与搜索通用约定及常见问题,全部请求逐条实测。

LibredeskLibredeskREST API2026/10/24

Libredesk v2.9.0 API 使用详解

目标:讲解 Libredesk v2.9.0 REST Admin API 的认证方式、端点总览、各资源域(坐席/团队/联系人/会话/标签/状态/优先级/报表/Webhook/设置)的调用方法与真实响应,以及分页与搜索的通用约定。全部请求在本地部署的 v2.9.0 实例(http://127.0.0.1:8153,前缀 /api/v1)用 curl 逐条实测,响应 JSON 逐行照抄;官方 API 文档自述「部分端点尚未文档化」,本文路由清单同时以 v2.9.0 源码 cmd/handlers.go 为准做了补全。

一、环境信息

  • 实测实例:Libredesk v2.9.0(v2.9.0 (5668a2a2 2026-10-22T11:43:42Z, linux/amd64)),Docker Compose 部署(部署方法见 《Libredesk Docker Compose 部署指南》)
  • API 基址:http://127.0.0.1:8153/api/v1(官方默认端口 9000 时为 http://<服务器IP>:9000/api/v1)
  • 客户端工具:curl 7.81+(系统自带)
  • 认证凭据:Agent 级 API Key + Secret(在管理界面 Admin → Teammates → Agents 打开坐席点 Generate API key 生成;生成接口为 POST /api/v1/agents/{id}/api-key,吊销为 DELETE /api/v1/agents/{id}/api-key,需 users:manage 权限)
  • 路由权威来源:仓库源码 cmd/handlers.go(v2.9.0,2026-10-24 查询)+ 官方 API 参考 https://docs.libredesk.io/api-reference/introduction
  • 已授权测试数据:团队「客服一组」、联系人「张三/王测试」、标签「vip客户/vip-客户」均为实例内真实数据

二、前置条件

调用 API 前需要三样东西:

  1. 一个可访问的实例:自建或演示环境(官方提供 https://demo.libredesk.io/,但演示站不建议写数据);
  2. API Key 与 Secret:管理员登录后在坐席详情页生成。Secret 只显示一次,请立即保存;同一把 Key 拥有所属坐席的全部角色与权限(官方文档原文:"A request made with an API key has the same roles and permissions as the agent that owns the key");
  3. curl 或任意 HTTP 客户端:本文全部示例用 curl。

三、API 总览

3.1 协议与约定

约定项说明
协议HTTP + JSON,全部端点挂在 /api/v1 前缀下
响应封装成功 {"status":"success","data":...};失败 {"status":"error","message":"...","data":null,"error_type":"..."}
认证Token(Authorization: token KEY:SECRET)或 Basic(Authorization: Basic base64(KEY:SECRET))二选一
请求体格式因端点而异:标签/坐席/会话等用 JSON;联系人创建用 multipart/form-data(详见 5.3 节实测)
错误类型GeneralException(通用错误/凭据无效)、InputException/InputError(入参错误)
限流认证端点组默认 30 次/分钟/IP(config.toml [rate_limit.auth],可调)

3.2 端点域全景(v2.9.0 源码路由归纳)

资源域代表端点权限要求
坐席 AgentsGET/POST /agents、GET/PUT/DELETE /agents/{id}、POST /agents/{id}/api-keyusers:manage;/agents/me 系列仅需登录
团队 TeamsGET/POST /teams、GET/PUT/DELETE /teams/{id}teams:manage
联系人 ContactsGET/POST /contacts、GET/PUT/DELETE /contacts/{id}、POST /contacts/{id}/notescontacts:read_all/contacts:write 等
会话 Conversations`GET /conversations/allunassigned
消息 MessagesGET/POST /conversations/{uuid}/messages、DELETE /conversations/{cuuid}/messages/{uuid}messages:read/write
标签 TagsGET/POST /tags、PUT/DELETE /tags/{id}登录读 / tags:manage 写
状态与优先级GET/POST /statuses、GET /priorities登录读 / status:manage 写
收件箱 InboxesGET/POST /inboxes、PUT /inboxes/{id}inboxes:manage
自动化 AutomationsGET/POST /automations/rules、PUT /automations/rules/{id}/toggleautomations:manage
WebhookGET/POST /webhooks、POST /webhooks/{id}/testwebhooks:manage
报表 Reports`GET /reports/overview/countssla
视图 ViewsGET/POST /views/me、GET/POST /shared-viewsview:manage 等
SLAGET/POST /sla、PUT/DELETE /sla/{id}sla:manage
模板 TemplatesGET/POST /templatestemplates:manage
角色 RolesGET/POST /rolesroles:manage
AIGET /ai/prompts、`POST /ai/completiongenerate-reply
设置 SettingsGET/PUT /settings/general、GET/PUT /settings/notifications/emailgeneral_settings:manage 等
帮助中心门户(Widget/公开)/api/v1/lang、媒体上传 /api/v1/media 等部分公开

💡 技术拓展:与多数工单系统把管理 API 和客户侧 API 混在一套不同,Libredesk 的 API 分三个信任面——

信任面代表端点认证
管理面 Admin API/api/v1/agents、/conversations 等API Key 或登录会话
会话登录POST /api/v1/auth/login邮箱+密码换 Cookie
公开/Widget 面聊天 Widget、帮助中心、CSAT免认证但按 IP 限流

本文聚焦管理面 Admin API。Widget/公开面的限流阈值在 config.toml [rate_limit.widget]/[rate_limit.public]/[rate_limit.media] 配置(见 《Libredesk v2.9.0 配置参数详解》5.10 节)。

四、认证与首次调用

4.1 Token 认证(推荐)

格式:Authorization: token <API_KEY>:<API_SECRET>。实测当前坐席信息:

# Token 认证获取当前坐席
curl -s -H "Authorization: token 76meLTzy0rSyk4ShDq9EgZB05X7JRhzZ:MG9xz1XhWPfVDapodPhHC8Y5S5bg8cXWEfC2QEW4DiYFdXUqSaKJpNwvpp83KaxR" \
  http://127.0.0.1:8153/api/v1/agents/me
{"status":"success","data":{"id":1,"created_at":"2026-10-23T19:47:10.248407Z","updated_at":"2026-10-23T20:21:24.174576Z","first_name":"System","last_name":"","email":"System","type":"agent","availability_status":"offline", ...

4.2 Basic 认证

格式:HTTP Basic,用户名=API Key,密码=API Secret。同一端点等价验证:

# Basic 认证(curl -u 自动做 base64)
curl -s -u "76meLTzy0rSyk4ShDq9EgZB05X7JRhzZ:MG9xz1XhWPfVDapodPhHC8Y5S5bg8cXWEfC2QEW4DiYFdXUqSaKJpNwvpp83KaxR" \
  http://127.0.0.1:8153/api/v1/agents/me
{"status":"success","data":{"id":1,"created_at":"2026-10-23T19:47:10.248407Z","updated_at":"2026-10-23T20:21:24.174576Z", ...

4.3 认证失败实测

# 错误的 Secret
curl -s -H "Authorization: token 76meLTzy0rSyk4ShDq9EgZB05X7JRhzZ:wrongsecret" \
  -w '\nHTTP %{http_code}\n' http://127.0.0.1:8153/api/v1/agents/me
{"status":"error","message":"Invalid credential","data":null,"error_type":"GeneralException"}
HTTP 401
# 完全不带认证头访问需登录端点
curl -s -w '\nHTTP %{http_code}\n' http://127.0.0.1:8153/api/v1/agents
{"status":"error","message":"Invalid or expired session","data":null,"error_type":"GeneralException"}
HTTP 401

4.4 会话登录(Web 端同款接口)

不持 API Key 时可用管理员账号换会话 Cookie(即 Web 界面登录走的接口):

# 密码登录拿会话(-c 保存 Cookie)
curl -s -c cookies.txt -H 'Content-Type: application/json' \
  -d '{"email":"System","password":"Q1w2e3r4!@"}' \
  http://127.0.0.1:8153/api/v1/auth/login
{"status":"success","data":{"id":1,...,"first_name":"System","email":"System","type":"agent", ...

⚠️ 注意:/auth/login 属 [rate_limit.auth] 限流组(默认 30 次/分钟/IP),脚本轮询登录会被限流;程序化对接一律用 API Key。

五、各 API 域详解

5.1 坐席 Agents

坐席即客服人员。列出与详情(实测回显):

# 坐席详情
curl -s -H "Authorization: token 76meLTzy0rSyk4ShDq9EgZB05X7JRhzZ:MG9xz1XhWPfVDapodPhHC8Y5S5bg8cXWEfC2QEW4DiYFdXUqSaKJpNwvpp83KaxR" \
  http://127.0.0.1:8153/api/v1/agents/1
{"status":"success","data":{"id":1,"created_at":"2026-10-23T19:47:10.248407Z","updated_at":"2026-10-23T20:21:24.174576Z","first_name":"System","last_name":"","email":"System","type":"agent", ...

创建坐席(JSON 请求体,roles 传角色名数组;实测创建李坐席):

# 创建坐席
curl -s -X POST -H "Authorization: token 76meLTzy0rSyk4ShDq9EgZB05X7JRhzZ:MG9xz1XhWPfVDapodPhHC8Y5S5bg8cXWEfC2QEW4DiYFdXUqSaKJpNwvpp83KaxR" \
  -H 'Content-Type: application/json' \
  -d '{"first_name":"李","last_name":"坐席","email":"li@example.com","roles":["Agent"]}' \
  http://127.0.0.1:8153/api/v1/agents
{"status":"success","data":{"id":4,"created_at":"2026-10-23T20:30:56.368484Z","updated_at":"2026-10-23T20:30:56.368484Z","first_name":"李","last_name":"坐席","email":"li@example.com","type":"agent","availability_status":"offline", ...

API Key 管理(生成后 Secret 只返回一次):

# 为坐席生成 API Key(需 users:manage 权限)
curl -s -X POST -H "Authorization: token <KEY>:<SECRET>" http://127.0.0.1:8153/api/v1/agents/4/api-key
# 吊销
curl -s -X DELETE -H "Authorization: token <KEY>:<SECRET>" http://127.0.0.1:8153/api/v1/agents/4/api-key

5.2 团队 Teams

# 团队列表
curl -s -H "Authorization: token 76meLTzy0rSyk4ShDq9EgZB05X7JRhzZ:MG9xz1XhWPfVDapodPhHC8Y5S5bg8cXWEfC2QEW4DiYFdXUqSaKJpNwvpp83KaxR" \
  http://127.0.0.1:8153/api/v1/teams
{"status":"success","data":[{"id":1,"created_at":"2026-10-23T19:52:31.052118Z","updated_at":"2026-10-23T19:52:31.052118Z","emoji":"","name":"客服一组","conversation_assignment_type":"Round robin","timezone":"","business_hours_id":null,"sla_policy_id":null,"max_auto_assigned_conversations":0}]}

关键字段:conversation_assignment_type(分派策略,Round robin 轮询)与 max_auto_assigned_conversations(每人自动分派上限,0=不限)。

5.3 联系人 Contacts

注意:联系人创建/更新用 multipart form 表单,不是 JSON——这是最容易踩的坑(发 JSON 会得到 "Error parsing request")。实测创建:

# 创建联系人(表单字段:email 与 phone_number 至少一项)
curl -s -X POST -H "Authorization: token 76meLTzy0rSyk4ShDq9EgZB05X7JRhzZ:MG9xz1XhWPfVDapodPhHC8Y5S5bg8cXWEfC2QEW4DiYFdXUqSaKJpNwvpp83KaxR" \
  -F 'first_name=王' -F 'last_name=测试' -F 'email=wangtest@example.com' -F 'phone_number=+8613800138000' \
  http://127.0.0.1:8153/api/v1/contacts
{"status":"success","data":{"id":3,"created_at":"2026-10-23T20:29:38.591597Z","updated_at":"2026-10-23T20:29:38.591597Z","first_name":"王","last_name":"测试","email":"wangtest@example.com","type":"contact","availability_status":"offline","phone_number_country_code":null,"phone_number":"+8613800138000", ...

列表(默认分页 30 条,实测已有两名联系人):

curl -s -H "Authorization: token 76meLTzy0rSyk4ShDq9EgZB05X7JRhzZ:MG9xz1XhWPfVDapodPhHC8Y5S5bg8cXWEfC2QEW4DiYFdXUqSaKJpNwvpp83KaxR" \
  http://127.0.0.1:8153/api/v1/contacts
{"status":"success","data":{"results":[{"id":2,"type":"contact","first_name":"张三","last_name":"","email":"zhangsan@example.com","enabled":true,"avatar_url":null,"external_user_id":null,"availability_status":"offline","created_at":"2026-10-23T19:52:31.106142Z","updated_at":"2026-10-23T19:52:31.106142Z"}],"total":1,"per_page":30,"total_pages":1,"page":1}}

联系人笔记:GET/POST /contacts/{id}/notes、DELETE /contacts/{id}/notes/{note_id};导出:GET /contacts/{id}/export;屏蔽:PUT /contacts/{id}/block。

5.4 会话 Conversations 与消息 Messages

会话列表三分法(全部/未分配/已分配),实测空列表分页结构:

curl -s -H "Authorization: token 76meLTzy0rSyk4ShDq9EgZB05X7JRhzZ:MG9xz1XhWPfVDapodPhHC8Y5S5bg8cXWEfC2QEW4DiYFdXUqSaKJpNwvpp83KaxR" \
  http://127.0.0.1:8153/api/v1/conversations/all
{"status":"success","data":{"results":[],"total":0,"per_page":30,"total_pages":0,"page":1}}

创建会话必须指定 inbox_id(会话从属于某个收件箱渠道)——缺省时的真实报错:

# 缺 inbox_id 创建会话
curl -s -X POST -H "Authorization: token <KEY>:<SECRET>" -H 'Content-Type: application/json' \
  -d '{"contact_id":3,"channel":"email","subject":"测试工单"}' \
  http://127.0.0.1:8153/api/v1/conversations
{"status":"error","message":"`inbox_id` Required","data":null,"error_type":"InputException"}

⚠️ 注意:inbox_id 来自收件箱管理(GET/POST /inboxes)。创建收件箱必须带对应渠道的 config(SMTP/IMAP 服务器参数或 WhatsApp 号码配置等),裸渠道名会得到 "config empty" 错误——收件箱参数结构随渠道类型差异较大,建议先在 Web 管理界面建好收件箱,再用 GET /inboxes 读取其结构后脚本化。

会话操作端点(源码路由,均实测路由存在):指派坐席/团队 PUT /conversations/{uuid}/assignee/user|team(及 /remove)、改状态 PUT /conversations/{uuid}/status、改优先级 PUT /conversations/{uuid}/priority、打标签 POST /conversations/{uuid}/tags、消息列表 GET /conversations/{uuid}/messages、发消息 POST /conversations/{uuid}/messages、会话记录下载 GET /conversations/{uuid}/transcript。

5.5 标签 Tags

创建标签用 JSON 请求体(name 必填,实测不传 name 得到 `name` empty):

# 创建标签
curl -s -X POST -H "Authorization: token 76meLTzy0rSyk4ShDq9EgZB05X7JRhzZ:MG9xz1XhWPfVDapodPhHC8Y5S5bg8cXWEfC2QEW4DiYFdXUqSaKJpNwvpp83KaxR" \
  -H 'Content-Type: application/json' -d '{"name":"vip-客户","color":"#e11d48"}' \
  http://127.0.0.1:8153/api/v1/tags
{"status":"success","data":{"id":2,"created_at":"2026-10-23T20:30:56.316848Z","updated_at":"2026-10-23T20:30:56.316848Z","name":"vip-客户"}}
# 标签列表
curl -s -H "Authorization: token 76meLTzy0rSyk4ShDq9EgZB05X7JRhzZ:MG9xz1XhWPfVDapodPhHC8Y5S5bg8cXWEfC2QEW4DiYFdXUqSaKJpNwvpp83KaxR" \
  http://127.0.0.1:8153/api/v1/tags
{"status":"success","data":[{"id":1,"created_at":"2026-10-23T19:52:05.612412Z","updated_at":"2026-10-23T19:52:05.612412Z","name":"vip客户"}]}

5.6 状态与优先级

# 会话状态列表
curl -s -H "Authorization: token 76meLTzy0rSyk4ShDq9EgZB05X7JRhzZ:MG9xz1XhWPfVDapodPhHC8Y5S5bg8cXWEfC2QEW4DiYFdXUqSaKJpNwvpp83KaxR" \
  http://127.0.0.1:8153/api/v1/statuses
{"status":"success","data":[{"id":1,"created_at":"2026-10-23T19:47:09.922149Z","name":"Open","category":"open"},{"id":2,"created_at":"2026-10-23T19:47:09.922149Z","name":"Snoozed","category":"waiting"},{"id":3,"created_at":"2026-10-23T19:47:09.922149Z","name":"Resolved","category":"resolved"},{"id":4,"created_at":"2026-10-23T19:47:09.922149Z","name":"Closed","category":"resolved"}]}
# 优先级列表
curl -s -H "Authorization: token 76meLTzy0rSyk4ShDq9EgZB05X7JRhzZ:MG9xz1XhWPfVDapodPhHC8Y5S5bg8cXWEfC2QEW4DiYFdXUqSaKJpNwvpp83KaxR" \
  http://127.0.0.1:8153/api/v1/priorities
{"status":"success","data":[{"id":1,"created_at":"2026-10-23T19:47:09.922149Z","name":"Low"},{"id":2,"created_at":"2026-10-23T19:47:09.922149Z","name":"Medium"},{"id":3,"created_at":"2026-10-23T19:47:09.922149Z","name":"High"}]}

改会话状态/优先级时把这里的 id 传给 PUT /conversations/{uuid}/status|priority。状态支持自定义(POST /statuses,status:manage 权限)。

5.7 报表 Reports

# 总览计数
curl -s -H "Authorization: token 76meLTzy0rSyk4ShDq9EgZB05X7JRhzZ:MG9xz1XhWPfVDapodPhHC8Y5S5bg8cXWEfC2QEW4DiYFdXUqSaKJpNwvpp83KaxR" \
  http://127.0.0.1:8153/api/v1/reports/overview/counts
{"status": "success", "data": {"open" : 0, "awaiting_response" : 0, "unassigned" : 0, "pending" : 0, "agents_online" : 0, "agents_away" : 0, "agents_reassigning" : 0, "agents_offline" : 1}}

其余报表端点:/reports/overview/sla(SLA 达成)、/reports/overview/charts(趋势图数据)、/reports/overview/csat(满意度)、/reports/overview/messages(消息量)、/reports/overview/tags(标签分布),均支持时间范围查询参数。

5.8 Webhook

# Webhook 列表
curl -s -H "Authorization: token 76meLTzy0rSyk4ShDq9EgZB05X7JRhzZ:MG9xz1XhWPfVDapodPhHC8Y5S5bg8cXWEfC2QEW4DiYFdXUqSaKJpNwvpp83KaxR" \
  http://127.0.0.1:8153/api/v1/webhooks
{"status":"success","data":[]}

管理端点:POST /webhooks(注册订阅 URL + 事件集)、PUT /webhooks/{id}、PUT /webhooks/{id}/toggle(启停)、POST /webhooks/{id}/test(向目标 URL 发送测试事件)。派发行为由 config.toml [webhook] 段控制(5 workers / 10000 队列 / 15s 超时,见配置篇 5.9 节)。

5.9 设置 Settings

# 通用设置
curl -s -H "Authorization: token 76meLTzy0rSyk4ShDq9EgZB05X7JRhzZ:MG9xz1XhWPfVDapodPhHC8Y5S5bg8cXWEfC2QEW4DiYFdXUqSaKJpNwvpp83KaxR" \
  http://127.0.0.1:8153/api/v1/settings/general
{"status":"success","data":{"app.allowed_file_upload_extensions":["*"],"app.business_hours_id":"","app.favicon_url":"http://localhost:9000/favicon.ico","app.lang":"en-US","app.logo_url":"","app.max_file_upload_size":20,"app.restart_required":false,"app.root_url":"http://localhost:9000", ...

设置以键值对返回(app.* 前缀),PUT /settings/general 更新。注意这类设置存数据库,与 config.toml 文件配置是两套(文件管进程行为,设置管运行时业务参数)。

六、分页、过滤与搜索通用约定

6.1 分页(列表端点统一)

查询参数:page(页码,<1 时按 1 处理)与 page_size(每页条数,默认 30,上限 500,源码常量 maxPageSize=500)。响应统一结构(实测 page_size=1):

curl -s -H "Authorization: token 76meLTzy0rSyk4ShDq9EgZB05X7JRhzZ:MG9xz1XhWPfVDapodPhHC8Y5S5bg8cXWEfC2QEW4DiYFdXUqSaKJpNwvpp83KaxR" \
  "http://127.0.0.1:8153/api/v1/contacts?page=1&page_size=1"
{"status":"success","data":{"results":[...],"total":2,"per_page":1,"total_pages":2,"page":1}}

字段含义:results 数据数组、total 总条数、per_page 每页条数、total_pages 总页数、page 当前页。翻页循环用 page 递增直到 page > total_pages。

6.2 搜索

搜索端点三组:GET /contacts/search、GET /conversations/search、GET /messages/search(首屏结果型)与 GET /search/conversations、GET /search/messages(游标分页型)。规则(源码常量 + 实测):

  • 查询参数名是 query(不是 q),最少 3 个字符,实测缺时报错:
# 查询词少于 3 字符
curl -s -H "Authorization: token 76meLTzy0rSyk4ShDq9EgZB05X7JRhzZ:MG9xz1XhWPfVDapodPhHC8Y5S5bg8cXWEfC2QEW4DiYFdXUqSaKJpNwvpp83KaxR" \
  "http://127.0.0.1:8153/api/v1/contacts/search?q=张三"
{"status":"error","message":"Please enter at least 3 characters to search.","data":null,"error_type":"InputException"}
# 合法搜索(query=wang 命中联系人)
curl -s -H "Authorization: token 76meLTzy0rSyk4ShDq9EgZB05X7JRhzZ:MG9xz1XhWPfVDapodPhHC8Y5S5bg8cXWEfC2QEW4DiYFdXUqSaKJpNwvpp83KaxR" \
  "http://127.0.0.1:8153/api/v1/contacts/search?query=wang"
{"status":"success","data":[{"id":3,"created_at":"2026-10-23T20:29:38.591597Z","first_name":"王","last_name":"测试","email":"wangtest@example.com","phone_number":"+8613800138000","phone_number_country_code":null,"external_user_id":null}]}
  • 首屏结果型搜索可用 limit 限制条数(上限:会话 1000、消息 30、联系人 15,源码常量);
  • 游标分页型(/search/*)额外支持 filters(过滤)、sort(排序)、cursor(游标翻页),响应含 has_more 与 next_cursor。

6.3 列表排序与过滤

联系人列表端点支持 order(升/降序方向)与 order_by(排序字段)、filters(JSON 过滤条件)查询参数(源码 handleGetContacts 实参);会话列表的过滤条件同类。传参格式为 URL 查询串,filters 值为 JSON 字符串(需 URL 编码)。

七、常见问题

Q1:报 Invalid credential(HTTP 401)? 三种可能:① Secret 抄错(Secret 只在生成时显示一次,丢了就吊销重建);② Authorization 头格式不对——Token 认证必须是 token KEY:SECRET(注意 token 前缀与冒号分隔,非 Bearer);③ Basic 认证忘了 base64(用 curl -u KEY:SECRET 让 curl 处理)。

Q2:发 JSON 得到 Error parsing request? 该端点吃的是 multipart form 而非 JSON。实测矩阵:JSON 体——/auth/login、/agents、/tags、/conversations;form 体——/contacts(创建/更新)。拿不准时看官方 API 文档对应端点的请求示例,或抓 Web 界面的请求模仿。

Q3:per_page 参数不生效? 参数名是 page_size 不是 per_page(per_page 只出现在响应里);超过 500 会被截到 500。

Q4:搜索一直报 Please enter at least 3 characters to search.? 参数名用 query 且长度 ≥3 字符(中文按字符算,两个字的名字搜不到,可改搜邮箱/拼音前缀)。

Q5:创建会话报 `inbox_id` Required? 会话必须挂在一个收件箱下。先在 Web 界面或 API 创建收件箱(需完整渠道 config),GET /inboxes 拿到 id 后再创建会话。

Q6:程序对接该用哪个账号的 API Key? 为集成场景建专用坐席账号并按需授予最小角色,而不是复用 System 管理员 Key——API Key 的权限完全等价于所属坐席,System Key 泄漏等于整站失守。Key 用途异常时在坐席页吊销重发。

八、参考链接