Limits & errors
Free-plan quotas, rate limits, and the error envelope.
Free-plan limits
| Limit | Value |
|---|---|
| notifications / day | 250 (resets midnight UTC) |
| requests / minute / key | 120 |
| devices | 2 |
| API keys / project | 3 |
| request body | 32 KB |
Errors
Errors always use one envelope, and rate limits include a Retry-After
header:
{
"error": {
"code": "quota_exceeded",
"message": "Daily notification limit of 250 reached",
"details": { "reset_at": "2026-08-09T00:00:00.000Z" }
}
}Common codes:
| Code | Meaning |
|---|---|
unauthorized | missing, wrong, revoked or expired credential |
forbidden | authenticated but not allowed (e.g. missing permission) |
not_found | resource doesn't exist — or isn't yours |
validation_error | request shape rejected; details lists fields |
rate_limited | burst limit hit; retry after Retry-After seconds |
quota_exceeded | daily quota reached; details.reset_at says when |
idempotency_conflict | same Idempotency-Key racing a concurrent request |
invalid_json | body wasn't parseable JSON |
API reference
A machine-readable OpenAPI spec for the public endpoints lives at api.stdpush.com/docs.