Vai al contenuto

Notifiche programmate

Programma una notifica per più tardi con send_at, oppure ripetila secondo una pianificazione cron. PushWard la conserva e la invia al momento previsto, quindi dalla tua parte non deve restare in esecuzione nulla fino ad allora.

Post the same body you would send to POST /notifications, plus a send_at time, to POST /notifications/scheduled. PushWard stores it and sends it when send_at arrives, usually within a few seconds. Nothing reaches your devices or the in-app inbox before then. To send it again and again, add a recurrence rule.

Programma un promemoria
curl -X POST https://api.pushward.app/notifications/scheduled \
  -H "Authorization: Bearer hlk_YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Bins go out tonight",
    "body": "Collection is at 7:00 tomorrow.",
    "source": "home",
    "send_at": "2026-10-01T18:00:00+02:00"
  }'

The response is the schedule, with an id you can use to check on it or cancel it:

{
  "id": 42,
  "status": "scheduled",
  "send_at": "2026-10-01T16:00:00Z",
  "title": "Bins go out tonight",
  "body": "Collection is at 7:00 tomorrow.",
  "level": "active",
  "source": "home",
  "created_at": "2026-09-27T12:00:00Z"
}

From Home Assistant, pushward.send_notification takes the same send_at and recurrence fields, with the time zone defaulting to Home Assistant's own, and returns the schedule's id to the automation. pushward.list_scheduled_notifications and pushward.cancel_scheduled_notification cover the rest. See Home Assistant for an example.

Rules

  • send_at is an RFC 3339 timestamp. It must be in the future and at most 365 days ahead; otherwise the request fails with 400 and code scheduled_notification.invalid. Leaving it out fails the same way, unless the schedule has a recurrence. Any UTC offset works, and the response always reports it in UTC.
  • The rest of the body is checked exactly like POST /notifications, when you schedule it, so a bad media URL or an unknown activity_slug fails right away rather than at send time.
  • Up to 25 scheduled notifications can be waiting per account. One more returns 409 with code scheduled_notification.limit_exceeded. A repeating schedule takes one of those slots for its whole series.
  • Scheduling is free. The send counts toward your notification quota at the moment it goes out, like any other notification. If the quota is used up by then, the notification is not sent and its status becomes failed with failure_reason quota_exceeded. If your quota is already used up when you schedule, the request fails with the same 429 (quota.exceeded) as POST /notifications.
  • If the activity named in activity_slug was deleted before the send, the notification still goes out, without the link.
  • Revoking the integration key that created a scheduled notification deletes its pending schedules outright (they do not show up as canceled; one already being sent still goes out). Lowering the key's notifications level below schedule, or letting the key expire, instead makes each schedule fail with key_revoked when it comes due.
  • An integration key can list, read and cancel only the scheduled notifications it created.
  • The names in an organization key's target are resolved when you schedule, so renaming a group afterwards does not matter. Who is in a group is read when it is sent, and a group deleted by then reaches nobody. See Teams.
ℹ Info

Scheduled notifications need notifications at schedule on your integration key; send covers only POST /notifications. Your default key already has it.

Status

StatusMeaning
scheduledWaiting for send_at. A repeating schedule comes back to this status after each send.
sendingBeing sent right now. It can still be canceled: the send is dropped unless it has already gone out.
sentDelivered. notification_id is the notification it became, sent_at when it went out, and delivery / reason report the push outcome as on POST /notifications. A repeating schedule ends here once its until or count runs out.
failedNot sent. failure_reason is quota_exceeded, key_revoked, target_deleted (every group, tag and member an organization's target names is gone, see Teams) or internal_error. For a repeating schedule, key_revoked ends the series, and so does target_deleted unless the target names a member who can be invited back (then only that send is skipped). The other two skip one send and the series carries on.
canceledCanceled before it was sent (a repeating schedule: before its next send). canceled_at is when. The content stays readable so the app can show what was canceled.

Sent and failed schedules stay readable for 7 days, canceled ones for 24 hours, then they are removed.

In arrivo nella versione 1.17.0 dell'app

Questa sezione descrive una funzionalità di un aggiornamento dell'app in attesa di revisione su App Store. Si sblocca qui automaticamente non appena l'aggiornamento è disponibile.

Repeating notifications

Add a recurrence object to send the same notification on a cron schedule. The schedule keeps one id for the whole series and holds one pending slot: after each send it goes back to scheduled with the next send_at, and canceling it stops the series.

Dal lunedì al venerdì alle 8:00 a Varsavia
curl -X POST https://api.pushward.app/notifications/scheduled \
  -H "Authorization: Bearer hlk_YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Daily stand-up",
    "body": "Stand-up starts at 08:15.",
    "source": "calendar",
    "recurrence": {
      "cron": "0 8 * * 1-5",
      "timezone": "Europe/Warsaw"
    }
  }'

Created on a Monday afternoon, the first send is Tuesday at 08:00 in Warsaw:

{
  "id": 43,
  "status": "scheduled",
  "send_at": "2026-09-29T06:00:00Z",
  "title": "Daily stand-up",
  "body": "Stand-up starts at 08:15.",
  "level": "active",
  "source": "calendar",
  "recurrence": {
    "cron": "0 8 * * 1-5",
    "timezone": "Europe/Warsaw"
  },
  "occurrence": 0,
  "created_at": "2026-09-28T12:00:00Z"
}
FieldTypeRequiredDescription
cronstringYesA standard 5-field cron expression (minute, hour, day of month, month, day of week) or one of @hourly, @daily, @weekly, @monthly, @yearly. Sends must be at least 15 minutes apart. @every and a TZ= prefix are rejected; the zone goes in timezone.
timezonestringYesIANA time zone name, such as Europe/Warsaw or America/New_York. The cron expression runs on local wall-clock time there, so 08:00 stays 08:00 across daylight saving changes.
untilstringNoRFC 3339 timestamp of the last allowed send (inclusive).
countintegerNoNumber of sends, 1-1000. Only real sends count: a skipped one does not (the quota was used up, or nothing was left in an organization's target but a removed member who can be invited back).

Set until or count, not both. With neither, the series runs until you cancel it.

cronSends
0 8 * * 1-5Weekdays at 08:00
30 7 * * *Every day at 07:30
0 10 * * 6,0Saturdays and Sundays at 10:00
0 9 * * 1Mondays at 09:00
0 18 1 * *The 1st of every month at 18:00
0 */4 * * *Every 4 hours, on the hour
*/15 9-17 * * 1-5Every 15 minutes from 09:00 to 17:45 on weekdays
@dailyEvery day at midnight (same as 0 0 * * *)
  • send_at is optional with a recurrence. It marks where the series starts: the first send is the first cron match at or after it, and it defaults to now. If you pass it, the rules above apply to it.
  • The first send must be at most 365 days ahead, so a rule whose first match is further out (one for February 29, say) fails with 400 scheduled_notification.invalid. Later sends have no such limit.
  • Every send counts toward your notification quota when it goes out, like any other notification.
  • If sends fall due during an outage, the pending one goes out when service returns and the rest are skipped, never sent in a burst.
  • Daylight saving time: on the day the clocks go back, a time inside the repeated hour sends once. On the day they go forward, a time inside the skipped hour sends just after it (02:30 becomes 03:30), so the day is not lost.

A repeating schedule's response also carries recurrence, occurrence (sends so far) and last_sent_at. send_at is the next send. notification_id, delivery and reason describe the latest send, and failure_reason is set when the latest one due was skipped, until the next send goes out.

List, check and cancel

GET /notifications/scheduled lists your schedules. By default (?status=scheduled) it returns the ones still waiting, soonest first; pass sent, failed, canceled or all for the others, latest first. limit (1-100, default 50) caps a page. When more remain, the response has a next_cursor: pass it back as ?cursor= with the same status for the next page. The last page has no next_cursor, and a cursor only works with the status it came from. GET /notifications/scheduled/{id} returns one.

Annulla una notifica programmata
curl -X DELETE https://api.pushward.app/notifications/scheduled/42 \
  -H "Authorization: Bearer hlk_YOUR_TOKEN"

A cancel returns 204 and the schedule becomes canceled: it is not sent, and a repeating schedule stops for good. It stays readable for 24 hours, then it is deleted. A schedule that is being sent right now is canceled too, unless that send has already gone out: then the notification still arrives, a repeating schedule is canceled after that send, and a one-time schedule counts as sent, so the cancel only removes its record. Canceling a canceled schedule again changes nothing, and canceling one that was already sent or failed only removes its record.

Add ?purge=true to delete the schedule outright, in any status, with no canceled record. Use it when you replace a schedule with a new one, so the old one does not show as canceled in the app.

In arrivo nella versione 1.15.0 dell'app

Questa sezione descrive una funzionalità di un aggiornamento dell'app in attesa di revisione su App Store. Si sblocca qui automaticamente non appena l'aggiornamento è disponibile.