Help · section 39 of 44
Webhooks
Mirrors the in-app Help. The live copy in your console and `dlake guide help` are always current.
Outbound: the Data Lake POSTs your row changes to a URL you own. (For the opposite direction — a third party POSTing events into your tables — see Inbound Webhooks.)
POST /api/ddl/events/webhooks {name, url, filter:{tables, ops}} → subscription + whsec_ secret (shown once — used to verify the Stripe-style HMAC signature header t=...,v1=..., 5-minute replay window). The delivery worker POSTs event batches with retries and exponential backoff; subscriptions that exhaust retries dead-letter (inspectable per subscription) and auto-disable after 3 consecutive dead-letters so a permanently broken endpoint stops churning. Destination URLs are SSRF-checked (no loopback/RFC1918/link-local) both when the subscription is created and again at connect/delivery time — a URL that resolves to a private/internal address is rejected even if it looked safe at creation.
Undelivered events are retained until delivered (not just for the fixed replay window), so a subscription that’s briefly down catches up once it recovers — but retention is bounded: an event that goes undelivered for 30 days trips the max-age cap, which auto-disables the lagging subscription and releases its retained backlog so one dead consumer can’t pin the outbox forever. Re-enable (and optionally replay) once the endpoint is healthy.
Replay: POST /api/ddl/events/webhooks/{id}/replay rewinds the delivery cursor so past events still in the outbox (≤7-day retention) are re-delivered — fromRetentionStart, fromEventId, or fromUtc (clamped to the retention floor; re-enables + clears failure state). Re-delivery is at-least-once (dedup by EventId); replayed events are existence-checked (on every table) and re-evaluated against current RLS, so a since-deleted row’s insert/update is not re-sent (its delete tombstone still replays). Snapshot vs. live: a default-payload subscription re-sends the captured point-in-time snapshot from the outbox; a payloadQuery subscription re-runs the query at replay time, so it reflects current state (or the default fallback for since-deleted rows), not the historical row — use a default-payload subscription for exact historical replay.
Custom payload query (nested/multi-table payloads): a subscription can carry an optional payloadQuery — a read-only SELECT … FOR JSON run at delivery time, keyed by the changed row, whose JSON replaces each event’s data. So one webhook can deliver a joined/nested payload (e.g. an order with its line items) instead of just the watched row. Parameters available: @<PkColumn> per primary-key column, plus @dl_op/@dl_table/@dl_schema/@dl_rowKeyJson. Validated on save (single SELECT, must contain FOR JSON, parsed against the DB); RLS-scoped to the subscription owner; empty result (e.g. on DELETE) falls back to the default payload; query errors retry like any delivery failure. Reads live data at delivery time. Leave blank for the default single-row payload.