---
title: "Synthetic-signal dry-run preview"
method: POST
path: "/v1/delivery/bindings/{id}/preview"
tags: ["Delivery"]
---

# Synthetic-signal dry-run preview

`POST /v1/delivery/bindings/{id}/preview`

## Request

- Base URL: `https://api.talonic.com`
- URL: `https://api.talonic.com/v1/delivery/bindings/{id}/preview`
- Auth: HTTP bearer

Builds a synthetic {DeliveryEvent} that matches the binding's
`signal_filter.event_type` (overlaying any `signal_filter.match`
constraints), then walks the delivery pipeline up to — but NOT
including — `connector.deliver()`:
`resolver.resolve(signal) → projectFieldMap → serializer.serialize`.

When the resolver can load a real entity, `sample_mode` is `"real"`
and `projected` / `serialized` / `wire_preview` are populated. If the
resolver throws (typically `EntityMissingError` because the synthetic
entity id doesn't exist in this tenant), the service falls back to
`sample_mode: "structural"` — it returns the resolver's declared
`shape` without concrete data. The preview never makes a network
call, never inserts a delivery row, and never touches the DLQ.

## Path parameters

- `id` string, uuid, required

## Response `200`

Preview response — real dry-run or structural fallback.

- BindingPreviewResponse: Output of `POST /v1/delivery/bindings/{id}/preview`. When the resolver successfully loads a synthetic entity the full pipeline (`resolve → projectFieldMap → serialize`) runs and `sample_mode="real"`. When the resolver throws (commonly `EntityMissingError` on a synthetic id) the service falls back to `sample_mode="structural"` and returns only the resolver's declared shape — `projected`, `serialized`, and `wire_preview` are `null` in that case.
  - `available` true, required: Always `true`. Present so future gated-preview responses can set `available=false` without breaking consumers.
  - `sample_mode` 'real' | 'structural', required: `real` — the resolver loaded a synthetic entity and every pipeline stage ran. `structural` — the resolver threw (typically `entity_missing`) so only the declared shape is returned.
  - `signal` object, required: Synthetic {DeliveryEvent} built from `signal_filter.event_type` with placeholder entity ids (`<preview-{field}>`) and `signal_filter.match` overlaid so the synthetic signal passes its own filter. `customer_id` always matches the authenticated tenant.
  - `resolver` object, required
    - `type` string, required: Registered deliverable-resolver type (e.g. `markdown`, `run.dataspace.outcome`).
    - `shape` union, required: The resolver's declared `DeliverableShape`.
      - object
        - `kind` 'record', required
        - `is_collection` boolean
        - `columns` object[]
          - `name` string
          - `type` string
          - `nullable` boolean
      - object
        - `kind` 'blob', required
        - `mime` string, required
      - object
        - `kind` 'graph', required
        - `node_types` string[]
        - `edge_types` string[]
      - object
        - `kind` 'envelope', required
  - `projected` object, nullable, required: Resolver output after `projectFieldMap(binding.field_map)`. `null` when `sample_mode='structural'`.
  - `serialized` object, nullable, required: Serializer output (`kind: 'bytes' | 'rows' | 'graph' | 'object'` + per-kind fields). `null` when `sample_mode='structural'`.
  - `wire_preview` object, nullable, required: Static projection of how the wire-level payload would look at delivery time. Never sent to the connector. `null` when `sample_mode="structural"`.
    - `body_preview` string, required: UTF-8 body stringification, truncated to the first 8 KiB with an ellipsis if longer.
    - `mime` string: Inferred content type of the body.
    - `size_bytes` integer, required: Full body size in bytes (the serializer's real output, not the truncated preview).
    - `headers_preview` object, required: The `X-Talonic-*` headers that would ship on the wire. The `X-Talonic-Signature` header, when present, is rendered as `t=<preview>,v1=<preview>` — the preview never computes a real HMAC so the signing secret is not exercised.
  - `structural_sample` object: Only present when `sample_mode="structural"`. Mirrors `resolver.shape` for convenience.
    - `deliverable_type` string
    - `shape` unknown
  - `fallback_reason` string: Only present when `sample_mode="structural"`. Human-readable reason the resolver could not produce a real sample.

## Other responses

- `400`: The request is invalid.
- `401`: Missing or invalid API key.
- `404`: The requested resource was not found.
- `429`: Daily rate limit exceeded.

---

[API](https://skmtc.dev/talonic/apis/talonic-api.md) · [All operations](https://skmtc.dev/talonic/apis/talonic-api/llms.txt) · [OpenAPI document](https://skmtc.dev/talonic/apis/talonic-api/revisions/678fe5f8c9c3?raw)
