Guides
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
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"
}'
Stored immediately, delivered later
The Event is written durably the moment you publish it —
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.RFC 3339, future, within 30 days
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
Event scheduled
→
POST .../events/{event_id}/cancel
→
fan-out never happens
Cancellation only works on an event that's still waiting — once fan-out has actually started, it's too late.
| 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. |
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. |
| 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. |
Under the hood, deferred fan-out uses the queue's own native delayed-processing option —
there's no separate scheduler or cron sweep involved, so a scheduled event fires exactly
once its time arrives, not on the next periodic check.