Skip to main content

Create Binding

Create a delivery binding that routes domain events through a deliverable resolver and serializer to a destination, with field mapping and retry policy.

Create a binding that wires a domain event to a destination. The compatibility triangle is validated on creation: the signal event type must be compatible with the deliverable resolver, the serializer must support the deliverable shape, and the connector must support the serializer format.

The typical workflow is: query the catalog endpoints top-down (signals, then deliverables, then serializers, then connectors), pick compatible values, and create the binding. A single event can fan out to multiple bindings — create separate bindings for each destination or output format you need.

The response returns the binding with is_active: true and last_status: null. The field_map controls payload projection: use static to inject fixed values, drop to remove fields, and key-value pairs to rename fields. The delivery_policy defaults to 7 attempts with exponential backoff over ~10 hours if omitted.

After creation, the binding is immediately live — the next matching event will trigger delivery. Use the binding preview to dry-run the resolve-project-serialize flow. Monitor delivery health via the history and DLQ endpoints.

Withholding fields with excluded_fields

The optional excluded_fields array is a binding-level egress filter: every field key it names is omitted from the delivered payload for this destination. It accepts up to 200 entries of 1-256 characters each, and it is the intended tool for pipeline-internal fields — join payloads like a matched reference row — that downstream stages consume but this particular destination must not receive. This is the only per-destination field withhold: a schema field's suppress_output or a resolution-policy include: false hides the field from the data product itself, not from the delivered capture payload.

Exclusions are honored by the pipeline.capture deliverable only, and the API rejects a create or update that sets excluded_fields on any other deliverable_type — on other deliverables the list would persist but every delivery would still ship the field, a silent no-op on a data-egress control. Matching against the payload is exact and case-sensitive on the schema field_name / cell field_key; an excluded field is removed both from the declared-field seed and from the cell overlay, so a populated cell cannot leak through.

An excluded_fields entry that matches no field withholds nothing — it is accepted silently at write time (usually a typo or a renamed schema field), and the payload delivers unchanged. The binding preview's exclusion_check is the only place this misconfiguration is surfaced, so preview after every change to the exclusion list.
Use the catalog endpoints (/v1/delivery/catalog/*) to discover valid combinations before creating a binding. The catalog lists all available signals, deliverables, serializers, and connectors with their compatibility constraints. Internal diagnostic fields (keys prefixed __) are always excluded from delivered payloads — you never need to list them in excluded_fields.
POST/v1/delivery/bindings

Body parameters

signal_filter*objectEvent filter. Must include `event_type` (e.g. `document.extraction.completed`).
deliverable_type*stringPayload resolver: `notification`, `document_capture`, `document_markdown`, `document_meta`, `run_outcomes`, `approved_record`.
serializer_format*stringOutput format: `json`, `ndjson`, `csv`, `xlsx`, `rows`, `graph`, `raw`.
destination_id*stringTarget destination ID.
name*stringBinding name (1-200 characters).
excluded_fieldsstring[]Field keys omitted from the delivered payload (max 200 entries, 1-256 chars each). Only valid with the `pipeline.capture` deliverable; matching is exact and case-sensitive.
field_mapobjectJSONPath field projection map. Keys are output field names, values are JSONPath expressions.
serializer_configobjectSerializer-specific configuration options.
resolver_configobjectResolver-specific options, e.g. `null_handling` for pipeline.capture.
delivery_policyobjectRetry policy with `max_attempts` (default 7) and `backoff_schedule` (array of ms delays).

Request body

{
  "name": "Notify on extraction complete",
  "signal_filter": { "event_type": "document.extraction.completed" },
  "deliverable_type": "document_capture",
  "serializer_format": "json",
  "destination_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "field_map": { "vendor": "$.vendor_name", "total": "$.amount" },
  "delivery_policy": { "max_attempts": 5, "backoff_schedule": [1000, 5000, 30000] }
}

Response

Response fields (201 Created)

idstringBinding UUID.
namestringBinding name.
signal_filterobjectEvent filter with `event_type` and optional match criteria.
deliverable_typestringPayload resolver type.
destination_idstringTarget destination UUID.
serializer_formatstringSerializer format.
serializer_configobjectSerializer-specific configuration.
excluded_fieldsstring[] | nullBinding-level egress filter; null when no exclusions are set.
field_mapobjectJSONPath field projection map.
delivery_policyobjectRetry policy.
is_activebooleanAlways true on creation.
last_statusnullAlways null on creation.
created_atstringISO 8601 creation timestamp.
updated_atstringISO 8601 last update timestamp.

Response (201 Created)

{
  "id": "d4e5f6a7-b8c9-0123-defa-345678901234",
  "name": "Notify on extraction complete",
  "signal_filter": { "event_type": "document.extraction.completed" },
  "deliverable_type": "document_capture",
  "destination_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "serializer_format": "json",
  "serializer_config": {},
  "field_map": { "vendor": "$.vendor_name", "total": "$.amount" },
  "delivery_policy": { "max_attempts": 5, "backoff_schedule": [1000, 5000, 30000] },
  "is_active": true,
  "last_status": null,
  "created_at": "2024-09-10T09:00:00.000Z",
  "updated_at": "2024-09-10T09:00:00.000Z"
}

Errors

Error responses

400validation_errorThe compatibility triangle validation failed: signal event type, deliverable type, and serializer format are not all mutually compatible.
401unauthorizedMissing or invalid API key.
429rate_limitedToo many requests. Retry after the period indicated in the Retry-After header.

Frequently asked questions

What is the default retry policy?+
By default, deliveries are retried up to 7 times with an exponential backoff schedule: 0s, 30s, 2m, 8m, 30m, 2h, 8h. Override this with the delivery_policy field.
What is the field_map for?+
The field_map applies a JSONPath projection to the resolved payload before serialization. Use it to rename fields, drop internal fields, or add static values. If omitted, the full payload is delivered as-is.
How do I find valid signal, deliverable, and serializer combinations?+
Walk the catalog endpoints top-down: GET /v1/delivery/catalog/signals for event types, then deliverables (check compatible_signals), then serializers (check supports_kinds against the deliverable shape), then connectors (check supported_serializers). Combinations chosen this way pass the compatibility triangle.
How is excluded_fields different from suppress_output on the schema?+
A schema field's `suppress_output` (and a resolution policy's `include: false`) hides the field from the data product itself. `excluded_fields` is the only per-destination withhold: it removes the field from this binding's delivered payload while every other destination and the product keep it.
Why does my excluded field still arrive at the destination?+
Matching is exact and case-sensitive against the schema field_name / cell field_key, and an entry that matches nothing withholds nothing — it is accepted silently at write time. Run the binding preview and check `exclusion_check.unmatched_keys` to find the typo or renamed field.