跳到主要内容

入站 Webhook

外部系统向 Soln 写入数据时调用入站 Webhook 接口:请求体就是流程的输入数据,流程再按画布上的映射写入本地表单。

只有 入站 + Webhook 流程会暴露这个地址。查询数据和消息推送各有自己的地址,见查询数据和消息推送。

请求方式​

项说明
方法POST
地址<runtime-origin>/api/open-link/inbound/webhooks/<flowCode>
Content-Type必须以 application/json 开头,否则返回 OPEN_LINK_CONTENT_TYPE_INVALID
请求体大小最大 10 MiB,超出返回 OPEN_LINK_PAYLOAD_TOO_LARGE
鉴权按该 OpenLink 的入站鉴权配置携带请求头(共享令牌 / Bearer Token / 签名校验),并且先经过白名单校验
可选请求头X-Idempotency-Key 用于防重复提交;X-Request-Id 会记录为外部请求 ID

<runtime-origin> 是工作区运行时地址(和浏览器打开 Soln 的地址一致),<flowCode> 是流程编码,例如 open_link_flow_0505058add3a。流程的开始节点展示完整 Webhook URL,设计画布的 请求示例 也会给出可复制的调用示例。

请求体​

请求体必须是一个 JSON 对象,字段怎么传取决于画布上有没有转换节点。

有转换节点:按外部字段编码传​

key 是外部字段编码,value 是该字段的值:

{
"order_no": "SO-2026-0001",
"amount": 128.5,
"customer": { "code": "C-1001" },
"ordered_at": "2026-09-18T10:00:00.000Z"
}
  • 字段编码取自外部表单的字段定义
  • 外键或关联字段传被引用对象的字段,例如 customer.code;嵌套对象按路径读取
  • 没有出现在映射里的字段会被忽略,多余字段不影响执行

没有转换节点:按本地表单字段 API 名传​

画布上只有目标节点、没有转换节点时,Soln 把请求体直接当作本地表单数据写入,key 用本地表单的字段 API 名:

{
"order_no": "SO-2026-0001",
"amount": 128.5
}

子表数据​

子表数据放在 input.childTables 数组里:

{
"order_no": "SO-2026-0001",
"input": {
"childTables": [
{
"externalObjectCode": "order_lines",
"rows": [
{ "line_no": "1", "sku": "A-100", "qty": 2 },
{ "line_no": "2", "sku": "A-200", "qty": 1 }
]
}
]
}
}

每个子表按 externalObjectCode(也可以写 externalObjectId)与画布上配置的子表配对匹配,不按数组顺序;匹配不到的 rows 不会被写入。

可选包装与回调​

  • 请求体只包含 payload(以及可选 callback)时,Soln 取 payload 的内容作为输入数据
  • callback 是异步回调控制对象:{ "url": "https://...", "headers": { ... } },用于流程结束后回调外部系统
  • 请求体里带 callbackId 时,它会被当作幂等键使用(等价于 X-Idempotency-Key)
  • 工作流回调流程的字段约定见工作流集成

响应​

场景返回
接收成功HTTP 202,返回 accepted、duplicate、logId、traceId、status、flowCode、callbackRequested 和 statusQueryUrl
重复提交同一个幂等键再次提交时返回 duplicate: true 和已有执行的 logId,不会重复写入
失败非 2xx,响应体为 { code, requestId, message?, detail? }

接收成功只代表请求进入队列。查询执行结果时用 GET 请求 statusQueryUrl:

curl --request GET \
'https://runtime.example.com/api/open-link/inbound/webhooks/executions/<logId>?traceId=<traceId>'

结果包含 status、completed、localRecordId、durationMs、errorCode、errorMessage 以及回调投递状态。

常见错误​

errorCode说明
OPEN_LINK_CONTENT_TYPE_INVALIDContent-Type 不是 JSON
OPEN_LINK_JSON_VALUE_INVALID请求体不是合法 JSON
OPEN_LINK_PAYLOAD_TOO_LARGE请求体超过 10 MiB
OPEN_LINK_EXECUTION_PAYLOAD_INVALID请求体不是 JSON 对象
OPEN_LINK_WEBHOOK_SOURCE_DENIED来源没有通过白名单
OPEN_LINK_WEBHOOK_AUTH_INVALID入站凭证校验失败
OPEN_LINK_WEBHOOK_TIMESTAMP_EXPIRED签名时间戳超出允许的时钟窗口
OPEN_LINK_WEBHOOK_CALLBACK_INVALIDcallback 控制对象不合法
OPEN_LINK_FLOW_DEFINITION_NOT_PUBLISHED流程没有可运行的已发布版本
OPEN_LINK_IDEMPOTENCY_KEY_CONFLICT同一个幂等键被用于其他流程
OPEN_LINK_INBOUND_RATE_LIMIT_EXCEEDED超过每分钟请求数限制
OPEN_LINK_INBOUND_CONCURRENCY_LIMIT_EXCEEDED超过最大并发请求数限制

调用示例​

两个示例都使用签名校验:签名原文是 METHOD\npath\ntimestamp\n原始 body,时间戳必须是当前时间,签名也要按真实请求体重新计算,示例里的写法只表示格式。

只写主表​

curl --request POST \
'https://runtime.example.com/api/open-link/inbound/webhooks/open_link_flow_0505058add3a' \
--header 'Content-Type: application/json' \
--header 'X-App-Id: app_Aqg9LRZahMDuMRS9' \
--header 'X-OpenLink-Timestamp: 1789712190157' \
--header 'X-OpenLink-Signature: <按真实请求体重新计算>' \
--data '{"order_no":"SO-2026-0001","amount":128.5,"customer":{"code":"C-1001"}}'

主表加子表​

curl --request POST \
'https://runtime.example.com/api/open-link/inbound/webhooks/open_link_flow_0505058add3a' \
--header 'Content-Type: application/json' \
--header 'X-App-Id: app_Aqg9LRZahMDuMRS9' \
--header 'X-OpenLink-Timestamp: 1789712190157' \
--header 'X-OpenLink-Signature: <按真实请求体重新计算>' \
--data '{
"order_no": "SO-2026-0001",
"amount": 128.5,
"customer": { "code": "C-1001" },
"input": {
"childTables": [
{
"externalObjectCode": "order_lines",
"rows": [
{ "line_no": "1", "sku": "A-100", "qty": 2 },
{ "line_no": "2", "sku": "A-200", "qty": 1 }
]
}
]
}
}'

子表的 externalObjectCode 必须与画布上子表配对选中的外部对象编码一致,主表字段和 input.childTables 放在同一个请求体里提交。如果画布上没有转换节点,主表字段改用本地表单字段 API 名。

两个示例都使用签名校验;改用共享令牌或 Bearer Token 时,把三个签名请求头换成对应请求头,规则见入站鉴权。