立刻智能体平台 API 文档

通过开放 API 将 AI 会话、知识库写入、企微业务数据与推送通知等能力接入业务系统。按目录查看各接口;若要把你的 HTTP 接口登记为技能,请看 技能接入规范。

Version 1.4

概述

立刻智能体平台提供多组开放 HTTP API,覆盖 AI 会话、人工客服轮询、知识库写入、合作客商写入、服务绩效议题同步和推送通知。外部系统可按需选择接口,使用 API Key 鉴权发起请求;各接口的参数与响应以对应章节为准。

开放 API 与技能接入:本页介绍如何调用平台开放 API。若要把你的 HTTP 接口登记为技能,请看 技能接入规范(Skills Spec 1.0)。

接入流程

①准备凭证
Customer Code + API Key
②选择接口
确认所需权限
③发送请求
按接口填写参数
④处理响应
按接口解析结果

Base URL

https://agent.likelic.com/api/v1

认证方式

所有 API 请求必须在 HTTP Headers 中携带以下两个认证字段,且两个凭证必须属于同一企业:

Header说明格式要求示例
X-Customer-Code 客户唯一代码(由管理员分配) 1-50 位字母、数字、下划线或短横线 demo_company
X-API-Key API 访问密钥(在控制台 API 设置中创建) 以 sk- 开头,后跟 48 位十六进制字符 sk-a1b2c3d4e5f6...

认证校验规则

校验项说明
格式校验Customer Code 和 API Key 均需符合上述格式,否则返回 401
归属校验API Key 必须属于该 Customer Code 对应的企业,否则返回 403
有效期校验如果 API Key 设置了过期时间,过期后将返回 403
状态校验API Key 被禁用后将返回 403
安全提示:API Key 是敏感凭证,请勿在前端代码、公开仓库或日志中暴露。建议通过后端服务代理调用,并定期轮换密钥。

智能对话接口 Core

POST /api/v1/chat

向智能体发送问题并获取 AI 回答。支持指定提示词模板和流式/非流式输出模式。

请求参数 (JSON Body)

请求限制:请求体大小不得超过 100KB。
字段类型必填说明
question string 必填 用户提出的问题内容。不可为空字符串,最大长度 800 个字符。
template_id string 可选 指定提示词模板 ID(18-32 位字母数字组合)。不传或留空则使用用户后台设置的默认模板。可在控制台「提示词管理」中查看每个模板的 ID。
session_id string 可选 会话 ID(最长 36 位)。传入相同的 session_id 可将多次连续对话归组为同一会话,在控制台「对话日志」中合并展示。非流式模式下,首次对话不传此参数,系统将自动生成并在响应中返回;流式模式下,若需记录连续会话,应在首次请求就传入,客户端自行生成 UUID,因为流式返回的内容不包含 session_id。
stream boolean 可选 是否启用流式输出。默认 false。设为 true 时以 SSE (Server-Sent Events) 格式逐字返回。

关键词转人工(企业微信)

若企业已在控制台配置「企业微信 → 人工客服转接」(开启转人工推送并填写群机器人 Webhook、触发词),则开放 API 与网页组件、控制台 Chat 共用同一套触发词:当用户 question 中包含任一条触发词时,本次请求不会调用大模型,而是创建/续接人工会话,并向企微群推送卡片。

  • session_id:首条转人工请求可不传,响应中的 session_id 须保存;后续用户与人工沟通过程中请继续传入同一 session_id,追问会推送到同一企微群线程。
  • 响应:data.human_mode === true 表示已进入人工模式;data.answer 为提示文案;data.human_session_db_id 为内部会话主键(与群内卡片「会话记录ID」一致,供排障或对接工单)。
  • 退出人工:用户发送结束类话术(与控制台人工会话一致)且传入当前 session_id 时,可结束会话并回到 AI。
  • 流式:转人工在流式、非流式下均在调用模型之前判定;命中转人工时返回普通 JSON(非 SSE)。
  • 按 API Key 控制:专业版及以上在「API 设置 → 管理密钥权限」中可关闭某密钥的转人工,或指定仅使用某条企微「人工客服转接」配置(多配置时避免串线)。基础版(Lite)无企业微信菜单,亦不展示该项,开放 API 侧沿用默认转人工策略(若企业未配企微则不会命中)。

非流式输出 (stream: false)

完整等待模型生成后一次性返回结果,适用于后台任务、批处理等场景。

请求示例(首次对话)

curl -X POST https://agent.likelic.com/api/v1/chat \
  -H "Content-Type: application/json" \
  -H "X-Customer-Code: your_customer_code" \
  -H "X-API-Key: sk-your-api-key-here" \
  -d '{
    "question": "你们的退货政策是什么?",
    "template_id": "Abc123Def456GhiJkl789Mnop"
  }'

请求示例(多轮对话,续接会话)

curl -X POST https://agent.likelic.com/api/v1/chat \
  -H "Content-Type: application/json" \
  -H "X-Customer-Code: your_customer_code" \
  -H "X-API-Key: sk-your-api-key-here" \
  -d '{
    "question": "那退款需要多长时间到账?",
    "template_id": "Abc123Def456GhiJkl789Mnop",
    "session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
  }'

响应示例

{
  "success": true,
  "data": {
    "answer": "根据我们的退货政策,您可以在收到商品后 7 天内申请无理由退货...",
    "session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "sources": [
      {
        "question": "退货政策有什么规定?",
        "score": 0.92
      }
    ],
    "model": "qwen-plus",
    "tokensUsed": 486,
    "responseTime": 1523
  }
}

响应字段说明

字段类型说明
successboolean请求是否成功
data.answerstringAI 生成的回答内容
data.session_idstring会话 ID。首次对话由系统自动生成,后续对话请回传此值以续接同一会话
data.sourcesarray命中的知识库条目及匹配分数
data.modelstring本次使用的模型名称
data.tokensUsednumber本次消耗的 Token 总量
data.responseTimenumber端到端响应时间 (毫秒)
data.human_modeboolean可选。为 true 时表示本请求已走关键词转人工,未调用大模型
data.human_session_db_idnumber可选。人工会话在系统中的主键 ID,与企微卡片「会话记录ID」一致
data.session_endedboolean可选。用户结束人工会话时为 true

流式输出 (stream: true)

以 SSE (Server-Sent Events) 格式实时推送生成内容,适用于前端实时展示打字效果等交互场景。

提示:流式模式下,若需记录连续会话,应在首次请求就传入 session_id(客户端自行生成 UUID),因为流式返回的内容不包含 session_id,无法像非流式那样从响应中获取。

请求示例(流式 + 首次会话,需传入 session_id 以记录连续对话)

curl -X POST https://agent.likelic.com/api/v1/chat \
  -H "Content-Type: application/json" \
  -H "X-Customer-Code: your_customer_code" \
  -H "X-API-Key: sk-your-api-key-here" \
  -d '{
    "question": "如何申请退款?",
    "template_id": "Abc123Def456GhiJkl789Mnop",
    "session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "stream": true
  }'

流式响应格式

响应 Content-Type 为 text/event-stream,数据以 SSE 格式逐行推送:

data: {"content":"根据"}

data: {"content":"我们"}

data: {"content":"的退货"}

data: {"content":"政策,"}

data: {"content":"..."}

data: [DONE]
提示:流式模式下,每个 data: 行包含一个 JSON 对象,其中 content 字段为增量文本片段。当收到 data: [DONE] 时表示生成完毕。

JavaScript 流式调用示例

// 若需记录连续会话,流式首次请求需传入 session_id(流式响应不包含 session_id)
const sessionId = crypto.randomUUID();
const response = await fetch('https://agent.likelic.com/api/v1/chat', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-Customer-Code': 'your_customer_code',
    'X-API-Key': 'sk-your-api-key-here'
  },
  body: JSON.stringify({
    question: '如何申请退款?',
    template_id: 'Abc123Def456GhiJkl789Mnop',
    session_id: sessionId,
    stream: true
  })
});

const reader = response.body.getReader();
const decoder = new TextDecoder();
let result = '';

while (true) {
  const { done, value } = await reader.read();
  if (done) break;

  const chunk = decoder.decode(value);
  const lines = chunk.split('\n');

  for (const line of lines) {
    if (line.startsWith('data: ') && line !== 'data: [DONE]') {
      const json = JSON.parse(line.slice(6));
      result += json.content;
      console.log(json.content); // 实时输出
    }
  }
}

Python 调用示例

import requests
import json

url = "https://agent.likelic.com/api/v1/chat"
headers = {
    "Content-Type": "application/json",
    "X-Customer-Code": "your_customer_code",
    "X-API-Key": "sk-your-api-key-here"
}

# 非流式调用(首次对话,不传 session_id)
resp = requests.post(url, headers=headers, json={
    "question": "你们的退货政策是什么?",
    "template_id": "Abc123Def456GhiJkl789Mnop"
})
data = resp.json()["data"]
session_id = data["session_id"]  # 保存用于后续多轮对话
print(data["answer"])

# 多轮对话(传入首次返回的 session_id)
resp = requests.post(url, headers=headers, json={
    "question": "那退款需要多长时间到账?",
    "template_id": "Abc123Def456GhiJkl789Mnop",
    "session_id": session_id
})
print(resp.json()["data"]["answer"])

# 流式调用(若需记录连续会话,首次请求需传入 session_id,因流式响应不包含 session_id)
import uuid
stream_session_id = str(uuid.uuid4())
resp = requests.post(url, headers=headers, json={
    "question": "还有其他注意事项吗?",
    "template_id": "Abc123Def456GhiJkl789Mnop",
    "session_id": stream_session_id,
    "stream": True
}, stream=True)

for line in resp.iter_lines():
    if line:
        decoded = line.decode("utf-8")
        if decoded.startswith("data: ") and decoded != "data: [DONE]":
            data = json.loads(decoded[6:])
            print(data["content"], end="", flush=True)

人工客服回复轮询 HUMAN

GET /api/v1/human-replies

在 human_mode 为 true 且拿到与 /chat 相同的 session_id 后,可用本接口轮询企微群内回复。鉴权与 Chat 一致:X-Customer-Code、X-API-Key。human_mode 的触发方式见 AI 会话接口「关键词转人工(企业微信)」。

查询参数

参数说明
session_id必填,与对话接口一致,最长 36 字符
since_id可选,默认 0。仅返回 id > since_id 的消息(与控制台/组件 human-replies 行为一致)

响应 data.messages[]

字段说明
id消息主键,下次请求作 since_id
content正文
wechat_from_user企微侧发送者标识;系统提示(如会话超时结束)为 __system__。前端展示建议:人工客服 {wechat_from_user}:{content},系统消息可仅展示 content
created_at创建时间

请求示例

curl -G "https://agent.likelic.com/api/v1/human-replies" \
  -H "X-Customer-Code: your_customer_code" \
  -H "X-API-Key: sk-your-api-key-here" \
  --data-urlencode "session_id=a1b2c3d4-e5f6-7890-abcd-ef1234567890" \
  --data-urlencode "since_id=0"

知识库写入接口 KB

POST /api/v1/knowledge/entries

从外部系统向本企业知识库新增一条问答对,鉴权与 Chat 相同(X-Customer-Code + X-API-Key)。校验通过后先写入 MySQL并立即返回成功;向量嵌入与 Qdrant 同步在后台异步执行(与控制台 Excel 批量导入的第二阶段一致),稍后在智能对话中即可检索到该条。

配额与分类:受当前方案「知识库条数」限制。category 必须是贵企业知识库中已存在且未停用的分类名称,本接口不会自动创建分类;请先在控制台「知识库 → 分类管理」中建好分类,再用该分类名调用。若方案不支持配图,请勿传 answer_image。

请求参数 (JSON Body)

本接口请求体上限 512 KB(大于通用 v1 的 100 KB)。

字段类型必填说明
question string 必填 问题内容,trim 后非空,最大 800 字符。
answer string 必填 答案正文,trim 后非空,最大 5000 字符。
category string 必填 分类名称,最大 20 字符。必须是贵企业分类目录中已存在且未停用的分类名(与控制台「分类管理」一致);对不上或该分类已停用时返回 400,并在 data.existing_categories 中附带当前可用的分类名列表。本接口不会新建分类。
answer_image string 可选 答案配图,须为可访问的 http(s) 图片 URL,最大 2048 字符。仅专业版及以上支持;基础版传入将返回 403。
keywords string 可选 关键词,多个关键词用英文逗号 , 分隔(不可用中文逗号)。整段字符串最大 200 字符;单个关键词最长 20 字符;最多 10 个关键词。
created_by string 可选 对接方自定义的创建人标识(如对方系统用户名),最大 100 字符;便于与控制台「创建人」列对齐审计。

成功响应示例

{
  "success": true,
  "data": {
    "id": 12345,
    "category": "产品说明",
    "created_by": "crm_sync",
    "updated_by": null,
    "vector_sync": "queued",
    "message": "Entry saved to database. Vector embedding sync runs asynchronously; ..."
  }
}

配额不足示例(403)

{
  "success": false,
  "message": "Knowledge base entry limit reached for your plan (...)",
  "data": { "limit": 10000, "current": 10000, "remaining": 0 }
}

分类名对不上示例(400)

category 在分类目录中不存在、或该分类已停用时返回:

{
  "success": false,
  "message": "category \"未知分类\" does not exist as an enabled category in this customer's category catalog. Use one of data.existing_categories, or create the category in the console first.",
  "data": {
    "existing_categories": ["默认", "产品说明"]
  }
}

请求示例

curl -X POST https://agent.likelic.com/api/v1/knowledge/entries \
  -H "Content-Type: application/json" \
  -H "X-Customer-Code: your_customer_code" \
  -H "X-API-Key: sk-your-api-key-here" \
  -d '{
    "question": "如何重置密码?",
    "answer": "请在登录页点击「忘记密码」并按邮件指引操作。",
    "category": "账户与安全",
    "keywords": "password,reset,login",
    "answer_image": "https://example.com/help/screenshot.png"
  }'

更新单条知识(PUT)

PUT /api/v1/knowledge/entries/:id

使用创建接口返回的 data.id 作为路径参数 :id,更新同一条问答。请求体字段与 POST 相同,但 created_by 会被忽略(创建人不可改,响应回库中原值);请用可选字段 updated_by(最大 100 字符)作为本次修改人标识。若不传 answer_image,则保留该条原有配图。

字段类型必填说明
updated_by string 可选 本次更新的操作者标识,最大 100 字符。

更新成功响应示例

{
  "success": true,
  "data": {
    "id": 12345,
    "category": "产品说明",
    "created_by": "crm_sync",
    "updated_by": "operator_a",
    "vector_sync": "queued",
    "message": "Entry updated. Vector embedding sync runs asynchronously; ..."
  }
}
curl -X PUT https://agent.likelic.com/api/v1/knowledge/entries/12345 \
  -H "Content-Type: application/json" \
  -H "X-Customer-Code: your_customer_code" \
  -H "X-API-Key: sk-your-api-key-here" \
  -d '{
    "question": "如何重置密码?",
    "answer": "请在登录页点击「忘记密码」并按邮件指引操作。",
    "category": "账户与安全",
    "keywords": "password,reset",
    "updated_by": "operator_a"
  }'

合作客商写入 WEWORK PARTNER

POST /api/v1/wework/partner-companies/import

从外部系统批量写入合作客商主数据,鉴权与 Chat 相同(X-Customer-Code + X-API-Key)。按 (租户, company_code) upsert:company_code 已存在则合并更新,不存在则新增。行为与控制台「导入合作公司」Excel 导入完全一致。

启用方式:本能力默认关闭。需在控制台 → 系统设置 →「开放 API 权限」启用「合作客商写入」并授权至少一个 API Key(或在「合作公司」页「API 导入设置」中配置)。未启用或调用方 Key 未获授权时返回 403。控制台 Excel 导入不受此开关影响。
覆盖提示:upsert 为整行覆盖更新——同一 company_code 再次写入会覆盖销售、跟踪人、状态等已维护字段。无软删/版本机制,请确保来源数据准确。

请求参数 (JSON Body)

顶层字段 rows 为数组,非空且不超过 5000 行;每行字段如下:

字段类型必填说明
company_code string 必填 租户内唯一键,最大 64 字符。用于 upsert 定位:同一代码再次导入即更新该条。
company_name string 必填 公司全称,最大 255 字符。
company_short_name string 可选 公司简称,最大 128 字符。
sales_name string 可选 销售,最大 128 字符。
tracker_name string 可选 跟踪人,最大 128 字符。
company_status string 可选 合作状态。取中文 已合作 / 试用中 / 已过期,或枚举 cooperating / trial / expired;留空为未标记。传入非法值则该行被跳过。

行级校验

缺少 company_code 或 company_name、或 company_status 非法的行会被跳过并计入 data.skipped,跳过原因逐条列在 data.errors(不影响其余有效行写入)。

请求示例

curl -X POST https://agent.likelic.com/api/v1/wework/partner-companies/import \
  -H "Content-Type: application/json" \
  -H "X-Customer-Code: your_customer_code" \
  -H "X-API-Key: sk-your-api-key-here" \
  -d '{
    "rows": [
      {
        "company_code": "C1001",
        "company_name": "示例科技有限公司",
        "company_short_name": "示例科技",
        "sales_name": "张三",
        "tracker_name": "李四",
        "company_status": "已合作"
      },
      {
        "company_code": "C1002",
        "company_name": "另一家公司",
        "company_status": "trial"
      }
    ]
  }'

成功响应示例

{
  "success": true,
  "data": {
    "inserted": 1,
    "updated": 1,
    "skipped": 0,
    "errors": []
  }
}

含跳过行的响应示例

{
  "success": true,
  "data": {
    "inserted": 2,
    "updated": 0,
    "skipped": 1,
    "errors": ["第 3 行:缺少公司代码"]
  }
}

错误示例

// 未启用 wework_partner,或调用方 Key 未获授权 → 403
{ "success": false, "message": "开放 API「合作客商写入」未在系统设置中启用" }
{ "success": false, "message": "当前 API Key 未被授权调用「合作客商写入」接口" }
// rows 缺失/非数组,或超过 5000 行 → 400
{ "success": false, "message": "缺少 rows 数组" }
{ "success": false, "message": "单次最多导入 5000 行" }

服务绩效议题同步 WEWORK QA

GET /api/v1/wework/qa/issues

供外部系统(如部门管理系统)轮询拉取已评分的绩效议题,写入自有业务库。鉴权与 Chat / 知识库相同(X-Customer-Code + X-API-Key),无需 IP 白名单。

自 v10 起本接口同时返回 QQ 议题,请按 channel 字段区分入账。 现有对接方会开始收到 QQ 议题。若仍按「全部是企微群议题」入账,或用 company_name 关联客户,可能错账或关联不上。 增量游标拉不到上线前已评分的 QQ 议题:这些议题的 sync_at 早于对接方当前游标,增量轮询补不回这批历史记录,只有全量重拉(不传 sync_since)才能补齐。
名称更新:「企微绩效」已更名「服务绩效」,本接口报错文字随之更新;接口路径、HTTP 状态码与 code 不变,程序判断请以状态码与 code 为准,勿匹配文字。
套餐:仅旗舰版(Ultra)且已开通「服务绩效」的租户可用。开通 QQ 服务绩效的租户同时返回 QQ 群议题。仅返回已有评分的议题(assess_status 为 success 或 failed 均返回);数据范围与控制台绩效看板一致(保留期内)。

查询参数(列表)

参数类型必填说明
sync_since string 可选 增量游标:返回 sync_at >= sync_since 的议题。格式 YYYY-MM-DDTHH:mm:ss、YYYY-MM-DD HH:mm:ss 或 YYYY-MM-DD(当天 00:00:00)。不传则全量分页拉取。
page int 可选 页码,从 1 开始,默认 1。
limit int 可选 每页条数,默认 50,最大 100。

列表按 sync_at ASC, id ASC 排序,便于增量游标推进。响应 meta 含 page、limit、total、retention_from(生效保留起始日);传入 sync_since 时另回显 meta.sync_since。

列表响应 data[] 字段

字段类型说明
idnumber议题唯一 ID,建议作为对方系统 source_id 做幂等 upsert
channelstringwework 企微群 / qq QQ 群
company_namestring \| null群所属公司全称;若未维护则回退为群名称。QQ 群可在群管理里绑定合作公司;没绑定的 QQ 议题仍回退为 QQ 群名
company_statusstring \| null客户合作状态:已合作 / 试用中 / 已过期(未设置时为 null)。QQ 议题没绑定公司时为 null
summarystring \| null议题摘要
start_timestring议题在群聊中的开始时间
customer_namestring \| null客户展示名
statusstringopen / resolved / timeout
score_totalnumber \| null综合质量分 0–100;评分失败时为 null
assess_statusstringsuccess / failed
primary_staff_namestring \| null主责员工姓名(有效回复数最高;并列取第一个)
staffsarray参与员工:name、effective_reply_count
created_atstring议题入库时间(可作对方系统创建时间)
sync_atstring增量游标:末次值得同步的变化时间(状态变更 / 首次评分 / 人工重评)
字段映射:类型、备注等业务字段由对接方自行决定,本接口不提供。员工标识仅返回姓名,账号映射由对方系统处理。

列表响应示例

{
  "success": true,
  "data": [
    {
      "id": 12345,
      "channel": "wework",
      "company_name": "示例科技有限公司",
      "company_status": "已合作",
      "summary": "客户反馈产品无法登录",
      "start_time": "2026-06-24T10:30:00",
      "customer_name": "张三",
      "status": "resolved",
      "score_total": 85,
      "assess_status": "success",
      "primary_staff_name": "李四",
      "staffs": [
        { "name": "李四", "effective_reply_count": 3 },
        { "name": "王五", "effective_reply_count": 1 }
      ],
      "created_at": "2026-06-24T10:35:00",
      "sync_at": "2026-06-24T10:40:00"
    }
  ],
  "meta": {
    "page": 1,
    "limit": 50,
    "total": 128,
    "retention_from": "2026-05-25",
    "sync_since": "2026-06-24T10:00:00"
  }
}

推荐同步流程

  1. 首次全量:不传 sync_since,按 page 分页直至 data 为空;每条以 id upsert。
  2. 增量轮询(建议 5–15 分钟):sync_since = 上次 max(sync_at) - 1 分钟(重叠防漏);同一 id 再次出现则 UPDATE。
  3. 停服恢复:沿用旧 sync_since 即可补回期间变更。
  4. 多页:同一 sync_since 下若 total > limit,继续 page=2,3,... 直至拉完本批。

请求示例(增量拉取)

curl -G "https://agent.likelic.com/api/v1/wework/qa/issues" \
  -H "X-Customer-Code: your_customer_code" \
  -H "X-API-Key: sk-your-api-key-here" \
  --data-urlencode "sync_since=2026-06-24T10:00:00" \
  --data-urlencode "page=1" \
  --data-urlencode "limit=100"

单条详情 GET /api/v1/wework/qa/issues/:id

GET /api/v1/wework/qa/issues/:id

返回字段与列表项相同,用于按 ID 补拉或校验。路径参数 :id 为议题 ID。

curl "https://agent.likelic.com/api/v1/wework/qa/issues/12345" \
  -H "X-Customer-Code: your_customer_code" \
  -H "X-API-Key: sk-your-api-key-here"

成功返回 { "success": true, "data": { ... } };不存在、未评分或超出保留期返回 404。

推送通知 OUTBOUND

推送通知让你的业务系统(ERP、CRM、计费系统等)通过开放 API,经企微机器人或 QQ 机器人向客户所在的企微群 / QQ 群发送通知,例如「贵司服务将于 30 天后到期」。业务系统只管提交,平台负责找到目标群、按时段排队、控制发送节奏,并提供逐群回执。本能力共四个接口:

接口用途
GET /api/v1/rooms接口一:查询群清单(可作为通知目标的企微群与 QQ 群)
POST /api/v1/notifications接口二:下发通知(受理后返回 202,后台排队发送)
GET /api/v1/notifications/{biz_msg_id}接口三:查询回执(逐群发送结果与整条聚合状态)
POST /api/v1/notifications/{biz_msg_id}/cancel接口四:撤回通知(取消尚未发出的群,已发出的不可撤回)
套餐:推送通知为专业版 / 旗舰版(Pro / Ultra)能力,基础版调用会返回 403 plan_required。

适用场景

  • 合同 / 服务到期前的续费提醒(如到期前 30 / 15 / 7 / 1 天各提醒一次)。
  • 账单、发货、单证等业务状态变化时通知客户群。
  • 需要在消息里 @ 对接人(如「如需续费请联系@张三 」)。

只发群,不发私聊;支持纯文本,以及最多 3 个附件(图片、文件、链接卡片);一次请求提交一条通知,不支持批量或修改;尚未发出的部分可以撤回。

启用方式

启用方式:本能力默认关闭,从未保存过开放 API 权限的企业也须显式开启。需在控制台 → 系统设置 →「开放 API 权限」中打开「推送通知」,并勾选允许调用的 API Key,保存。未开启或 Key 未被勾选时,四个接口都返回 403 scope_disabled。
  1. 准备 API 密钥:在控制台「外部拓展 → API 设置」创建一个 sk- 开头的密钥,建议单独给推送通知使用。密钥只能放在你自己的后端,切勿写进前端代码。
  2. 授权 Key:在「系统设置 → 开放 API 权限」中打开「推送通知」,并勾选允许调用的 API Key,保存。
  3. 设置允许推送时段(可选):在「系统设置 → 允许推送时段」中配置(北京时间)。默认 09:00–11:00 与 14:00–17:00 两段;清空全部时段表示不限时段、随时可发。
  4. 绑定群与公司(按公司发送时需要):在「合作管理 → 群管理」给客户群填上公司代码(可先导入合作公司再自动匹配)。只按群 ID 发送时可跳过这一步。
  5. QQ 群需群主开通主动推送:群主在群内打开「机器人主动在群聊内发言」,否则发往该群的通知会被跳过。

之后若在系统设置里关闭「推送通知」,已受理但还没发出的通知也会一并停止发送(回执中落 failed,原因 scope_disabled),重新开启后不会自动恢复,需要业务系统重新下发。

通用约定

项目约定
接口地址https://agent.likelic.com/api/v1
鉴权与其他开放 API 相同,Header 携带 X-Customer-Code(企业唯一代码)与 X-API-Key(sk- 开头,须已在「推送通知」中被授权)
请求体JSON(Content-Type: application/json)
响应格式成功为 { "success": true, "data": ..., "meta": ... }(meta 仅列表接口有);失败为 { "success": false, "message": "...", "code": "..." }。请按 HTTP 状态码 + code 联合判断,message 是给人看的说明,可能调整,不要用于程序分支。参数校验失败(400)时另带 field 指明出错字段
时间所有时刻都是带 +08:00 偏移的 ISO 8601 字符串(北京时间),如 2026-10-24T09:37:00.000+08:00,无论调用方在哪个时区都能直接解析。「当天」「次日」一律按北京自然日计
分页列表接口用 page(从 1 开始,默认 1)与 limit(默认 20,最大 200),响应的 meta 为 { page, limit, total }

接口一:查询群清单 GET /api/v1/rooms

GET /api/v1/rooms

拉取本企业全部可作为通知目标的企微群与 QQ 群。常用于:① 在自己系统里做「客户 ↔ 群」绑定(用于按群 ID 发送);② 核对哪些群还没绑公司、哪些群当前推不出去。

查询参数(均可选)

参数类型必填说明
channelstring可选wework 或 qq
company_codestring可选只看绑定了该公司代码的群
push_statestring可选ready、blocked 或 unknown
pageint可选页码,从 1 开始,默认 1
limitint可选每页条数,默认 20,最大 200

取值非法时返回 400 validation_error,不会静默忽略。结果固定按 channel → room_name → room_id 升序排列,翻页不会漏项或重复。没有任何群时返回 200、data 为空数组、meta.total 为 0。

请求示例

curl -G "https://agent.likelic.com/api/v1/rooms" \
  -H "X-Customer-Code: your_customer_code" \
  -H "X-API-Key: sk-your-api-key-here" \
  --data-urlencode "company_code=ACME01" \
  --data-urlencode "page=1" \
  --data-urlencode "limit=20"

响应示例

{
  "success": true,
  "data": [
    {
      "channel": "wework",
      "instance_id": 3,
      "instance_name": "售后企微机器人",
      "room_id": "10696049xxxxxxxxx",
      "room_name": "艾克米物流售后群",
      "member_count": 12,
      "company_code": "ACME01",
      "company_name": "艾克米物流",
      "company_match_status": "auto",
      "push_state": "ready",
      "push_blocked_reason": null
    }
  ],
  "meta": { "page": 1, "limit": 20, "total": 1 }
}

响应 data[] 字段

企微群与 QQ 群字段完全一致,只靠 channel 区分;没有值的字段返回 null,不会省略。

字段类型说明
channelstringwework 或 qq
instance_idnumber机器人实例 ID(数字)
instance_namestring | null机器人实例名称
room_idstring群 ID(按群发送时使用)
room_namestring | null群名称
member_countnumber | null群成员数
company_code / company_namestring | null绑定的公司代码 / 全称,未绑定为 null
company_match_statusstring | null公司匹配方式:auto(自动匹配)、manual(人工填写)、pending(匹配待定,尚未绑定)或 null
push_statestring可推送状态,见下表
push_blocked_reasonstring | nullpush_state 为 blocked 时的原因,其余为 null

可推送状态 push_state

push_statepush_blocked_reason含义发通知会怎样
readynull可正常推送正常排队发送
unknownnull仅 QQ 群:还没试发过,不知道群主是否开通主动推送正常排队、照常尝试
blockedinstance_offline机器人实例离线(企微掉线 / 登录失效,QQ 实例被停用),人工处理后可恢复照常受理,排队等实例恢复
blockedbot_not_in_room曾因机器人不在群而发送失败跳过,直至运营检测后清除
blockedproactive_push_disabled仅 QQ 群:群主未开通主动推送跳过,直至群主开通并检测

push_state 与是否绑定公司无关:未绑公司但可推送的群仍是 ready,可以按群 ID 直接发送。已删除的机器人实例下的群不会出现在清单里。

接口二:下发通知 POST /api/v1/notifications

POST /api/v1/notifications

提交一条通知。平台当场解析目标群、生成逐群投递单并返回 202;实际发送由平台按时段与节奏在后台完成,本接口不返回发送结果,请用接口三查询回执。

请求参数 (JSON Body)

字段类型必填说明
biz_msg_idstring必填业务幂等键,1~128 个字符,不能全为空白,不能以 console-probe- 开头(系统保留)。比较时不区分大小写、忽略尾随空格,见下文「幂等与重复提交」
targetobject必填发给谁,四种形态恰好选一种,见下表
textstring条件必填通知正文,纯文本;不带 attachments 时必填,带附件时可省略。去掉首尾空白后不能为空,且不超过 1000 个字符(按 Unicode 字符计,一个汉字或一个 emoji 都算 1 个)。首尾空白会被去掉
attachmentsarray可选附件,1~3 项;每项 type 为 image、file 或 link,字段见下文「附件」
urgentboolean可选默认 false。true 表示紧急通知,不受允许推送时段限制,见下文「推送时段与排期」

target 的四种形态

形态写法说明
按公司代码{ "company_code": "ACME01" }发到绑定了该公司代码的全部群(如售前群、售后群都会收到)。可另加 "channel": "wework" 或 "qq" 只发一个渠道,不加则两个渠道都发
按公司全称{ "company_name": "艾克米物流" }按合作公司全称精确匹配后,同样发到该公司的全部群;也可另加 channel
按群{ "channel": "qq", "instance_id": 12, "room_id": "..." }三个字段须同时提供,取自接口一的返回项;只发这一个群
按会话串{ "conversation": "R:{群ID}@{成员ID}" }直接指定群,并可在消息开头 @ 成员,见下文「会话串定位与开头 @」
  • 同时给了两种形态,或一种都没给 → 400 validation_error。
  • 按公司全称匹配到多家同名公司时不会自动挑选,返回 409 company_name_ambiguous 并在 data.candidates 列出每家的 company_code 与 company_name,请改用公司代码重发。
  • 同一个群被多个机器人收录时只发一次:按公司发送时,平台按群去重,同一个企微群(或 QQ 群)即使被本企业多个机器人实例收录,也只生成一条投递单,由其中推送状态最好的实例发送。

附件(attachments)

一条通知最多带 3 个附件,写在请求体的 attachments 数组里;带附件时 text 可省略(无正文也无附件则返回 400 validation_error,field 为 text)。每项按 type 取下列字段:

type字段说明
imageurl 或 base64(二选一)、file_name(可选)图片;url 为不超过 1024 个字符的 http(s) 地址;file_name 最长 100 个字符,缺省时按「图片 序号.扩展名」补齐
fileurl 或 base64(二选一)、file_name(必填)文件;file_name 最长 100 个字符,QQ 里下载得到的文件名就是它
linktitle(必填,≤ 64 个字符)、url(必填,≤ 1024 个字符)、description(可选,≤ 200 个字符)、image_url(可选,≤ 1024 个字符)链接卡片;回执里给出的是实际目标地址
  • image / file 的 url 与 base64 不能同时给、也不能都不给,否则 400 validation_error(field 形如 attachments[1].url)。
  • 平台在受理时把图片与文件转存到自己的存储再发送;url 须能被公网访问,转存时的抓取最多等待 30 秒。
  • 图片支持 jpg / jpeg / png / gif / webp / bmp,单个不超过 10MB;文件支持 pdf / doc / docx / xls / xlsx / ppt / pptx / txt / csv / zip / rar,单个不超过 20MB。
  • 类型按文件实际内容判定,改扩展名无效;可执行文件(Windows / Linux / macOS 可执行程序、带解释器声明的脚本)一律拒绝。

附件被拒绝时返回 400 attachment_rejected,并带 index(第几个附件,从 0 计)与 reason;被拒绝的请求不占用 biz_msg_id,修正后可用同一个键重新提交。

reason含义
fetch_failed按 url 抓取失败(无法访问、返回错误状态等)
fetch_timeout抓取超时
unsafe_url地址不被允许(内网地址、非 http(s) 等)
too_large超过大小上限(图片 10MB、文件 20MB)
type_not_allowed实际类型不在白名单内,或与声明的类型不符
executable识别为可执行文件

附件在两个渠道里的呈现

  • 企微群:正文在前,然后逐条发出原生的图片、文件和链接卡片。
  • QQ 群:正文与全部附件合成一条消息——图片与文件写成下载链接,链接卡片写成「标题:链接」;下载得到的文件名为你给的 file_name。
  • QQ 合成长度校验:目标含 QQ 群时,平台按合成后的纯文本计算长度,超过 2000 字受理时即返回 400 qq_message_too_long(带实际长度 length 与上限 limit),不截断正文、不丢附件,也不占用 biz_msg_id;目标只含企微群时不做此校验。
  • 部分送达(例如企微里正文已发出、后面的附件失败)按失败处理,回执里 parts_delivered / parts_total 记录送达进度;重投或续发只补发未送达的部分。

带附件的完整请求示例

curl -X POST https://agent.likelic.com/api/v1/notifications \
  -H "Content-Type: application/json" \
  -H "X-Customer-Code: your_customer_code" \
  -H "X-API-Key: sk-your-api-key-here" \
  -d '{
    "biz_msg_id": "renew-ACME01-2026-10-24-d7",
    "target": { "company_code": "ACME01" },
    "text": "贵司服务将于 7 天后到期,续费资料见附件。",
    "attachments": [
      { "type": "file", "url": "https://example.com/quote.pdf", "file_name": "续费报价单.pdf" },
      { "type": "link", "title": "在线续费", "url": "https://example.com/renew" }
    ]
  }'

会话串定位与开头 @(target.conversation)

除按公司、按群外,还可以用会话串直接指定群,并在消息开头 @ 成员:

  • 企微群:R:{群ID}@{成员ID}@{成员ID}
  • QQ 群:{group_openid}@{成员ID}(不带 R: 前缀)

示例(均为占位 ID,请换成你自己的):{ "conversation": "R:1078xxxxxxxxxxxx@1688xxxxxxxxxxxx" }。规则:

  • 平台按格式标记判定渠道(有 R: 为企微,无前缀为 QQ);可以另给 channel,但与格式矛盾时报错。
  • 成员最多 20 个;成员之间不能有空段、重复或空白;总长不超过 512。非法写法(如 R:1078@a@@b、显式给了 channel: "qq" 却以 R: 开头、21 个成员)返回 400 validation_error,field 为 target.conversation。没写 channel 时,以 R: 开头一律按企微群处理:把 QQ 群串误加了 R: 会被当成企微群查找,通常返回 404 room_not_found,而不是 400。
  • conversation 与公司代码、公司全称、按群三种定位方式互斥,同时出现返回 400。
  • 该群在本企业所有未删除的实例下都没有收录时返回 404 room_not_found;实例由平台按群自动定位。

会话串里的成员会在正文那一条消息的开头依次被 @(企微在群内 @,QQ 按出站提及格式),之后紧接正文,只发一条。正文里的 @姓名 照常解析,同一成员只 @ 一次;成员 ID 不在群内时消息照常发送,并在回执 warnings 里记一条;QQ 实例关闭 markdown 时放弃提及。带附件时 @ 只附在正文那一条上,没有正文时开头只含 @。

请求体大小与并发限制

  • 下发接口的请求体上限为 85MB(带 base64 附件时留意体积),超限返回 413 payload_too_large。
  • 同一租户同时处理的大请求(超过 2MB)最多 4 个,超出返回 429 too_many_large_requests,请稍后重试。
  • 同一个 biz_msg_id 并发提交时,后到的请求可能返回 409 notification_in_progress,稍等片刻用接口三查询回执即可。

以上 400 / 413 / 429 都表示整条不受理,不生成投递单,也不占用 biz_msg_id。

请求示例

curl -X POST https://agent.likelic.com/api/v1/notifications \
  -H "Content-Type: application/json" \
  -H "X-Customer-Code: your_customer_code" \
  -H "X-API-Key: sk-your-api-key-here" \
  -d '{
    "biz_msg_id": "renew-ACME01-2026-10-24-d30",
    "target": { "company_code": "ACME01" },
    "text": "您好,贵司的 XXX 服务将于 2026 年 10 月 24 日到期,您请看是否安排续费,如需续费请联系@张三 ,谢谢您的支持!"
  }'

首次受理响应示例(202)

{
  "success": true,
  "data": {
    "notification_id": 1024,
    "biz_msg_id": "renew-ACME01-2026-10-24-d30",
    "duplicate": false,
    "summary": { "total": 2, "queued": 1, "skipped": 1 },
    "deliveries": [
      {
        "delivery_id": 5001,
        "channel": "wework",
        "instance_id": 3,
        "room_id": "10696049xxxxxxxxx",
        "room_name": "艾克米物流售后群",
        "company_code": "ACME01",
        "company_name": "艾克米物流",
        "status": "pending",
        "skip_reason": null,
        "scheduled_at": "2026-09-28T09:37:00.000+08:00"
      },
      {
        "delivery_id": 5002,
        "channel": "qq",
        "instance_id": 12,
        "room_id": "C9F3A2xxxxxxxxxxxxxxxxxxxxxxxxxx",
        "room_name": "艾克米物流服务群",
        "company_code": "ACME01",
        "company_name": "艾克米物流",
        "status": "skipped",
        "skip_reason": "proactive_push_disabled",
        "scheduled_at": null
      }
    ]
  }
}
  • summary 满足 queued + skipped = total;deliveries 固定按 delivery_id 升序。
  • 受理时即可判定发不进去的群(bot_not_in_room、proactive_push_disabled)直接落 skipped,不会进入发送队列;实例离线不算跳过,照常排队。
  • 全部目标群都被跳过时返回 409 all_targets_skipped,data.deliveries 逐条列出群与 skip_reason,本次不受理、不占用 biz_msg_id——群主开通或机器人重新进群、并在合作管理中完成检测后,可用同一个 biz_msg_id 重新提交。
  • 任何 4xx 都表示整条不受理,一条投递单都不会生成,修正后重发即可。

推送时段与排期

  • 受理时若当前时刻(北京时间)落在允许推送时段内,scheduled_at 即为当前时刻;若在时段外,则排到下一个时段内的随机时刻(按分钟),同一批通知的发送时刻会被自然打散,不会半夜打扰客户,也不会在同一时刻集中发出。
  • urgent: true 时不受时段限制,scheduled_at 为受理时刻;但每日发送上限等保护照常生效——urgent 只放宽「什么时候发」,不放宽「能不能发」。
  • 平台会在同一个机器人的相邻两条消息之间自动留出间隔,并与消息群发共用企微实例的每日发送上限。当天额度用完、或时段配置变更后已不在时段内时,投递单保持 pending,scheduled_at 顺延到之后的时段,不会因此失败。因此 scheduled_at 是计划时刻,可能随排队情况后移。

幂等与重复提交

  • biz_msg_id 在本企业内唯一。重复提交相同的 biz_msg_id 返回 200、duplicate: true,并回吐首次生成的 notification_id 与投递单当前状态(字段同接口三的 deliveries),不会新建投递单,也不会用本次请求的其他字段覆盖首次内容。并发重复提交同样只会受理一次。summary 为首次受理时的快照(排队 / 跳过计数不随投递进展变化),不能用来判断是否已发出;实时状态以 deliveries[].status 或接口三 GET /api/v1/notifications/{biz_msg_id} 为准。
  • biz_msg_id 比较时不区分大小写、忽略尾随空格:例如 Order-a1 与 order-A1 视为同一个键。请不要依赖大小写或尾随空格来区分不同的通知,否则后一条会被当作重复提交而不会发出。
  • 建议用「业务对象 + 业务日期 + 提醒轮次」拼出稳定的键,例如 renew-ACME01-2026-10-24-d30;重试或跑批重复执行时沿用同一个键即可,客户不会收到两条相同提醒。

@ 提及的书写约定

正文里写 @姓名 可以在群里 @ 到对应的人(被 @ 的人会收到提醒),常用于「如需续费请联系@张三 」:

  • @姓名 后必须加一个空格(或换行),如 请联系@张三 ,谢谢。平台取 @ 到下一个空白之间的整段文字作为姓名、并要求完全相等,所以 @张三,谢谢、@张三您好 这类连写不会被识别;群里同时有「张三」和「张三丰」时,@张三 只会 @ 到「张三」。
  • @ 可以出现在正文任意位置。找不到这个人、或本群有多个同名的人时,平台不会乱 @,@姓名 按纯文本原样发出,消息照常送达,并在该投递单的 warnings 中说明。
  • 优先匹配本企业员工(员工需在控制台「成员与权限」绑定企微 / QQ 身份),其次匹配群成员;被 @ 的人必须在该群内。
  • 不支持 @所有人,不支持按手机号或工号 @ 人。

QQ 群的额外限制(渠道差异,不是故障):

  • QQ 只能 @ 在本群有发言记录的人。QQ 实例默认的「仅 @ 回复」模式下,机器人只收到 @ 它的消息,所以只有在本群 @ 过机器人的人才 @ 得到,命中率低;把实例改为「全量消息作上下文,仅 @ 回复」后命中率会明显提升。
  • 客户看到的是对方的 QQ 群昵称,不是正文里写的姓名。
  • 员工的 QQ 身份按机器人绑定,换一个 QQ 机器人须重新绑定。
  • 链接后面紧跟文字时,平台会在链接末尾自动补一个空格,否则 QQ 会把后面的文字并入链接、点开是错误地址。这是正文「原样发出」的唯一例外。
  • 行首缩进不会显示;带 ? & # 等参数的链接可能无法点击,但文字逐字正确、可以复制。

接口三:查询回执 GET /api/v1/notifications/{biz_msg_id}

GET /api/v1/notifications/{biz_msg_id}

用下发时的 biz_msg_id 查询这条通知发到了哪些群、是否发出(biz_msg_id 放进 URL 路径时请做 URL 编码)。biz_msg_id 在本企业下不存在时返回 404 notification_not_found。

请求示例

curl "https://agent.likelic.com/api/v1/notifications/renew-ACME01-2026-10-24-d30" \
  -H "X-Customer-Code: your_customer_code" \
  -H "X-API-Key: sk-your-api-key-here"

响应示例

{
  "success": true,
  "data": {
    "notification_id": 1024,
    "biz_msg_id": "renew-ACME01-2026-10-24-d30",
    "target_kind": "company_code",
    "target_value": "ACME01",
    "text": "您好,贵司的 XXX 服务将于 2026 年 10 月 24 日到期,您请看是否安排续费,如需续费请联系@张三 ,谢谢您的支持!",
    "urgent": false,
    "accepted_at": "2026-09-27T20:15:03.000+08:00",
    "attachments": [],
    "cancelled_at": null,
    "cancel_source": null,
    "cancel_reason": null,
    "status": "sent",
    "summary": { "total": 2, "queued": 0, "sent": 1, "failed": 0, "skipped": 1, "cancelled": 0 },
    "deliveries": [
      {
        "delivery_id": 5001,
        "channel": "wework",
        "instance_id": 3,
        "instance_name": "售后企微机器人",
        "room_id": "10696049xxxxxxxxx",
        "room_name": "艾克米物流售后群",
        "company_code": "ACME01",
        "company_name": "艾克米物流",
        "status": "sent",
        "skip_reason": null,
        "scheduled_at": "2026-09-28T09:37:00.000+08:00",
        "sent_at": "2026-09-28T09:37:04.000+08:00",
        "attempts": 0,
        "parts_total": 1,
        "parts_delivered": 1,
        "last_error_code": null,
        "warnings": null,
        "retry_of_delivery_id": null,
        "source": "open_api"
      },
      {
        "delivery_id": 5002,
        "channel": "qq",
        "instance_id": 12,
        "instance_name": "QQ 服务机器人",
        "room_id": "C9F3A2xxxxxxxxxxxxxxxxxxxxxxxxxx",
        "room_name": "艾克米物流服务群",
        "company_code": "ACME01",
        "company_name": "艾克米物流",
        "status": "skipped",
        "skip_reason": "proactive_push_disabled",
        "scheduled_at": null,
        "sent_at": null,
        "attempts": 0,
        "parts_total": 1,
        "parts_delivered": 0,
        "last_error_code": null,
        "warnings": null,
        "retry_of_delivery_id": null,
        "source": "open_api"
      }
    ]
  }
}

响应 data 字段

字段说明
notification_id平台生成的通知 ID
biz_msg_id首次提交时的业务幂等键
target_kindcompany_code、company_name、room 或 conversation
target_value定位值;按群发送时为 渠道:实例ID:群ID,按会话串发送时为原会话串
text通知正文
urgent是否紧急通知
accepted_at受理时刻
attachments通知的附件列表,每项 { seq, type, file_name, title, description, url, thumb_url, size }(不适用的字段为 null);图片与文件的 url 为平台转存后的地址,链接卡片的 url 为实际目标地址;无附件为空数组
cancelled_at / cancel_source / cancel_reason撤回时刻、来源(open_api 或 console)与原因;未撤回均为 null
status整条通知的聚合状态,见下文「聚合状态与轮询」
summary{ total, queued, sent, failed, skipped, cancelled }
deliveries全部投递单(含控制台重投产生的),按 delivery_id 升序

deliveries[] 每项字段

字段说明
delivery_id投递单 ID
channel / instance_id / instance_name渠道与发送所用的机器人实例
room_id / room_name目标群
company_code / company_name公司
statuspending(排队中,含发送中)、sent(已发送)、failed(失败)、skipped(已跳过)、cancelled(已撤回)
parts_total / parts_delivered分段送达进度:企微每条消息(正文、每个附件)算一段,QQ 恒为 1 段;受理时 parts_delivered 为 0
skip_reasonstatus 为 skipped 时必有值:bot_not_in_room 或 proactive_push_disabled;其余为 null
scheduled_at计划发送时刻(skipped 为 null)
sent_at实际发送时刻,未发送为 null
attempts已计次的重试次数
last_error_codestatus 为 failed 时的失败码,见下文「失败码」;其余为 null
warnings提醒数组(如某个 @ 未命中),没有为 null;有提醒不代表失败
retry_of_delivery_id由控制台重投产生时,指向被重投的那条;否则为 null
source来源:open_api(开放 API 下发)、mcp(经 MCP 工具 send_notification 下发)、console_retry(控制台重投)、console_probe(控制台检测)

群名、实例名、公司名记录的是发送当时的名称,之后改名不影响回执。pending 不区分排队原因(等时段、等间隔、当天额度已满、实例离线、发送中都是 pending),但 scheduled_at 会反映顺延后的时刻。

聚合状态与轮询

整条通知的 status 与 summary 以每个目标群的最终结果为单位统计:同一个群被控制台重投过时只看最后一次投递,console_probe 来源的投递单不参与统计。summary.total 等于目标群数(重投不增加),恒有 queued + sent + failed + skipped + cancelled = total。

status条件
pending还有群在排队(queued > 0)
sent全部群都已发送
partially_sent部分群发送成功(其余为失败、跳过或已撤回)
failed没有任何群发送成功,且存在失败的群
cancelled没有任何群发送成功、没有失败的群,且存在已撤回的群(撤回前已被跳过的群不影响)
轮询建议:受理后间隔几分钟查询一次,见到 status 不是 pending 即可停止轮询。时段外受理的通知要到下一个时段才会发出,请据 scheduled_at 安排查询时间,避免无意义的高频轮询。每条投递单自创建起最长 72 小时内一定会有结果(发出、或落 failed)。若之后运营在控制台手工重投,整条通知会回到 pending 并重新收敛。

指令头 status 按以下顺序判定:queued > 0 → pending;全部已发送 → sent;有群已发送 → partially_sent;有失败 → failed;有已撤回 → cancelled;其余 → failed。因此只有在没有任何群发送成功时,才会与 v11 的判定结果不同(撤回后为 cancelled)。

例如一条通知命中群 A、群 B,A 发送成功、B 失败:status 为 partially_sent,summary 为 { total: 2, queued: 0, sent: 1, failed: 1, skipped: 0, cancelled: 0 };运营重投 B 且成功后,deliveries 共 3 条,status 变为 sent,summary 为 { total: 2, queued: 0, sent: 2, failed: 0, skipped: 0, cancelled: 0 }。

失败码(last_error_code)

投递单为 failed 时,last_error_code 必为以下 11 个值之一:

失败码含义建议
bot_not_in_room机器人不在群内把机器人重新拉进群,运营在合作管理中检测后重投或重新下发
proactive_push_disabledQQ 群主未开通主动推送请群主开通,检测后重投或重新下发
room_not_found发送前发现目标群记录已不存在核对群清单
instance_deleted目标群所属的机器人实例已删除换其他实例所在的群
qq_api_errorQQ 返回了业务错误联系运营查看投递记录中的原因
wework_api_error企微机器人返回了业务错误联系运营查看投递记录中的原因
send_result_unknown请求已发出但未得到明确结果,可能已送达平台不会自动重发,以免客户收到两条;请先到群里核实,确未收到再由运营重投
scope_disabled发送前发现「推送通知」已被关闭重新开启后由业务系统重新下发
plan_required发送前发现套餐已不支持推送通知升级套餐后重新下发
retry_exhausted可重试的错误多次重试后仍失败稍后重新下发,或联系运营
retry_window_expired超过重试时限仍未发出(如实例长时间离线)恢复实例后重新下发或由运营重投

机器人实例临时掉线、平台限流等可恢复的情况不会直接判失败,投递单保持 pending 并自动延后重试。

跳过原因(skip_reason)

跳过原因含义
bot_not_in_room该群此前因机器人不在群而发送失败,平台不再往该群发,直至运营在合作管理 → 群管理对该群执行「后续检测」或「实时检测」,或该群收到新的消息
proactive_push_disabled该 QQ 群此前因群主未开通主动推送被拒,直至群主开通、运营检测后才会再发

skipped 是终态,平台不会自动补发。阻塞解除后,可由运营在投递记录中重投,或业务系统用新的 biz_msg_id 重新下发。

在控制台查看与重投

运营可在控制台「合作管理 → 投递记录」按公司名、群名或 biz_msg_id 查看每个群的投递结果,并对失败或已跳过的记录手工重投:

  • 重投新建一条投递单(source 为 console_retry,retry_of_delivery_id 指向原记录),原记录保留不变,会同时出现在回执的 deliveries 中;同一条记录只能重投一次。
  • 重投按允许推送时段排队,不继承 urgent。
  • 重投后整条通知的回执 status 会回到 pending,直至新投递单有结果;带附件的通知重投时只补发未送达的部分。
  • 运营点某行的小眼睛可打开通知预览(正文、附件、各群投递与送达进度、撤回记录),并在预览里撤回整条通知;已撤回通知的失败行显示「不可重投」,重投会返回 409 notification_cancelled。
  • 运营在群管理对 QQ 群做「实时检测」时发出的测试消息属于控制台检测(console_probe),不会出现在开放 API 的回执中。

接口四:撤回通知 POST /api/v1/notifications/{biz_msg_id}/cancel

POST /api/v1/notifications/{biz_msg_id}/cancel

撤回一条通知尚未发出的部分。只取消排队中的群,已发出的群无法撤回;撤回即整条作废,不可恢复——其中失败的群也不能再由控制台重投。biz_msg_id 放进 URL 路径时请做 URL 编码;本企业下不存在时返回 404 notification_not_found。

请求参数 (JSON Body)

字段类型必填说明
reasonstring可选撤回原因,去掉首尾空白后不超过 200 个字符,空串视为未填;超长返回 400 validation_error,field 为 reason

请求示例

curl -X POST "https://agent.likelic.com/api/v1/notifications/renew-ACME01-2026-10-24-d7/cancel" \
  -H "Content-Type: application/json" \
  -H "X-Customer-Code: your_customer_code" \
  -H "X-API-Key: sk-your-api-key-here" \
  -d '{ "reason": "客户已续约,通知作废" }'

响应示例(200)

{
  "success": true,
  "data": {
    "biz_msg_id": "renew-ACME01-2026-10-24-d7",
    "status": "partially_sent",
    "cancelled_at": "2026-09-28T10:05:00.000+08:00",
    "cancelled_count": 1,
    "results": [
      { "delivery_id": 5001, "channel": "wework", "room_id": "10696049xxxxxxxxx", "room_name": "艾克米物流售后群", "outcome": "cancelled" },
      { "delivery_id": 5002, "channel": "qq", "room_id": "C9F3A2xxxxxxxxxxxxxxxxxxxxxxxxxx", "room_name": "艾克米物流服务群", "outcome": "sent" }
    ]
  }
}
  • status 是撤回后按上文规则重新聚合的整条通知状态;cancelled_count 为本次实际撤回的群数。
  • 幂等:对已撤回的通知再次撤回返回 200,cancelled_count 为 0 并带 message: "无可撤回项",撤回时刻与原因保持第一次的记录。
  • 部分送达的投递被撤回后保留已送达进度(parts_delivered 不变),状态为 cancelled。
  • 撤回后用同一个 biz_msg_id 再次提交下发,只会返回原来的回执,不会重新发送;要重发请换一个新的 biz_msg_id。
results[].outcome含义
cancelled本次撤回成功,该群不会再发送
sent已发出,无法撤回
sending正在发送中,结局以最终发送结果为准,无法撤回
already_final原本就是失败、已跳过或已撤回,本次不处理

错误码(推送通知)

HTTPcode出现在含义
400validation_error接口一、二、四参数不合法,field 与 message 指明字段
400attachment_rejected接口二附件被拒绝,index 指明第几个附件,reason 见「附件」一节;不占用 biz_msg_id
400qq_message_too_long接口二目标含 QQ 群且合成纯文本超过 2000 字,带 length 与 limit;不占用 biz_msg_id
403plan_required全部套餐不支持推送通知(基础版)
403scope_disabled全部未开启「推送通知」,或当前 Key 未被授权
404company_not_found接口二按公司代码或全称找不到该合作公司
404room_not_found接口二按群或会话串发送时,该群不存在、不属于本企业或所属实例已删除
404notification_not_found接口三、四本企业下没有该 biz_msg_id
409company_name_ambiguous接口二存在多家同名公司,data.candidates 列出候选
409company_unmatched接口二公司存在,但还没有绑定任何可推送的群
409all_targets_skipped接口二目标群全部被跳过,本次不受理,data.deliveries 列出原因
409notification_in_progress接口二同一 biz_msg_id 的另一个请求正在受理,稍后用接口三查询回执
413payload_too_large接口二请求体超过 85MB
429too_many_large_requests接口二同一租户同时处理的大请求(超过 2MB)已达 4 个,稍后重试
500internal_error全部服务端异常,可稍后用同一个 biz_msg_id 重试

以下情况发生在进入本能力之前,响应不带 code,与其他开放 API 一致:401(缺少鉴权 Header 或格式错误)、403 且无 code(Key 无效、已停用、已过期或与企业代码不匹配)、429(超过该 Key 的速率限制)、400 / 413(请求体不是合法 JSON 或超过大小限制;下发接口超过 85MB 时例外,返回带 code 的 payload_too_large)。

错误响应示例

// 按公司全称匹配到多家同名公司 → 409
{
  "success": false,
  "code": "company_name_ambiguous",
  "message": "...",
  "data": {
    "candidates": [
      { "company_code": "ACME01", "company_name": "艾克米物流" },
      { "company_code": "ACME02", "company_name": "艾克米物流" }
    ]
  }
}

错误码说明

状态码错误信息说明
400Question is required and must be a string请求体缺少 question 字段或类型不是字符串
400Question cannot be emptyquestion 为空字符串或仅包含空白字符
400Question exceeds maximum length of 800 characters问题内容超过 800 字符上限
400Invalid template_id formattemplate_id 格式不正确,应为 18-32 位字母数字组合
400Invalid session_id formatsession_id 格式不正确,应为字符串且最长 36 位
400Invalid template_id指定的 template_id 不存在
400Template does not belong to this customer该模板不属于当前企业
401Missing API Key or Customer Code in headers请求头缺少 X-API-Key 或 X-Customer-Code
401Invalid API Key formatAPI Key 格式不正确,应以 sk- 开头后跟 48 位十六进制字符
401Invalid Customer Code formatCustomer Code 格式不正确,仅允许字母、数字、下划线和短横线(1-50位)
403Invalid or disabled API KeyAPI Key 无效或已被禁用
403API Key has expiredAPI Key 已过有效期,请在控制台重新创建
403API Key does not match Customer CodeAPI Key 与 Customer Code 不属于同一企业
429Too many requests请求频率超过当前 API Key 设定的速率限制,请稍后重试
400question / answer / category / keywords …知识库写入接口字段校验失败(类型、长度、关键词分隔符、配图 URL 等),见 message
403Knowledge base entry limit reached …当前方案知识库条数已满,data.remaining 为 0
400category "…" does not exist as an enabled category …category 不在分类目录中或已停用,请使用 data.existing_categories 中的名称,或先在控制台建好该分类
403… does not support answer images …当前方案不支持知识库配图,请去掉 answer_image 或升级版本
400非法的 sync_since(…)服务绩效议题列表的 sync_since 格式不正确
400无效的议题 id详情路径参数 :id 不是正整数
403当前套餐未开通服务绩效非旗舰版或未开通服务绩效能力
404议题不存在、未评分或已超出保留期详情接口未找到可同步的议题
403开放 API「合作客商写入」未在系统设置中启用 / Key 未被授权合作客商写入未启用,或调用方 Key 不在授权列表
400缺少 rows 数组 / 单次最多导入 5000 行合作客商写入 rows 缺失、非数组或超过上限
400validation_error推送通知:参数不合法,field 指明出错字段
403plan_required / scope_disabled推送通知:套餐不支持(基础版),或未开启「推送通知」/ 当前 Key 未被授权
404company_not_found / room_not_found / notification_not_found推送通知:找不到合作公司 / 目标群 / 该 biz_msg_id 的通知
409company_name_ambiguous / company_unmatched / all_targets_skipped / notification_in_progress推送通知:同名公司多家 / 公司未绑定可推送的群 / 目标群全部被跳过(本次不受理)/ 同一 biz_msg_id 正在受理
400attachment_rejected / qq_message_too_long推送通知:附件被拒绝 / QQ 合成后超过 2000 字(均不占用 biz_msg_id)
413 / 429payload_too_large / too_many_large_requests推送通知:请求体超过 85MB / 同一租户大请求并发已达 4 个
500Internal server error服务端内部异常,请联系管理员(推送通知接口此时带 code 为 internal_error)

推送通知接口的失败响应另带 code 字段,请按 HTTP 状态码 + code 联合判断;各 code 出现在哪个接口、投递失败码与跳过原因见 推送通知 · 错误码。

错误响应格式

{
  "success": false,
  "message": "具体错误描述"
}
注意:出于安全考虑,当服务端发生 500 错误时,响应中不会暴露内部错误详情,统一返回 "Internal server error"。如需排查请联系平台管理员查看服务端日志。

频率限制

为保障服务稳定性,每个 API Key 拥有独立的频率限制配置。系统在认证通过后,根据该 Key 的设定进行限流:

限流规则

限制维度限额说明
平台全局上限1000 次/分钟所有 API Key 不可超过此上限
单 Key 速率限制按 Key 配置创建 API Key 时可设置,默认 1000 次/分钟。实际生效值 = min(Key 配置值, 1000)
请求体大小100 KB(通用)/ 512 KB(POST /api/v1/knowledge/entries)单次请求 JSON Body 的最大字节数
问题长度800 字符question 字段的最大字符数
示例:若您在控制台创建 API Key 时设置速率限制为 200 次/分钟,则该 Key 的实际限流为 200 次/分钟;若设置为 2000,则以平台上限 1000 次/分钟生效。

限流响应头

每次 API 请求的响应中都会包含以下 Headers,方便客户端感知当前额度:

Header说明
RateLimit-Limit当前 Key 在本窗口内允许的最大请求数
RateLimit-Remaining当前窗口内剩余可用请求数
RateLimit-Reset当前窗口重置的 Unix 时间戳(秒)
提示:建议客户端读取 RateLimit-Remaining 响应头,在剩余额度不足时主动降速,避免触发 429 限流。如需调整限额,可在控制台「API 密钥管理」中修改对应 Key 的速率设置。

最佳实践

安全建议

建议说明
使用后端代理切勿将 API Key 暴露在前端代码、移动端应用包或公开仓库中,通过后端服务转发请求
定期轮换密钥建议每 90 天轮换一次 API Key,旧密钥在过渡期后及时禁用或删除
最小权限原则为不同业务场景创建独立的 API Key,便于权限管控和用量追踪
设置过期时间为临时集成或外部合作场景的 API Key 设置合理的过期时间
监控异常调用关注控制台中的 API 调用日志,及时发现异常流量或未授权的调用行为

调用建议

建议说明
指定模板 ID不同业务场景使用不同提示词模板,获取更精准的回答效果
利用多轮会话首次对话保存返回的 session_id,后续追问时传入该值,同一会话的所有对话将在控制台中合并展示,便于追踪和复盘
启用流式输出面向用户的实时交互场景建议使用流式模式,提升用户体验
错误重试网络异常(5xx)时建议实现指数退避重试机制,最多重试 3 次。注意:400/401/403 错误无需重试
限流感知读取响应头中的 RateLimit-Remaining 字段,在剩余额度不足时主动降速
超时设置非流式请求建议设置 30 秒超时,流式请求建议 60 秒
输入预处理发送前对用户问题进行 trim 处理,去除首尾空白字符,减少无效 Token 消耗
议题增量同步以 id 幂等 upsert;增量用 sync_since(建议回拨 1 分钟重叠);轮询间隔 5–15 分钟;停服恢复后沿用旧游标即可补数据