# Send now, deliver later.

> Schedule push notifications with Pocket Alert. Set an exact time or a delay up to 30 days ahead, list pending messages, and cancel before delivery. No cron job required.

<!-- source: https://pocketalert.app/features/scheduled-delivery -->

Last updated: 2026-08-11

Set an exact time or a relative delay on any message, up to 30 days out, and cancel it any time before it fires. No cron job, no worker process.

Docs: https://info.pocketalert.app/features/scheduled-delivery.html

## Three steps, one extra field

1. **Add one field** — Take a message you already send and add send_at with a time, or delay with an offset.
2. **Keep the tid** — You get back a tid and the resolved delivery time in your timezone and in UTC.
3. **Cancel if needed** — List pending messages any time, and cancel with a DELETE if plans change.

## Two ways to say when

Every reminder you have ever wanted from a script needed a process that stayed alive until the moment arrived. Not any more.

- **Absolute times** — Give an exact timestamp in RFC3339, Unix time, or a plain date and time — whichever your language makes easy.
- **Relative delays** — Or give a relative delay: 30m, 2h, or bare seconds. Handy when the trigger is "two hours after this script started".
- **Your timezone, not UTC** — Times without an offset are read in your account timezone, so 09:00 means nine where you are.
- **List and cancel** — List everything pending and cancel any of it before delivery. A race with the dispatcher resolves cleanly, never halfway.
- **Encrypted until delivery** — Content sits encrypted at rest until it is delivered, attachments included. A cancelled message takes its file with it.
- **A schedule is a promise** — Priority and plan resolve at scheduling time. A message promised as critical arrives as critical, whatever changed since.

## How scheduled delivery works

    
Add `send_at` or `delay` to a normal create-message request. Instead of sending immediately, Pocket Alert stores an encrypted snapshot of the message and hands it to an internal dispatcher, which delivers it at the right moment as an ordinary push. The delivered message then appears in your history like any other.

    
You get back a `201` with `"scheduled": true`, the resolved delivery time in both your timezone and UTC, and a `tid` — keep that one, it is what you cancel with.

    
## What it replaces

    
Certificate expiry reminders, maintenance windows, a nudge two hours after a migration starts to go and check the row counts, a follow-up the morning after a deploy. All of that used to need a cron entry or a worker process that had to survive until the moment arrived. Now it is one extra field on a request you were already making.

    
## Edge cases, handled

    
A past `send_at` returns `400`, with sixty seconds of tolerance for clock skew — inside that window the message is simply sent now. Overdue messages after a restart are delivered late rather than dropped. Attachments upload when you schedule and are linked on delivery.

## FAQ

### How do I schedule a push notification?

Add `send_at` with an exact time or `delay` with a relative offset to any message. `send_at` accepts RFC3339, a Unix timestamp, or a plain `YYYY-MM-DD HH:MM`; `delay` accepts durations like `30m` and `2h`. Send one or the other, never both.

### How far ahead can I schedule?

Thirty days. Anything further out is rejected rather than silently clamped.

### Which timezone is used?

Your account timezone. A `send_at` of 2026-08-15 09:00 means nine in the morning where you are, not in UTC. Add an offset explicitly if you want to be unambiguous.

### Can I cancel a scheduled message?

List pending messages with `GET /v1/messages/scheduled` and cancel one with `DELETE /v1/messages/scheduled/{tid}`. If delivery has already started you get a `409` instead of a half-cancelled message. Cancelling also deletes any attachment.

### What if the delivery time passes during downtime?

It is delivered late, not dropped. If the service restarts past a delivery time, the message goes out on the next tick. The content sits encrypted at rest with your key from the moment you schedule it.

### Is scheduling available on the free plan?

Scheduled delivery is a paid feature, and a free-plan request using `send_at` or `delay` returns `403` rather than being silently sent immediately. Priority and plan are resolved when you schedule, so a message scheduled as critical still arrives as critical.
