朱雀新媒体创作

API 用户手册

API 密钥签发、OpenAI 兼容接入与智能体 / 工作流 / 搜索流 / 排版流端点的完整调试指南

API 用户手册

本手册面向需要通过 HTTP API 程序化调用本平台能力的开发者。所有 API 调用走与网页端完全相同的服务端执行链,积分计费、幂等、授权同步生效。

当前支持的 API 能力:

能力OpenAI 兼容自有 API
智能体(内部)✅✅
FastGPT 智能体 / 工作流(外部应用)✅✅
工作流—✅
搜索流—✅
排版流—✅

1. 快速开始

第 1 步:签发 API 密钥

登录后进入 仪表盘 → 个人中心 → API 密钥(/dashboard/api-keys),点击「创建 API 密钥」。

  • 密钥明文形如 zq_AbC123...,只显示一次,关闭弹窗后无法再查看,请立即保存。
  • 每个账号只持有一条密钥(单 key 形态)。泄漏时使用「重新生成」,旧密钥立即失效。
  • 不再使用时可「禁用」(临时挂起)或「删除」。

第 2 步:发出第一个请求

curl -X POST https://svip.zhuque.net.cn/api/openai/v1/chat/completions \
  -H "Authorization: Bearer zq_你的密钥" \
  -H "Content-Type: application/json" \
  -d '{"model": "<agentId>", "messages": [{"role": "user", "content": "你好"}]}'

<agentId> 通过下方「模型列表」接口获取。

第 3 步:确认计费

每次调用的积分消耗在响应的 usage / chargedCredits 字段中返回,与网页端执行计费规则一致,可在「积分记录」页核对。

2. 鉴权

API Key 通过 HTTP 头传递,两种写法等价:

Authorization: Bearer zq_你的密钥
x-api-key: zq_你的密钥

规则与安全约定:

  • 请求显式携带密钥时,服务端只走密钥通道校验;密钥无效、被禁用、过期或属主账号被禁用,一律返回 401,不会回退到浏览器登录态。
  • 不携带密钥的请求走浏览器 session,行为与网页端一致。
  • 密钥与登录账号同权限:只能调用用户侧能力,不能访问管理端接口,也不能管理密钥本身(密钥管理仅限浏览器 session)。
  • 密钥请勿提交到公开代码仓库或写入前端代码;建议放环境变量。

密钥管理接口(仅 session,供自建控制台参考):

方法路径说明
GET/api/user/api-keys查询当前密钥(前缀/状态/最近使用,不含明文)
POST/api/user/api-keys创建;body {"rotate": true} 表示轮换,已存在且未轮换返回 409
PATCH/api/user/api-keys{"isActive": true/false} 启用/禁用
DELETE/api/user/api-keys删除

3. OpenAI 兼容端点

适用于内部智能体与 FastGPT 外部应用。可直接填入任何支持自定义 OpenAI 服务地址的客户端(ChatBox、LobeChat、沉浸式翻译、openai-python / openai-node SDK 等)。

3.1 模型列表

GET /api/openai/v1/models
Authorization: Bearer zq_你的密钥
{
  "object": "list",
  "data": [
    { "id": "68f1a2b3c4d5e6f7a8b9c0d1", "object": "model", "created": 1759500000, "owned_by": "zhuque" },
    { "id": "68f1a2b3c4d5e6f7a8b9c0d2", "object": "model", "created": 1759500000, "owned_by": "zhuque-fastgpt" }
  ]
}

owned_by 含义:zhuque = 内部智能体;zhuque-fastgpt = FastGPT 应用。id 即后续请求的 model 参数。

3.2 对话补全

POST /api/openai/v1/chat/completions
Authorization: Bearer zq_你的密钥
Content-Type: application/json

请求体:

字段类型必填说明
modelstring✅智能体 ID(见 3.1)
messagesarray✅OpenAI 消息数组,见下方说明
streamboolean—true 时返回 SSE 流,默认 false
temperaturenumber—0–2
max_tokensinteger—映射为平台输出长度,自动截断到 100–10000

messages 说明:

  • 只接受 user / assistant 角色;system / developer 消息的内容会被合并为第一条 user 消息的前缀(不会静默丢弃,但智能体真正的系统提示词由平台/应用配置决定,客户端 system 只是附加参考)。
  • content 支持 string 或 [{type: "text", text: "..."}] 数组。
  • 单条消息 ≤ 32KB,全部消息合计 ≤ 256KB,最多 100 条。
  • 会话上下文由客户端在 messages 中携带,服务端不保存跨请求会话;每次请求服务端生成独立幂等键,OpenAI 协议下没有重试去重语义。

非流式响应:

{
  "id": "chatcmpl-…",
  "object": "chat.completion",
  "created": 1759500000,
  "model": "68f1a2b3c4d5e6f7a8b9c0d1",
  "choices": [{ "index": 0, "message": { "role": "assistant", "content": "回答内容" }, "finish_reason": "stop" }],
  "usage": { "prompt_tokens": 128, "completion_tokens": 512, "total_tokens": 640 }
}

流式响应:标准 OpenAI chunk(chat.completion.chunk),结束时发送一个 choices: [] 的 usage 帧和 data: [DONE]。reasoning_content(思维链)会作为 delta 字段原样透传。

SDK 接入示例(Python):

from openai import OpenAI
 
client = OpenAI(
    base_url="https://svip.zhuque.net.cn/api/openai/v1",
    api_key="zq_你的密钥",
)
 
resp = client.chat.completions.create(
    model="<agentId>",
    messages=[{"role": "user", "content": "你好"}],
    stream=True,
)
for chunk in resp:
    delta = chunk.choices[0].delta if chunk.choices else None
    if delta and delta.content:
        print(delta.content, end="", flush=True)

Node.js:

import OpenAI from 'openai';
 
const client = new OpenAI({
  baseURL: 'https://svip.zhuque.net.cn/api/openai/v1',
  apiKey: 'zq_你的密钥',
});
 
const stream = await client.chat.completions.create({
  model: '<agentId>',
  messages: [{ role: 'user', content: '你好' }],
  stream: true,
});
for await (const chunk of stream) {
  process.stdout.write(chunk.choices[0]?.delta?.content ?? '');
}

已知限制:

  • FastGPT 应用请求交互输入(选择/表单)时,OpenAI 协议无法表达,会以 assistant 文本返回 JSON 提示后结束流。需要交互请改用下方自有 API(interactive / continue)。
  • FastGPT 固定积分计费,usage 可能缺失(非流式给 0 值),属正常现象。

4. 自有 API 通用约定

以下端点同时接受浏览器 session 与 Bearer 密钥,请求头与第 2 节一致。

  • Base URL:https://svip.zhuque.net.cn(即部署环境 NEXT_PUBLIC_SITE_URL 配置的站点地址;本地调试用 http://localhost:3000)。
  • 请求体均为 JSON(Content-Type: application/json)。
  • 幂等键:所有执行请求必须携带 idempotencyKey(UUID v4,每次新请求重新生成,如 uuidgen 或 SDK 的 crypto.randomUUID())。同一密钥 + 相同内容重发 → 返回已执行结果(不重复计费);同一密钥 + 不同内容 → 409。
  • 流式:带 Accept: text/event-stream 请求头或 body 中 stream: true;响应为 text/event-stream,事件格式见第 8 节。工作流、搜索流、排版流与 FastGPT 工作流应用的执行常超过 60 秒,非流式在整个执行完成前不返回任何字节,容易被中间网关按空闲超时切断——程序化调用一律建议流式。
  • 失败的执行记录要求换新幂等键重试(返回 409 提示)。

计费一览

能力计费方式说明
智能体(内部)输入+输出 token × 智能体倍率以 usage 为准
FastGPT 应用固定积分 × 倍率预扣-结算-释放,失败自动释放
工作流全部步骤 token 之和 × 流程倍率
搜索流搜索步 3 积分/步 × 倍率 + AI token 计费
排版流固定积分 + token

执行前账户余额须 大于 10 积分(门槛检查)。具体扣减金额以响应 chargedCredits 和积分记录为准。

5. 智能体 / FastGPT 应用

5.1 对话

POST /api/agents/{agentId}/chat            # 内部智能体
POST /api/agents/{externalId}/chat?source=external   # FastGPT 应用

请求体:

字段类型必填说明
messagesarray✅[{role: "user"|"assistant", content: string}]
idempotencyKeyuuid✅幂等键
modelstring—仅内部智能体:允许自选模型时指定底层模型;不传时回退智能体默认模型或首个启用模型
streamboolean—流式开关
temperaturenumber—0–2(外部应用忽略)
outputLengthnumber—期望输出长度 100–10000(外部应用忽略)
localChatIdstring—仅外部应用:复用会话(1–128 位字母数字_-)。不传则每次新会话

非流式响应(内部智能体):

{
  "success": true,
  "data": {
    "content": "回答正文",
    "reasoningContent": "思维链(如模型支持)",
    "usage": { "promptTokens": 128, "completionTokens": 512, "totalTokens": 640 },
    "creditsUsed": 10,
    "chargedCredits": 9,
    "currentCredits": 990,
    "billingStatus": "charged",
    "isEstimated": false,
    "finishReason": "stop"
  }
}

非流式响应(FastGPT 应用):data 中含 content、externalSessionId、resourceType;若应用发起交互,返回 interactive: {type: "userSelect"|"userInput", params: {...}} 而不是 content,此时进入「等待输入」状态,用 5.3 的 continue 提交交互结果。

流式(内部智能体):OpenAI chunk 形状的 data: 帧 + 末尾计费帧 + [DONE]。 流式(FastGPT 应用):自定义事件,见第 8 节事件表。

5.2 会话与历史(仅 FastGPT 应用)

GET /api/agents/{externalId}/session?localChatId=<id>&history=1&limit=20&cursor=<上一页nextCursor>

返回会话状态(active / running / waiting_input / unknown)、待交互的 interactive 数据和可选历史消息。推荐轮询场景使用 limit + cursor 翻页。

5.3 交互续答(仅 FastGPT 应用)

POST /api/agents/{externalId}/continue
{ "localChatId": "会话id", "idempotencyKey": "新的uuid", "interaction": <session 返回的 interactive 所需载荷>, "stream": false }

仅当会话处于 waiting_input 时可用;interaction 的具体结构由应用的交互控件决定(userSelect 通常为所选值,userInput 通常为表单字段对象)。

6. 工作流

POST /api/workflows/{workflowId}/execute
{ "input": "任务输入", "outputLength": 1500, "idempotencyKey": "uuid" }
  • input:1–20000 字符;outputLength:100–10000,默认 1500。

非流式成功响应(多步链式执行完成后一次性返回):

{
  "success": true,
  "data": {
    "finalStep": { "order": 3, "name": "最终步骤名", "model": "…", "result": "最终输出", "usage": {"promptTokens": 0, "completionTokens": 0, "totalTokens": 0} },
    "executedStepCount": 3,
    "totalTokens": 5230,
    "creditsUsed": 12,
    "chargedCredits": 12,
    "billingStatus": "charged",
    "executionId": "…",
    "replayed": false
  }
}

状态码:

  • 202 {success: false, status: "running", executionId} — 同幂等键正在执行(可用同 key 重发等待 replay,或换新 key 前先轮询状态)。
  • 409 — 幂等键冲突 / 历次执行失败后重试(换新幂等键)。
  • 502 — 上游失败(failureCode 见响应)。

状态查询:

GET /api/workflows/executions?idempotencyKey=<uuid>
{ "success": true, "data": { "id": "…", "status": "running", "executedStepCount": 2, "failureCode": null } }

status 取值:pending(未找到或排队)/ running / succeeded / failed。

7. 搜索流与排版流

7.1 搜索流

POST /api/searchflows/{flowId}/execute
{ "keyword": "搜索关键词或关键句", "userIntent": "你想让 AI 聚焦的意图", "outputLength": 1500, "idempotencyKey": "uuid" }
  • keyword:1–20000 字符;userIntent:1–10000 字符。
  • 流式响应会实时推送每步结果与最终步的内容增量(delta 事件)。
  • 搜索结果为空时返回 422(EMPTY_RESULT)。

状态查询:GET /api/searchflows/executions?idempotencyKey=<uuid>,响应结构同第 6 节。

7.2 排版流

POST /api/typesettingflows/{flowId}/execute
{ "keyword": "关键词", "imageCount": 5, "article": "正文原文(≤50000 字)", "idempotencyKey": "uuid" }
  • keyword:≤50 字符,仅限字母、数字与空格;imageCount:1–10。
  • 非流式响应:{success, data: {execution…}},HTTP 状态 200(完成)/ 202(进行中)/ 422(失败,带 code 与 error)。
  • 结果中的外链图片建议通过平台代理获取以避免防盗链:
GET /api/typesetting-executions/{executionId}/image?src=<图片URL>

执行历史:GET /api/typesetting-executions?status=&page=&pageSize=;单条:GET /api/typesetting-executions/{id}。

8. SSE 流式消费指南

流式响应为 text/event-stream,每个事件形如:

event: <事件名>
data: <JSON>

事件表

能力事件序列
内部智能体(OpenAI 形状)data: {choices:[{delta:{content}}]} … → data: {usage, creditsUsed, billingStatus, …} → data: [DONE]
FastGPT 应用delta(内容增量)→(可选)status / interactive → done(含计费)或 error
工作流step(每步完成)→ usage → completed(含最终结果);失败发 error
搜索流execution → step(每步开始/完成)→ delta(最终步内容增量)→ usage → completed;失败发 error
排版流step(步骤进度)→ usage → completed;失败发 error

error 事件结构:{executionId, code, message, messageKey?, retryable}。常见 code:UPSTREAM_FAILED(上游失败,可重试)、OUTPUT_TRUNCATED(输出超限,不可重试)、CLIENT_ABORTED(客户端主动取消)、LEASE_LOST(执行权转移,可重试)、FLOW_DEADLINE(整体超时)。

JavaScript 消费示例

const resp = await fetch(url, {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer zq_你的密钥',
    'Content-Type': 'application/json',
    'Accept': 'text/event-stream',
  },
  body: JSON.stringify(payload),
  signal: AbortSignal.timeout(300_000), // 长任务建议设置超时
});
 
const reader = resp.body.getReader();
const decoder = new TextDecoder();
let buffer = '';
 
while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  buffer += decoder.decode(value, { stream: true });
 
  let boundary;
  while ((boundary = buffer.indexOf('\n\n')) !== -1) {
    const block = buffer.slice(0, boundary);
    buffer = buffer.slice(boundary + 2);
 
    for (const line of block.split('\n')) {
      if (!line.startsWith('data:')) continue;
      const data = line.slice(5).trim();
      if (data === '[DONE]') continue;              // OpenAI 形状的结束标记
      const payload = JSON.parse(data);
      // 按能力处理:payload.choices?.[0]?.delta?.content / payload.delta?.content / payload.completed …
    }
  }
}

Python 消费示例

import json, requests
 
resp = requests.post(url, headers=headers, json=payload, stream=True, timeout=300)
for raw in resp.iter_lines(decode_unicode=True):
    if not raw or not raw.startswith('data:'):
        continue
    data = raw[5:].strip()
    if data == '[DONE]':
        break
    payload = json.loads(data)
    print(payload, flush=True)

调试建议:先用 curl -N(禁用缓冲)肉眼确认事件流,再写解析代码;反向代理(Nginx 等)需关闭 proxy_buffering 才能收到实时事件。

9. 错误码与排查

HTTP 状态码

状态含义常见原因与处理
400请求参数错误按 error 字段修正;严格校验 idempotencyKey 为 UUID
401未认证密钥缺失/错误/禁用/过期;检查 Bearer 头
402积分不足充值后重试;currentCredits 为当前余额
403无权访问智能体未公开/已停用
404资源不存在ID 错误,或能力未开放
409冲突幂等键已用/内容不一致/会话正在执行/需换新 key 重试
422执行失败搜索无结果、排版失败等,看 code/error
429限流见下表,等待 Retry-After 秒
5xx服务端/上游错误502 上游失败可重试;503 服务暂不可用;504 上游超时

限流(API Key 通道)

端点限额
智能体对话 / continue3 次/分钟
工作流 / 搜索流 / 排版流执行10 次/分钟(按密钥计)
FastGPT 会话查询30 次/分钟

FastGPT 相关错误码(code 字段)

FASTGPT_UNAUTHORIZED(平台到 FastGPT 的连接失效)、FASTGPT_RESOURCE_NOT_FOUND(应用被解绑或下线)、FASTGPT_TIMEOUT、FASTGPT_UPSTREAM_ERROR、FASTGPT_RATE_LIMITED、FASTGPT_SESSION_BUSY(同会话正在执行)、FASTGPT_INTERACTION_UNSUPPORTED(会话不在等待输入状态)、FASTGPT_SENSITIVE_DATA_BLOCKED(内容安全拦截)、FASTGPT_RESULT_UNKNOWN(结果未知,请勿用原幂等键重试,等待平台对账)。

常见排查

  • 明文密钥丢了:只能「重新生成」,无找回。
  • Model is required / Valid idempotencyKey is required:走的是自有 API 校验,检查字段名与 UUID 格式。
  • OpenAI 客户端报 404 model_not_found:model 必须是模型列表返回的智能体 ID,不是名称。
  • 流式收不到实时数据:确认带 Accept: text/event-stream(或 stream: true),并检查代理缓冲。
  • 同内容重发没有重新执行:幂等键相同会直接返回上次结果(replayed: true),要重新执行请换新 UUID。
  • 409 该请求已失败,请使用新的幂等键重试:失败记录不可复用,换新 key 重发。
  • OUTPUT_TRUNCATED(模型输出达到上限):目标字数对应的生成预算(字数 × 1.5,封顶 8192)装不下模型输出;调大 outputLength 重试(搜索流实测建议 ≥ 5000)。残缺内容不会交付,也不会重复计费。
  • 非流式请求约 60 秒被切断:长流程执行期间非流式不产出任何字节,会被网关按空闲超时断开,改用流式;伴随 FASTGPT_RESULT_UNKNOWN 时等待平台对账,勿用原幂等键重试。

10. 速率之外的约束速查

项限制
单条消息≤ 32 KB
messages 总量≤ 256 KB、≤ 100 条
工作流 input1–20000 字符
搜索流 keyword / userIntent≤ 20000 / ≤ 10000 字符
排版流 keyword / article≤ 50 字符(字母数字空格)/ ≤ 50000 字符
outputLength100–10000(默认 1500)
执行前余额门槛> 10 积分