Run Delivery Controls
Skip or re-point a Spec's Dispatch nodes for one POST /v1/run request with dispatch and bindings, read warnings and dispatch_skipped, and handle late failures.
A Spec's Dispatch nodes deliver every run's payloads to the destinations their bindings name. Two optional fields on POST /v1/run change that for one request without touching the Spec or its bindings. dispatch=false skips every Dispatch node for the request, so nothing is delivered for its documents. bindings is a JSON object keyed by Dispatch node id: a destination id re-points every binding of that node to that destination for this request, and null skips that node. Each re-pointed binding keeps its own field map, serializer, and retry policy; only the target changes.
The node ids are the ones shown in the Spec editor and in the signal_filter.match.stage_id of your existing dispatch.* bindings. dispatch=false is shorthand for "every node maps to null", so combining it with a non-null override is rejected. The map holds at most 64 entries and every value must be a destination UUID or null. Skipped nodes are not silent: each one records a dispatch with status skipped on the pipeline, visible through GET /v1/pipelines/{id}/dispatches, so the run's history shows that delivery was deliberately withheld.
Skip all delivery, or re-point one node and skip another
# Skip every Dispatch node for this request
curl -X POST https://api.talonic.com/v1/run \
-H "Authorization: Bearer $TALONIC_API_KEY" \
-F spec_id=SPEC_ID \
-F dispatch=false \
-F files=@invoice.pdf
# Re-point node A to a test destination, skip node B
curl -X POST https://api.talonic.com/v1/run \
-H "Authorization: Bearer $TALONIC_API_KEY" \
-F spec_id=SPEC_ID \
-F 'bindings={"NODE_A_ID":"TEST_DESTINATION_ID","NODE_B_ID":null}' \
-F files=@invoice.pdfWhat is checked at submit time
The request is refused with 400 invalid_delivery_controls when a key is neither a Dispatch node of the Spec's published version nor of the newest pipeline's frozen rail, when a value is not an active destination in your workspace, or when a value's connector cannot carry one of the node's bindings, for example a Google Sheets destination for a JSON binding, or a legacy-signature webhook binding pointed at object storage. Nothing is ingested when the controls are invalid, so fix the map and resubmit.
Some situations are accepted with a warning in the 202 response instead. Re-pointing a node that has no active binding gets no_binding_for_node, because nothing will be delivered for it regardless of the override. The early trigger modes read the Spec's published version while on_run_completed reads the rail frozen when the pipeline was created, and an append request reuses the newest pipeline; after you add or delete a Dispatch node and republish, the two can disagree for a while. A key that exists on only one side is accepted with node_not_in_live_pipeline or node_not_on_published_version, naming the pipeline concerned, so you can send both ids when you need both covered.
202 response with a warning
{
"run_id": "a8716d18-978d-4d19-8ca5-8b3784ca857c",
"spec_id": "1fc7807e-e1aa-4504-b796-5709986e78ed",
"status": "processing",
"input_count": 1,
"poll_url": "/v1/run/a8716d18-978d-4d19-8ca5-8b3784ca857c",
"documents": [ { "document_id": "c3d4e5f6-a7b8-9012-cdef-123456789012", "filename": "invoice.pdf", "size_bytes": 184320, "source": "file", "deduplicated": false } ],
"warnings": [
{ "code": "no_binding_for_node", "message": "Dispatch node 'NODE_A_ID' has no active binding — nothing will be delivered for it regardless of the override." }
]
}GET /v1/run/{id} echoes the controls whenever a request sent them: dispatch: false (only when set), the bindings map, and dispatch_skipped, which is true when the controls suppress at least one Dispatch node. Use dispatch_skipped in dashboards to tell "nothing arrived because the caller opted out" apart from "nothing arrived because delivery failed".
What happens later
- Bindings and destinations can change between submit and delivery. If an override destination has been deleted or deactivated by the time the payload is sent, that delivery fails with
destination_override_missingand lands in the dead-letter queue. It never falls back to the binding's own destination. - A
skippeddispatch cannot be re-dispatched:POST /v1/pipelines/{id}/dispatches/{dispatchId}/redispatchanswers409 DISPATCH_SKIPPED_BY_REQUEST. To deliver it after all, trigger the node manually withPOST /v1/pipelines/{id}/dispatches/{stageId}; manual triggers ignore request controls. - A re-dispatch of a dispatch that did ship inherits its frozen selection, including any per-request destination override.
- Controls attach to a document's first request on a pipeline. Re-submitting the same document into an
appendpipeline with different controls does not change what later re-emissions (a revised matcher verdict, a new App verdict) do for that document. - Under
append, a pipeline-level payload such as an assembly or data-product dispatch aggregates several requests. Records of a skipping request are left out and the rest ships; a destination override applies only when every contributing request names the same destination. - The legacy
document.structuredandrun.completeddeliveries are not governed by these fields.
destination_override_missing and goes to the DLQ instead of silently reaching the production destination. Recreate or reactivate the destination, then replay the DLQ entry.