Delivery Scheduling
Publish an event now, but defer fan-out until a future time — useful for anything that needs to land at a specific moment rather than the instant you call the API.
Publishing for the future
Add an optional deliver_at field to the publish request — everything else about publishing stays the same.
curl -X POST https://ingest.staging.lobthat.com/api/2026-06/app_01J0ZXYZ/events \
-H "Authorization: Bearer whk_<your_key>" \
-H "Content-Type: application/json" \
-d '{
"event_type": "order.created",
"payload": { "order_id": "ord_123" },
"deliver_at": "2026-08-01T09:00:00Z"
}'
deliver_at only defers when fan-out happens, not whether the event exists. If you never set it, behavior is exactly today's: fan-out happens right away.deliver_at must be a valid RFC 3339 timestamp, strictly in the future, and no more than 30 days out. Any violation — malformed, in the past, or too far out — is rejected at publish time with 400 invalid_deliver_at, before anything is written.Cancelling before it fires
Cancellation only works on an event that's still waiting — once fan-out has actually started, it's too late. A "Cancel Event" button lives right in the dashboard's countdown panel for a scheduled event, behind a destructive-action confirmation.
| Situation | Result |
|---|---|
| already_cancelled | Event was already cancelled — cancelling twice is rejected. |
| already_fanned_out | Fan-out has already happened (including an immediate, non-scheduled publish) — too late to cancel. |
| not_scheduled | The event was never given a deliver_at in the first place. |
| cancellation_locked | Too close to deliver_at — see the cancel-lockout window below. |
How it shows up in Delivery Logs
A scheduled event has its own visible states, distinct from the normal delivered/retrying/failed lifecycle that only applies once fan-out has actually happened.
| Status | Meaning |
|---|---|
| scheduled | Waiting for deliver_at — no delivery attempts exist yet, and none will until then. |
| overdue | deliver_at has passed with no delivery attempt recorded yet — distinct from a healthy event that just hasn't been picked up in the last few seconds. See the overdue threshold below. |
| cancelled | Cancelled before fan-out — will never be delivered. |
| pending | Not scheduled at all, just hasn't fanned out yet (today's existing meaning, unchanged). |
| fanned_out | Fan-out has happened — normal delivery/retry tracking takes over from here. |
Application-level settings
Two related settings, both scoped per Application and saved together via a single "Save Settings" action on the Application's Delivery Scheduling settings card.
deliver_at a scheduled event is allowed to sit with zero delivery attempts before it's reported overdue instead of scheduled. Default 10 minutes, configurable 1–1440.deliver_at cancellation is refused. Default 30 seconds, configurable 0–3600 — set to 0 to disable the lockout entirely. The same check naturally covers an already-overdue event too, with no special-casing needed.