n8n 出站交付
使用 n8n 对已复核 Numora 文档做出站集成的推荐模式,包括 outbox、dispatch 与可选的 delivery callback。
范围
本页描述如何通过 n8n 把已复核的 Numora 文档接到下游系统。
示例中的当前 provider 为 dynamics365。
推荐模式
Numora 当前支持两种出站交付模式。
1. Numora 托管下游执行
这是面向多租户 SaaS 的推荐模式。
- 终端用户在 Numora 内配置下游 connection 和 workflow。
n8n只负责轮询 delivery outbox 并调用dispatch。- 真正的下游写入由 Numora 复用已保存的 connection 与内部 workflow 来完成。
n8n不需要保存每个用户各自的 Dataverse 凭证。
推荐流程:
GET /v1/delivery/outboxPOST /v1/documents/{id}/dispatch- 轮询
GET /v1/documents/{id},直到文档离开push_pending
在这个模式下,不需要再调用 POST /v1/documents/{id}/delivery。
2. 外部执行器 + delivery callback
只有当下游写入动作发生在 Numora 外部时,才使用这个模式。
n8n或其它 worker 先读取文档结果。- 外部执行器直接写入目标系统。
- 外部执行器再调用 delivery callback,把成功或失败回写给 Numora。
- 如果你仍希望终端用户在 Numora 内维护 Dynamics connection,则
n8n可以向 Numora 申请短期 Dataverse token,而不是自己保存 client secret。
推荐流程:
GET /v1/delivery/outboxGET /v1/documents/{id}/resultPOST /v1/dynamics/session- 写入目标系统
POST /v1/documents/{id}/delivery
在这个模式下,不要调用 POST /v1/documents/{id}/dispatch。dispatch 仍然会回到 Numora 内部 workflow engine,并不能替代旧 workflow 逻辑。
轮询 Delivery Outbox
GET /v1/delivery/outbox?provider=dynamics365&limit=100
请求示例:
curl "https://api.numora.example/v1/delivery/outbox?provider=dynamics365&limit=100" \
-H "Authorization: Bearer $NUMORA_API_KEY" \
-H "x-request-id: n8n-outbox-001"响应示例:
{
"data": [
{
"document_id": "4be38121-3791-4856-80d5-c57dbec2cf78",
"schema": "invoice_v2",
"status": "reviewed",
"external_id": null,
"metadata": {},
"result_url": "/v1/documents/4be38121-3791-4856-80d5-c57dbec2cf78/result",
"dispatch_url": "/v1/documents/4be38121-3791-4856-80d5-c57dbec2cf78/dispatch",
"updated_at": "2026-03-24T02:36:37.684Z"
}
],
"meta": {
"provider": "dynamics365",
"next_cursor": null
}
}说明:
- outbox 返回的是当前可投递的、已复核且已 finalized 的文档。
- 已经处于
push_pending或push_succeeded的文档会被排除。 next_cursor是不透明游标,分页时应原样传回。
Dispatch 已复核文档
POST /v1/documents/{id}/dispatch
请求示例:
curl -X POST "https://api.numora.example/v1/documents/4be38121-3791-4856-80d5-c57dbec2cf78/dispatch" \
-H "Authorization: Bearer $NUMORA_API_KEY" \
-H "Content-Type: application/json" \
-H "x-request-id: n8n-dispatch-001" \
-d '{
"provider": "dynamics365"
}'响应示例:
{
"data": {
"id": "4be38121-3791-4856-80d5-c57dbec2cf78",
"schema": "invoice_v2",
"status": "push_pending",
"external_id": null,
"metadata": {},
"review_state": {
"version": 1,
"confirmed_general_field_names": ["invoice_number"],
"confirmed_line_item_ids": []
},
"duplicate_of": null,
"created_at": "2026-03-20T20:25:04.644Z",
"updated_at": "2026-03-24T02:36:37.684Z",
"status_url": "/v1/documents/4be38121-3791-4856-80d5-c57dbec2cf78",
"result_url": "/v1/documents/4be38121-3791-4856-80d5-c57dbec2cf78/result",
"dispatch_url": "/v1/documents/4be38121-3791-4856-80d5-c57dbec2cf78/dispatch"
},
"meta": {
"run_id": "18e1224c-fb6c-429e-89a3-9d3ee96ff7a9"
}
}说明:
dispatch是异步动作。202 Accepted表示已入队,不代表已完成。- 文档如果还没达到 reviewed + finalized,会返回
409 conflict。 - 如果当前没有可用的下游 workflow,也会返回
409 conflict。
Dispatch 后轮询文档状态
GET /v1/documents/{id}
推荐这样解释状态:
push_pending:下游执行仍在排队或运行中push_succeeded:下游执行成功完成push_failed:最近一次下游执行失败,需要重试或人工处理
对于推荐的 dispatch 模式,这个文档状态资源就是 n8n 判断完成与否的主信号。
记录外部交付结果
POST /v1/documents/{id}/delivery
只有在下游写入动作由 Numora 外部执行时才需要调用。
成功示例:
curl -X POST "https://api.numora.example/v1/documents/4be38121-3791-4856-80d5-c57dbec2cf78/delivery" \
-H "Authorization: Bearer $NUMORA_API_KEY" \
-H "Content-Type: application/json" \
-H "x-request-id: n8n-delivery-success-001" \
-d '{
"provider": "dynamics365",
"status": "succeeded",
"external_record_id": "crm-row-001",
"execution_id": "n8n-4be38121-3791-4856-80d5-c57dbec2cf78",
"attempted_at": "2026-03-24T03:00:00.000Z"
}'失败示例:
curl -X POST "https://api.numora.example/v1/documents/4be38121-3791-4856-80d5-c57dbec2cf78/delivery" \
-H "Authorization: Bearer $NUMORA_API_KEY" \
-H "Content-Type: application/json" \
-H "x-request-id: n8n-delivery-failed-001" \
-d '{
"provider": "dynamics365",
"status": "failed",
"execution_id": "n8n-4be38121-3791-4856-80d5-c57dbec2cf78",
"error_code": "crm_429",
"error_message": "Dataverse rate limited",
"attempted_at": "2026-03-24T03:00:00.000Z"
}'这个 callback 会按 execution_id 做幂等处理。
- 相同
execution_id+ 相同 payload 可以安全重放。 - 相同
execution_id+ 不同 delivery 数据会返回409 conflict。
申请短期 Dataverse Session
POST /v1/dynamics/session
只有在外部执行器模式下才需要这个接口。它适用于这种场景:你希望由 n8n 替代旧 workflow 的 Dataverse 逻辑,但仍然让终端用户在 Numora 内配置 Dynamics connection。
请求示例:
curl -X POST "https://api.numora.example/v1/dynamics/session" \
-H "Authorization: Bearer $NUMORA_API_KEY" \
-H "Content-Type: application/json" \
-H "x-request-id: n8n-dynamics-session-001" \
-d '{}'响应示例:
{
"data": {
"provider": "dynamics365",
"token_type": "Bearer",
"access_token": "<short-lived-dataverse-token>",
"organization_url": "https://org.crm.dynamics.com",
"organization_origin": "https://org.crm.dynamics.com",
"api_base_url": "https://org.crm.dynamics.com/api/data/v9.2",
"connection": {
"id": "conn_123",
"status": "active",
"organization_url": "https://org.crm.dynamics.com",
"tenant_id": "tenant-id",
"client_id": "client-id"
}
}
}说明:
- 不会返回已保存的 client secret。
- 返回的 bearer token 只适合可信 worker,例如你自管的
n8n。 - 如果要指定某条 Dynamics connection,可以在 JSON body 里传
connection_id。 - 如果执行器有意结束但不创建 CRM 记录,例如 supplier lookup 未命中,请向
POST /v1/documents/{id}/delivery回写status=skipped。Numora 会把它视为“完成但未写入 CRM”,并避免文档被自动 outbox 无限重试。
Invoice_v2 执行器映射
如果你要用 n8n 替代当前 invoice workflow,可以按下面的结构搭建:
- 轮询
GET /v1/delivery/outbox。 - 展开返回的每条 item。
- 调
GET /v1/documents/{id}/result。 - 从
data.data.fields读取字段,从data.data.line_items读取 line items。 - 调
POST /v1/dynamics/session。 - 在 Dataverse 中按固定 owner 名查询
team。 - 按
vendor_name查询otcm_supplier。 - 如果 supplier lookup 未命中,则 callback
status=skipped。 - 如果 supplier lookup 命中,则创建
otcm_inboundinvoice。 - 遍历
line_items并创建otcm_inboundinvoicelineitem。 - 以创建出的 invoice record id 回写
status=succeeded。
常用字段路径:
fields.invoice_number.valuefields.invoice_date.valuefields.due_date.valuefields.vendor_name.valuefields.subtotal.valuefields.tax_amount.valuefields.invoice_total.valueline_items[*].descriptionline_items[*].quantityline_items[*].unit_priceline_items[*].amountline_items[*].tax_code
读取 Delivery Attempts
GET /v1/documents/{id}/delivery?provider=dynamics365&limit=20
这个资源主要用于 callback 模式下查看历史交付记录。
推荐的 n8n 轮询策略
对于推荐的 Numora 托管 dispatch 模式:
- 每 5 到 10 分钟轮询一次。
- 调
GET /v1/delivery/outbox。 - 展开返回 items。
- 对每条 item 调用
dispatch_url。 - 保存
document_id和meta.run_id以便观测。 - 轮询
GET /v1/documents/{id}或查看 workflow runs,直到状态离开push_pending。
这种模式可以把目标系统连接和 workflow 配置都保留在 Numora 内部。