Quick links

Checklists

Send up to 20 to-do items with an alert. The recipient ticks them off in Zona; retries never reset what they have done.

Some alerts come with work attached: drain the queue, restart the worker, check the dashboard. Add a todo array and Zona shows those steps as a checklist on the alert. Whoever reads it can tick items off or remove them.

{
  "title": "Worker queue stalled",
  "body": "orders-worker has not processed a job in 10 minutes.",
  "severity": "high",
  "todo": [
    "Drain the queue",
    { "id": "restart", "text": "Restart orders-worker" },
    { "text": "Verify the dashboard is green" }
  ]
}
Table, scrolls horizontally when narrow
Rule Detail
Length todo is an array of up to 20 entries, or null. Omitted or null means no checklist.
Entry shape Each entry is a string, or an object with text and an optional id.
Text 1 to 200 characters after trimming, whether it is a plain string or an object’s text.
id Must match ^[A-Za-z0-9][A-Za-z0-9._:-]{0,63}$ and be unique within the list.
Default ids An entry without an id gets one from its position: i1, i2, and so on.
Completion An entry carrying done_at is rejected. Completion belongs to the recipient, never the sender.

A list that breaks any rule returns 400 INVALID_PAYLOAD.

If you mix entries with and without an id, remember the default comes from the position. An explicit id of i2 on the first entry would clash with the second entry’s default and be rejected as a duplicate.

What the recipient can do

Link to this section
  • The alert’s detail screen shows the checklist. Ticking an item strikes it through.
  • Items can be removed. The recipient cannot add new ones, and the sender cannot change the list after it is sent.
  • The inbox list shows a done-out-of-total count rather than the items themselves.
  • A checklist expires with its alert on the account’s retention schedule.

Checklists and retries

Link to this section

Ticked items are state on the recipient’s side, so they are never part of what you send. That makes retries safe:

  • Replaying the same Idempotency-Key with the same payload returns the stored alert untouched. Items the recipient already ticked stay ticked.
  • Changing the list, even by one word, is a different payload. With the same key it returns 409 IDEMPOTENCY_CONFLICT, like any other changed field.

To send an updated list, send a new alert with a new key.

curl --request POST \
  "https://gerncrjtrdjtjvybvseb.supabase.co/functions/v1/notify" \
  --header "Authorization: Bearer $ZONA_SOURCE_TOKEN" \
  --header "Idempotency-Key: queue-stall-20260726-1410" \
  --header "Content-Type: application/json" \
  --data '{
    "title": "Worker queue stalled",
    "body": "orders-worker has not processed a job in 10 minutes.",
    "severity": "high",
    "todo": ["Drain the queue", "Restart orders-worker", "Verify the dashboard is green"]
  }'

Checklists with images

Link to this section

In a multipart/form-data request, send todo as one form part whose value is the JSON-encoded array, the same way data is sent:

--form 'todo=["Drain the queue","Restart orders-worker"]'

The full multipart format is on Images.