Skip to content

API 运行接口

已发布应用的外部 API 调用入口。支持通过 Deployment ID、Document ID 或 Release 别名三种方式调用。

源码: apps/backend/src/routes/api-run.ts

POST /api/released-app/:deploymentId/run

通过 Deployment ID 运行已发布的应用。

认证方式

API Key / Schedule Token / OAuth Access Token

  • API KeyAuthorization: Bearer wn-...
  • Schedule Token:JWT 格式
  • OAuth TokenAuthorization: Bearer wno-...(需要 chat:completions scope)

请求参数

Path 参数

参数类型必填说明
deploymentIdstring部署 UUID

Body 参数

json
{
  "inputs": { "text": "hello world" },
  "version": "^1.0",
  "stream": true,
  "format": "ndjson",
  "timeout": 60
}
参数类型默认值说明
inputsobject{}Input Block 的输入值
versionstring-版本号。"1.0":精确匹配;"^1.0":major=1 的最新 minor;省略:最新版本
streambooleantrue是否流式响应
format"sse" | "ndjson""ndjson"流式响应格式(注意:API 调用默认 NDJSON,与编辑器默认 SSE 不同)
timeoutnumber-超时时间(秒),不超过管理后台配置的最大值

允许空 body(使用默认值)。

触发上下文 _trigger(issue #691):服务端会按调用来源构造 _trigger 对象并注入 inputs._trigger(API 调用为 { source: 'api', triggered_at };定时任务/Webhook 触发分别为 source: 'schedule' / 'webhook' 并附 schedule_id / webhook_id 等)。该字段为保留字: 调用方在 inputs 或 body 顶层传入的 _trigger 会被服务端覆写,无法伪造。 工作流绑定触发器模板后可通过 _trigger 输入读取,详见 /api/webhook-triggers

Query 参数

参数类型默认值说明
tracestring-设为 full 时返回完整执行轨迹 globalCtx(调试用)。默认不返回,详见下文「响应体大小上限与 trace 开关」。

响应体大小上限与 trace 开关

行为变更(Breaking Change)

为防止内联大文件(如大 base64 图片)经子流程放大撑爆响应体打垮平台,自本次起:

  • 裸部署 run 端点(/:deploymentId/run/d/:documentId/run)默认不再返回 globalCtx(完整执行轨迹)。只返回最终输出 sessions(通常几 KB)。
  • 需要完整轨迹用于调试时,显式加查询参数 ?trace=fullglobalCtx 中的超大字符串(如大 base64)会被替换为占位 { "__truncated": true, "originalBytes": N, "preview": "..." },避免多份内联副本。
  • 整个响应体受大小上限保护(默认约 8 MiB,可由管理后台 run.response_limit 配置)。超限时:
    • JSON 一次性模式(stream:false)→ 返回 HTTP 413 + { "error": "response_too_large", ... }不会尝试序列化超大对象到 OOM。
    • 流式模式(NDJSON / SSE)→ HTTP 状态码已发出无法更改,故返回 200,并以终态事件 run_errorerror: "response_too_large",含 executionStatus)结束,不发送超大的 run_complete / globalCtx
  • Release 网关端点(/r/:alias/:version/*)行为不变(本就通过输出映射只返回精简输出,不含 globalCtx)。

迁移建议:依赖 globalCtx 的调用方请改加 ?trace=full;更稳妥的做法是改用 /r/ 网关端点 + 输出映射,或用 wnfile 句柄传入大文件而非内联 base64。

请求体 / 输入大小上限(issue #664)

行为变更(Breaking Change)

为根治输入侧 OOM(超大 prompt / 内联大 base64 图纸撑爆平台内存),所有 run 入口(/:deploymentId/run/d/:documentId/run、Release /r/:alias/:version/*)在解析输入后、执行前加分层硬上限,超限明确报错(4xx),不静默放行。

维度默认上限超限错误码HTTP
请求体总大小4 MiBrequest_body_too_large413
单个输入字段1 MiBinput_field_too_large400
内联 data URI base64 负载1 MiBinline_base64_too_large400
全部文本输入聚合字节1 MiBprompt_too_large_bytes400
全部文本输入聚合 token200,000prompt_too_large_tokens400
输入结构嵌套深度32input_structure_too_deep400
输入结构节点数100,000input_structure_too_large400
  • 所有阈值热可调:管理后台 site_settingsrun.input_limit 配置(缺失/非法走上表安全默认,5 分钟缓存)。回归较大时可临时调大对应项。
  • 请求体总大小上限远小于网关 client_max_body_size(512m)——run 输入应走文件句柄而非内联文件。
  • 错误响应体形如 { "error": "<code>", "message": "...", "field": "inputs.xxx", "actual": <字节/token>, "limit": <上限> }
  • wnfile: / storage:// 文件句柄不计入上述字段/聚合限制(仅当引用串短于 256 字符、形如「协议 + ID」时豁免;超长的伪句柄不豁免,照常计入文本限制)。
  • 只精确拦截 data URI(data:...;base64,...)形态的内联 base64;裸 base64(无 data: 前缀)不做启发式识别(避免误伤普通长文本),由单字段 / 聚合字节限兜底。

内联 base64 → wnfile 句柄迁移示例

不要把图片 base64 内联进 inputs:

jsonc
// ❌ 会被 inline_base64_too_large 拒绝(超过 base64 上限时)
{ "inputs": { "image": "data:image/png;base64,iVBORw0KGgoAAAANS...(很长)" } }

改为先上传文件拿到 wnfile: 句柄,再把句柄作为输入传入:

jsonc
// ✅ 先调上传接口得到 file id,再传句柄(不受 base64/字段大小限制)
{ "inputs": { "image": "wnfile:550e8400-e29b-41d4-a716-446655440000" } }

PDF 输入处理(base64 / data URL,issue #677 / #678)

PDF 类型输入({"_type":"pdf","value":...})支持三种 value 形态,行为统一:

value 形态处理
wnfile:<id> / storage://<id> 句柄服务端下载并走 PDF→文字预处理(转 Markdown 注入 prompt),任意模型可读,不要求模型有 pdf 能力
data:application/pdf;base64,<...>服务端直接解码并走同一套 PDF→文字预处理,无需先上传(API Key 无法走 /storage 上传,故由服务端代解码)
裸 base64(无 data: 前缀)自动按 %PDF- 文件头识别为 PDF,走同样的预处理;非 PDF 内容(无 %PDF- 头)则按原样文本处理

要点:

  • 任意模型可读:经预处理转文字后,识别块即使配置的模型没有 pdf 原生能力也能正常跑通(这正是「编辑器手动上传 PDF 能跑通、而早期 base64 直传报错」的根因修复)。
  • 裸 base64 自动补前缀:未走预处理而直达模型原生通道的内联 PDF/图片,服务端按文件魔数自动补 data:application/pdf;base64, / data:image/<png|jpeg|webp|gif>;base64, 前缀,调用方无需自己拼 data URL。
  • 降级不再爆上下文:若模型既无 pdf 能力又未走预处理,PDF 输入会被替换为简短提示文本(而非把整串 base64 当文本注入 prompt),避免撑爆上下文。
  • 体积上限:内联 PDF base64 仍受输入层 inline_base64_too_large(默认 1 MiB)限制;大文件请改用 wnfile: 句柄。
jsonc
// ✅ 直接内联 base64 PDF(自动预处理,任意模型可读)
{ "inputs": { "doc": { "_type": "pdf", "value": "data:application/pdf;base64,JVBERi0xLjQK..." } } }
// ✅ 裸 base64 也可(自动识别 %PDF- 并补前缀)
{ "inputs": { "doc": { "_type": "pdf", "value": "JVBERi0xLjQK..." } } }

响应格式

NDJSON 流式响应(默认)

Content-Type: application/x-ndjson

API 模式下仅输出数据类 Block 的事件,过滤掉 prompt 等内部 Block 信息:

{"type":"run_start","runId":"uuid","documentId":"uuid"}
{"type":"block_start","blockId":"uuid","blockType":"code"}
{"type":"block_chunk","blockId":"uuid","delta":"部分输出"}
{"type":"block_complete","blockId":"uuid","output":"完整输出"}
{"type":"block_end","blockId":"uuid"}
{"type":"run_complete","runId":"uuid","sessions":[...],"completedBlocks":1,"duration":1234}

run_complete 默认不含 globalCtx;加 ?trace=full 后才追加(大 blob 已截断)。 若响应体超限,最后一行改为 {"type":"run_error","runId":"uuid","error":"response_too_large","executionStatus":"completed",...}

SSE 流式响应(format: "sse"

Content-Type: text/event-stream

事件类型与 NDJSON 一致,但使用 SSE 格式:

event: run_start
data: {"runId":"uuid","documentId":"uuid"}

event: block_complete
data: {"blockId":"uuid","output":"完整输出"}

event: run_complete
data: {"runId":"uuid","sessions":[...],"completedBlocks":1,"duration":1234}

同 NDJSON:默认不含 globalCtx?trace=full 才追加;超限时以 event: run_errorerror: "response_too_large")终止。

JSON 一次性响应(stream: false

状态码: 200

json
{
  "runId": "uuid",
  "documentId": "uuid",
  "sessions": [
    {
      "blockId": "uuid",
      "blockType": "code",
      "blockName": "处理数据",
      "status": "completed",
      "output": "处理结果"
    }
  ],
  "duration": 1234,
  "status": "success",
  "timedOut": false
}

默认不含 globalCtx。加 ?trace=full 后,响应额外包含 globalCtx 数组(完整执行轨迹,大 blob 已截断为占位)。

块级错误透出(?trace=full,issue #678):当某个 block statuserror 时,仅在带 ?trace=full 的请求下,该 session 会额外携带一个脱敏后的 error 字段(简短可定位的错误信息,已剥离凭证 / data URI / 长 base64 等敏感大负载,并截断到 500 字符)。不带 ?trace=full 时维持原行为(仅 status: "error",无 error 字段,保持向后兼容)。流式(NDJSON/SSE)的 block_error 事件本就实时携带 error,不受此开关影响。

json
// ?trace=full 下出错 block 的 session 形态
{ "blockId": "uuid", "blockType": "structure", "blockName": "识别", "status": "error", "output": null, "error": "内联数据不是合法 PDF(缺少 %PDF- 文件头)" }
响应体超限(stream: false

状态码: 413

json
{
  "runId": "uuid",
  "error": "response_too_large",
  "message": "响应体超过大小上限,已拒绝返回完整结果",
  "actualBytes": 8389000,
  "limitBytes": 8388608,
  "executionStatus": "completed",
  "hint": "请改用 wnfile 句柄输入以避免内联大 base64;或通过 /r/ 网关端点 + 输出映射获取精简输出;或减小工作流输出体积。"
}

hint 默认建议改用 wnfile 句柄 / /r/ 网关 / 减小输出;仅当本次请求确实带了 ?trace=full 时,才额外提示「去掉 ?trace=full 重试」(避免误导未带该参数的调用方)。

actualBytes 是 fail-fast 在「首次累计超过上限」那一刻的字节数,是真实响应大小的下界(不会继续序列化以求精确值),语义为「至少这么大、已超限」。

权限规则

部署可见性API Key 认证Schedule 认证OAuth 认证
public任意有效 API Key已通过 Token 验证任意有效 OAuth Token
privateAPI Key 所属团队必须与部署所属团队一致已通过 Token 验证(跳过权限检查)部署 owner 必须是当前用户,或用户属于部署所属团队

请求示例

bash
# JSON 一次性响应
curl -X POST \
  -H "Authorization: Bearer wn-your-api-key" \
  -H "Content-Type: application/json" \
  -d '{"inputs": {"text": "hello"}, "stream": false}' \
  https://block2-api.wainao.chat/api/released-app/DEPLOYMENT_UUID/run

# NDJSON 流式响应
curl -X POST \
  -H "Authorization: Bearer wn-your-api-key" \
  -d '{"inputs": {"text": "hello"}}' \
  https://block2-api.wainao.chat/api/released-app/DEPLOYMENT_UUID/run

# 指定版本
curl -X POST \
  -H "Authorization: Bearer wn-your-api-key" \
  -d '{"inputs": {"text": "hello"}, "version": "^1.0"}' \
  https://block2-api.wainao.chat/api/released-app/DEPLOYMENT_UUID/run

错误码

状态码错误说明
400Input validation failed输入参数验证失败
400input_field_too_large单个输入字段超大小上限(见「请求体 / 输入大小上限」)
400inline_base64_too_large内联 data URI base64 超上限,请改用 wnfile: 句柄
400prompt_too_large_bytes / prompt_too_large_tokens全部文本输入聚合字节 / token 超上限
400input_structure_too_deep / input_structure_too_large输入结构嵌套过深 / 节点过多
401Unauthorized认证失败或认证方式不支持
402insufficient_credits积分余额不足
403Permission denied: This is a private app...无权访问私有应用
403Deployment ID mismatchSchedule Token 中的 deploymentId 不匹配
404Deployment not found部署不存在或版本未找到
413request_body_too_large请求体总大小超上限(见「请求体 / 输入大小上限」)
413response_too_large响应体超过大小上限(仅 stream:false;流式模式以终态 run_error 表达,状态码仍 200)
500Invalid deployment snapshot: missing content部署快照数据损坏

POST /api/released-app/d/:documentId/run

通过 Document ID 运行已发布的应用。Document ID 是稳定的标识符,不会因重新发布而改变。

认证方式

API Key(仅 API Key,apiKeyAuth

请求参数

Path 参数

参数类型必填说明
documentIdstring文档 UUID(稳定标识)

Body 参数

/:deploymentId/run 一致。

响应格式

/:deploymentId/run 一致。

请求示例

bash
curl -X POST \
  -H "Authorization: Bearer wn-your-api-key" \
  -d '{"inputs": {"text": "hello"}, "stream": false}' \
  https://block2-api.wainao.chat/api/released-app/d/DOCUMENT_UUID/run

错误码

/:deploymentId/run 一致,额外包含:

状态码错误说明
401Unauthorized: Document ID route only supports API key authentication仅支持 API Key 认证

ALL /api/released-app/r/:alias/:version/*

Release 网关路由。通过应用别名 + 版本号 + 路径匹配已发布的端点并执行。

认证方式

接受 API Key、OAuth Access Token 或 Agent 绑定授权(路由链 releaseGatewayResolve → oauthAuth → oauthScopeGuard → apiKeyAuth)。是否强制鉴权由 Release 配置决定(REL-001,fail-closed):

  • 默认要鉴权releaseConfig.requireAuth !== false 时,调用必须携带有效凭据(API Key / OAuth Access Token / Agent 绑定授权),否则 401。配置缺失或解析失败一律按「要鉴权」。
  • 端点级豁免:端点配置 skipAuth: true 可让单个端点公开(覆盖全局 requireAuth),此时无需凭据即可调用。
  • 防 401 绕过:只要请求带了任一凭据 header(Authorization / X-API-Key / X-Internal-Secret / X-Internal-Api-Key-Id,即便值非法或为空),都会强制走鉴权,不会被当匿名放行。
  • 私有部署:匿名访问私有部署返回 403,即使该端点免鉴权。

限流(REL-002)

Release 可配置 rateLimitwindowSeconds 正整数 ≤ 3600、maxRequests 正整数 ≤ 100000);配置非法时回落全局限流。按调用方分桶(API Key 按 apiKeyId、Agent 按 bindingId,OAuth 与匿名公开端点按 release + 客户端 IP)。超过限流返回 429(附 Retry-After 头),响应体 { "error": "Too many requests, please try again later" }

请求参数

Path 参数

参数类型必填说明
aliasstringRelease 别名
versionstring版本号字符串
*string路由路径(匹配 routerTree 中的端点)

Body / Query 参数

  • 非 GET 请求: 从请求体解析 inputs
  • GET 请求: 从 query 参数构建 inputs

匹配规则

  1. 通过 aliasrelease_aliases 表中查找 release_document_id
  2. 根据版本号解析匹配的已发布版本
  3. 在版本的 routerTree 中按 path + HTTP method 匹配端点
  4. 找到端点关联的 deploymentId 并执行

响应格式

固定使用 JSON 一次性响应(runWithJSON),格式与上述 JSON 响应一致。

请求示例

bash
# GET 请求(参数通过 query 传递)
curl -H "Authorization: Bearer wn-your-api-key" \
  "https://block2-api.wainao.chat/api/released-app/r/my-app/v1/users?name=test"

# POST 请求(参数通过 body 传递)
curl -X POST \
  -H "Authorization: Bearer wn-your-api-key" \
  -d '{"name": "test"}' \
  "https://block2-api.wainao.chat/api/released-app/r/my-app/v1/users"

错误码

状态码错误说明
401Unauthorized认证失败;或要求鉴权(requireAuth)时未携带有效凭据
403Permission denied无权访问私有应用(含匿名访问私有部署)
429Too many requests, please try again later触发 Release 限流(rateLimit),见 Retry-After
404Release alias 'xxx' not found别名不存在
404No published version matching 'xxx' found版本不存在
404No endpoint matching METHOD /path端点未匹配
400Endpoint 'xxx' has no deployment configured端点未配置部署
404Deployment not found关联的部署不存在
413request_body_too_large请求体总大小超上限(见「请求体 / 输入大小上限」,与裸部署端点同一套阈值)
400input_field_too_large / inline_base64_too_large / prompt_too_large_bytes / prompt_too_large_tokens / input_structure_too_deep / input_structure_too_large输入分层硬上限(见「请求体 / 输入大小上限」);内联 base64 超限请改用 wnfile: 句柄

补充端点

本节补充 plans/need-update-api.md 中尚未覆盖到 docs-site 的接口。端点标题保持严格的 METHOD /path 格式,便于后台文档覆盖率服务识别。

GET /api/released-app/cross-team/bindings

列出当前调用方可用的跨团队 released app 绑定。

认证:API Key、Schedule Token、OAuth Access Token 或跨团队绑定授权。 请求:无请求体。Query 参数用于分页、过滤、搜索或状态筛选;未传时按后端默认排序与分页返回。

响应:成功时返回目标资源详情、状态或配置对象。

常见错误400 参数非法,401 未认证,403 权限不足,404 资源不存在;服务端或上游异常返回 500


POST /api/released-app/cross-team/proxy

通过跨团队绑定代理调用目标 released app。

认证:API Key、Schedule Token、OAuth Access Token 或跨团队绑定授权。 请求:请求体为 JSON,包含创建、提交、安装、发布或业务动作所需字段。

响应:成功时返回创建或更新后的资源对象,或 { "success": true }

常见错误400 参数非法,401 未认证,403 权限不足,404 资源不存在;服务端或上游异常返回 500

AI Workflow Editor