# HookPush Free push notifications for people and their agents. A person opens https://hookpush.live on their phone or computer, allows notifications, and gets a private webhook URL. Anything that can make an HTTP request to that URL sends a notification to that person's devices. No account, no API key beyond the URL itself. ## Send a notification POST https://hookpush.live/h/ Any of these work: curl -d "Build finished" https://hookpush.live/h/ curl -H "content-type: application/json" \ -d '{"title":"Deploy","body":"v1.4 is live","url":"https://example.com"}' \ https://hookpush.live/h/ curl "https://hookpush.live/h/?title=Done&body=All+tests+pass" Fields: `title` (default "Notification"), `body` (also accepted as `message` or `text`), `url` (opened when the notification is tapped, http/https only), `tag` (a later notification with the same tag replaces the earlier one). Response: `{"ok":true,"delivered":1,"devices":1}`. 404 means the hook no longer exists. 429 means slow down; the limit is 30 notifications per minute per hook, see `retry-after`. ## Schedule one for later Add `delay` (preferred) or `at` to any of the forms above. curl -d "body=Stand-up in 5" -d "delay=25m" https://hookpush.live/h/ curl -H "content-type: application/json" \ -d '{"body":"Happy birthday","at":"2026-12-24T09:00:00-05:00"}' \ https://hookpush.live/h/ - `delay`: seconds, or `90s`, `10m`, `2h`, `3d`, `1w`, `1h30m`. Measured from the moment the server receives it, so clocks and timezones cannot disagree. Use this when you can. - `at`: ISO 8601 **with `Z` or an offset**, or a unix timestamp. A time without a timezone is refused, and so is a time already in the past. Up to one year ahead. - The reply is 202 with `{"scheduled":true,"id":"...","at":"","in_seconds":1500,"now":""}`. Check `in_seconds` matches what you meant. `GET https://hookpush.live/api/time` returns the server's clock. - `GET https://hookpush.live/h//scheduled` lists what is pending. - `DELETE https://hookpush.live/h//scheduled/` cancels one (or `POST ...//cancel`). - Up to 100 pending per hook. Delivery is within a few seconds of the due time. ## Channels: notify the visitors of your own website A personal hook reaches one person's devices. A channel reaches everyone who subscribed to it. Use one when you (an agent) run a website and want its visitors to hear from you. 1. Create the channel. No browser or account needed: curl -H "content-type: application/json" \ -d '{"name":"Ada\'s updates","url":"https://ada.agentwire.space"}' \ https://hookpush.live/api/channels The reply has `channel` (public id), `publish_url` (secret; save it, it is shown once), `subscribe_page`, `embed` and `service_worker`. 2. Put the `embed` tag in your page where the button should appear: That alone works everywhere: the button opens `subscribe_page`, where the visitor allows notifications. 3. Better: also publish a file at `/sw.js` on your site with exactly this line: importScripts('https://hookpush.live/sw.js'); Now visitors subscribe without leaving your site, and notifications arrive under your site's own name. The embed detects the file by itself. iPhone visitors still use the subscribe page, because Apple only allows push from sites added to the Home Screen. 4. Send to everyone: POST to `publish_url` exactly like a personal hook. `delay`, `at`, `url`, `tag`, `icon` (https image) and the scheduling endpoints all work. Without `url`, a tap opens the channel's `url`. `GET https://hookpush.live/api/channels/` returns `{name, url, subscribers}`. Up to 5000 subscribers. Embed options: `data-label`, `data-label-on`, `data-sw`, `data-target="#my-button"`; script API `HookPush.subscribe()`, `HookPush.unsubscribe()`, `HookPush.state`, event `hookpush:change`. Only notify people about what they subscribed for. ## Rules - The URL is the secret. Anyone who has it can notify its owner. Do not publish it. - A person can protect their hook with a free passkey account on the site. Then the URL can only send: adding devices, deleting, or replacing the URL needs their sign-in. If their URL leaks they replace it, and you will get 404 until they give you the new one. - You can only reach devices whose owner opened the site and allowed notifications for that hook. - Keep messages short. Title is cut at 120 characters, body at 1200. - A GET with no `title` or `body` sends nothing; it only reports `{"devices":n,"scheduled":n}`.