Skip to content

Scheduled Delivery

Send a message now, have it arrive later. Add send_at or delay to any Create Message request and Pocket Alert stores it encrypted until the delivery time, then sends it as a normal push.

No cron job on your side, no queue worker, no process that has to stay alive until Tuesday.

Two ways to say when

ParameterAcceptsExamples
send_atRFC3339, Unix timestamp, or YYYY-MM-DD HH:MM2026-08-15T09:00:00Z, 1786867200, 2026-08-15 09:00
delayGo-style duration or bare seconds30m, 2h, 90s, 3600

Send one or the other — passing both returns 400.

A send_at without a timezone offset is read in your account timezone, so 2026-08-15 09:00 means nine in the morning where you are, not in UTC. Set it under account settings.

Scheduling a message

bash
curl -X POST "https://api.pocketalert.app/v1/messages" \
  -H "Token: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Certificate expires tomorrow",
    "message": "api.example.com — renew before 09:00 UTC",
    "send_at": "2026-08-15T09:00:00Z",
    "level": "high"
  }'
bash
curl -X POST "https://api.pocketalert.app/v1/messages" \
  -H "Token: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Check the migration",
    "message": "Started at 14:02 — verify row counts",
    "delay": "2h"
  }'
javascript
await fetch('https://api.pocketalert.app/v1/messages', {
  method: 'POST',
  headers: { 'Token': 'your-api-key', 'Content-Type': 'application/json' },
  body: JSON.stringify({
    title: 'Check the migration',
    message: 'Started at 14:02 — verify row counts',
    delay: '2h'
  })
});
python
import requests

requests.post(
    'https://api.pocketalert.app/v1/messages',
    headers={'Token': 'your-api-key'},
    json={
        'title': 'Check the migration',
        'message': 'Started at 14:02 — verify row counts',
        'delay': '2h'
    }
)

A scheduled message returns 201 with "scheduled": true instead of a delivered message:

json
{
  "tid": "n8k2vq7pxr4m",
  "scheduled": true,
  "status": "pending",
  "title": "Check the migration",
  "deliver_at": "09.08.2026 16:02:00",
  "deliver_at_utc": "2026-08-09T13:02:00Z",
  "tz": "Europe/Berlin"
}

Keep the tid — that is what you cancel with.

Listing scheduled messages GET

GET https://api.pocketalert.app/v1/messages/scheduled

Returns pending messages by default, soonest first.

Query parameterValuesDescription
statuspending, sending, sent, canceled, failed, allFilter by state. Defaults to pending.
bash
curl -X GET "https://api.pocketalert.app/v1/messages/scheduled?status=all" \
  -H "Token: your-api-key"

Each item carries tid, title, message, priority, status, deliver_at, deliver_at_utc, tz, application, device, created_at, and actions when the message has buttons.

Cancelling DELETE

DELETE https://api.pocketalert.app/v1/messages/scheduled/{tid}
bash
curl -X DELETE "https://api.pocketalert.app/v1/messages/scheduled/n8k2vq7pxr4m" \
  -H "Token: your-api-key"
StatusMeaning
200Cancelled. Any attachment is deleted with it.
404No scheduled message with that tid on your account
409Already sent, already sending, or already cancelled

Cancelling races the dispatcher safely: if delivery has already begun, you get 409 rather than a half-cancelled message.

Rules worth knowing

Horizon is 30 days. Anything further out is rejected.

Past times return 400, with 60 seconds of tolerance for clock skew. Inside that window the message is simply sent immediately.

Level and plan are resolved when you schedule, not when it delivers. A message scheduled as critical on a paid plan still arrives as critical even if the plan lapses in between. A schedule is a promise.

Attachments upload at scheduling time and are linked to the message on delivery. Cancelling removes the stored file.

Overdue messages are delivered late, not dropped. If the service restarts past a delivery time, the message goes out on the next tick rather than disappearing.

Content is encrypted at rest with your personal key from the moment you schedule it, the same as regular messages.

Paid feature

Scheduled delivery is available on paid plans. A free-plan request with send_at or delay returns 403 — nothing is silently dropped.

Pocket Alert Documentation