Quick links

Send your first alert

Install Zona, create a source, and send an alert from your terminal with curl, PowerShell, Python or Node.js.

You need an iPhone with Zona installed and a terminal on any computer. By the end of this page an alert from that computer will be sitting in your inbox.

Install Zona and create a source

Link to this section
  1. Install Zona on your iPhone and open it. Zona is currently a private TestFlight preview and coming to the App Store (availability).
  2. Go to Sources and create a source for the computer you are sitting at. Give it a name you will recognise in the inbox, such as Office PC.
  3. Copy the token that starts with zona_live_ straight away.

Put the token in an environment variable

Link to this section

Keep the token out of your scripts. For this walkthrough, set it for the current terminal session:

export ZONA_SOURCE_TOKEN='zona_live_YOUR_SOURCE_TOKEN'

For anything that runs unattended, move the token into your OS secret store or your CI provider’s secrets. Authentication and source tokens covers the options.

Send the alert

Link to this section

Every request needs three headers: the token as a Bearer credential, an Idempotency-Key that names this one event, and a Content-Type. title and body are the only required fields.

curl --request POST \
  "https://gerncrjtrdjtjvybvseb.supabase.co/functions/v1/notify" \
  --header "Authorization: Bearer $ZONA_SOURCE_TOKEN" \
  --header "Idempotency-Key: quickstart-$(date +%s)" \
  --header "Content-Type: application/json" \
  --data '{
    "title": "Hello from my terminal",
    "body": "If you can read this, the source token works.",
    "category": "test",
    "severity": "low"
  }'

Read the response

Link to this section

A new alert returns HTTP 202 with a body like this:

{
  "notificationId": "87c4215a-03e3-4c96-af7c-e4043120a514",
  "sourceId": "05c46ccb-0a9e-48c1-9b19-e0398f6ea69b",
  "sourceName": "Office PC",
  "acceptedAt": "2026-07-26T10:30:00.000Z",
  "idempotentReplay": false,
  "attachmentAccepted": false,
  "attachmentError": null,
  "pushAttempted": 1,
  "pushAccepted": 0,
  "pushQueued": 1
}

notificationId is the inbox record. pushQueued counts the phone deliveries Zona has lined up. It can be 0 if you are in quiet hours or have no phone registered for push, and the alert is still in your inbox. pushAccepted is always 0 here because push results arrive after the response.

Find it in the inbox

Link to this section

Open Zona. The alert is at the top of the inbox under the source name you chose, with a thin green ring around the source’s avatar for low severity. While Zona is open, a new alert shows as a banner at the top of the screen, or goes straight into the list if the inbox is already in view with no search or filter applied. If no banner appeared, check that notifications are allowed for Zona and that quiet hours are off; the alert stays in the inbox either way.

If it did not work

Link to this section
  • 401 with INVALID_TOKEN: the token is missing, mistyped, paused, expired or revoked. Check that the environment variable is set in the same terminal, or create a new key in Sources.
  • 400 with INVALID_IDEMPOTENCY_KEY: the key must be 8 to 128 characters of letters, digits, ., _, : and -, starting with a letter or digit.
  • 400 with INVALID_PAYLOAD: the JSON is malformed or a field breaks a rule. On Windows, check that the quotes survived your shell.

Every status code is listed in Errors and limits.

Before you wire this into a real job, read Idempotency and retries: a stable key per event is what keeps a retried request from sending the same alert twice. Then pick a ready-made integration from Recipes.