Authentication
PushMail uses API keys for programmatic access and session cookies for the dashboard. All API requests must be authenticated.
API keys
API keys are the primary way to authenticate with the PushMail API. Every key starts with pm_live_ so you can easily identify them in your code and logs.
curl https://pushmail.dev/api/v1/contacts?siteId=1 \
-H "Authorization: Bearer pm_live_a1b2c3d4e5f6..."Key properties
| Property | Description |
|---|---|
prefix | Visible prefix like pm_live_a1b2c3d4 — shown in dashboard for identification |
scopes | Permission scopes. Default * for full access. Site-scoped keys restrict to a single site. |
siteId | Optional. If set, key can only access resources for this site. Ideal for client-side or per-project keys. |
lastUsedAt | Automatically tracked. See when each key was last used in the dashboard. |
Creating API keys
curl -X POST https://pushmail.dev/api/v1/api-keys \
-H "Cookie: session=YOUR_SESSION" \
-H "Content-Type: application/json" \
-d '{
"name": "Production Backend",
"siteId": 1
}'{
"data": {
"id": 1,
"name": "Production Backend",
"prefix": "pm_live_a1b2c3d4",
"key": "pm_live_a1b2c3d4e5f6789...",
"siteId": 1,
"scopes": ["*"],
"createdAt": "2025-01-15T10:00:00.000Z"
}
}Save your key immediately
The full API key is only returned once at creation time. We store a SHA-256 hash — the plaintext key cannot be retrieved later. If you lose it, delete the key and create a new one.
Managing keys
curl https://pushmail.dev/api/v1/api-keys \
-H "Cookie: session=YOUR_SESSION"curl -X DELETE https://pushmail.dev/api/v1/api-keys/3 \
-H "Cookie: session=YOUR_SESSION"Session authentication
The dashboard uses HTTP-only session cookies. Sessions expire after 7 days. This is used by the web UI — for programmatic access, use API keys.
curl -X POST https://pushmail.dev/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "you@company.com",
"password": "your-password"
}'
# Response sets cookie: session=abc123...curl https://pushmail.dev/api/v1/sites \
-H "Cookie: session=abc123..."Error responses
Authentication errors return standard JSON error responses:
{
"error": "Unauthorized"
}{
"error": "API key does not have access to this site"
}Best practices
- Use environment variables — Never hardcode API keys in source code.
- Create site-scoped keys — If a key only needs access to one site, set the
siteIdwhen creating it. - Use separate keys per environment — Different keys for development, staging, and production.
- Rotate keys periodically — Create a new key, update your app, then delete the old one.
- Monitor usage — Check
lastUsedAtto find unused keys you can clean up.