API overview
The public API is served at api.<DOMAIN> and versioned under /v1. It is the same API the dashboard uses — there is no private surface behind it.
curl http://api.localhost/v1/contacts \
-H "X-API-Key: $NOTIFYZR_API_KEY"Base URLs
| Environment | Base URL |
|---|---|
| Development | http://api.localhost |
| Self-hosted | https://api.<your-domain> |
Authentication
Every authenticated call needs exactly one header:
X-API-Key: <your key>A key belongs to exactly one organization, and there is no parameter that changes which — so everything below is implicitly scoped to that organization. Mint keys in the dashboard under API keys; see Authentication for how they are scoped, revoked and expired.
Three surfaces are not authenticated this way:
| Surface | Auth |
|---|---|
POST /v1/forms/{id}/submissions | None. HTML forms post here directly; it is rate-limited instead. |
GET /health | None. |
| The hosted unsubscribe page | The signed ?t= token in the link is the authorisation. |
Reference
Start with Conventions — the response envelope, status codes, pagination and rate limits are the same everywhere, and are not repeated on each page.
| Resource | Covers |
|---|---|
| Sending and messages | /send, /messages, /emails, channel messages |
| Contacts | Contacts, properties, CSV imports, the suppression list |
| Segments | Saved filters and live membership |
| Broadcasts | One email to a whole segment |
| Templates | Templates and folders |
| Forms | Hosted forms and their submissions |
| Automations | Event-triggered graphs, runs and metrics |
| Domains | Sender domains and DNS verification |
| Channels | Discord, Telegram and ntfy.sh |
| Webhooks | Signed event callbacks |
| Usage and health | Plan, quotas, current usage, liveness |
| Error codes | Every error.code the API returns |
| Endpoints | The whole route table on one page |
Health
GET /health is unauthenticated and returns the service's status. It is what the status page at status.<DOMAIN> probes.