Skip to main content

Dead Letter Queue

Inspect permanently failed deliveries in the dead letter queue, filter them by binding or error code, and replay individual items or discard them.

Deliveries that exhaust all retry attempts are moved to the dead letter queue (DLQ). Items in the DLQ can be inspected, replayed (enqueues a fresh attempt), or deleted.

The DLQ is the terminal state for failed deliveries. Common error codes include connector_5xx (destination returned a server error), auth_failed (invalid credentials), ssrf_blocked (destination URL resolves to a private network), and payload_too_large (payload exceeds the cap). Non-retryable errors (auth_failed, ssrf_blocked) skip the retry ladder and go directly to the DLQ.

DLQ replay deletes the dead-letter row before enqueuing the new attempt. If the enqueue fails, the DLQ row is lost. This is an intentional trade-off: the system prefers losing a DLQ row over duplicating a delivery.
GET/v1/delivery/dlq

Query parameters

binding_idstringFilter by binding ID.
error_codestringFilter by error code.

Response

Response fields

dataarrayArray of dead-letter records.
data[].idstringDead-letter item UUID.
data[].binding_idstringBinding that produced this failure.
data[].event_idstringOutbox event ID (BIGSERIAL, as string).
data[].last_item_idstring | nullUUID of the last delivery attempt item.
data[].error_codestringMachine-readable error code (e.g. `connector_5xx`, `auth_failed`, `ssrf_blocked`, `payload_too_large`).
data[].error_messagestring | nullHuman-readable error message.
data[].attemptsintegerTotal number of delivery attempts made before reaching the DLQ.
data[].created_atstringISO 8601 timestamp when the item entered the DLQ.

Response

{
  "data": [
    {
      "id": "f6a7b8c9-d0e1-2345-fabc-567890123456",
      "binding_id": "d4e5f6a7-b8c9-0123-defa-345678901234",
      "event_id": "98750",
      "last_item_id": "e5f6a7b8-c9d0-1234-efab-456789012345",
      "error_code": "connector_5xx",
      "error_message": "HTTP 503",
      "attempts": 7,
      "created_at": "2024-09-16T03:00:00.000Z"
    }
  ]
}

Errors

Error responses

401unauthorizedMissing or invalid API key.
429rate_limitedToo many requests. Retry after the period indicated in the Retry-After header.
POST/v1/delivery/dlq/:id/replay

Response

Response fields

replayedbooleanAlways true on success. The DLQ row is deleted and a new delivery attempt is enqueued.

Response

{
  "replayed": true
}

Errors

Error responses

400bad_requestReplay is not available in master view (organization-wide API key).
401unauthorizedMissing or invalid API key.
404not_foundNo DLQ item with this ID exists for your organization.
429rate_limitedToo many requests. Retry after the period indicated in the Retry-After header.
DELETE/v1/delivery/dlq/:id

Response

Response fields

dismissedbooleanAlways true on success.

Response

{
  "dismissed": true
}

Errors

Error responses

400bad_requestDismiss is not available in master view (organization-wide API key).
401unauthorizedMissing or invalid API key.
404not_foundNo DLQ item with this ID exists for your organization.
429rate_limitedToo many requests. Retry after the period indicated in the Retry-After header.

Bulk replay

POST /v1/delivery/dlq/replay-all is the bulk form of the per-item replay: every dead-letter row matching the optional binding_id and error_code filters is deleted and re-enqueued as a fresh attempt-1 delivery, so the full retry ladder restarts for each. With no filters it replays the whole DLQ. Idempotency keys are unchanged across the replay, so receivers that dedupe on X-Talonic-Idempotency-Key are safe against duplicates.

POST/v1/delivery/dlq/replay-all

Query parameters

binding_idstringOnly replay dead-letter rows for this binding.
error_codestringOnly replay rows with this error code, for example `connector_5xx` after a destination outage.
Like the per-item replay, bulk replay deletes each DLQ row before enqueuing its new attempt. A typical recovery flow after a destination outage: filter the DLQ by error_code=connector_5xx, fix the destination, then replay-all with the same filter.