Rate Limits & Errors
Understand API limits and how errors are structured.
Rate limits
Limits are applied per API key on a rolling 60-second window:
| Plan | Requests per minute |
|---|---|
| Free | 120 |
| Pro | 600 |
When a limit is exceeded the API responds with HTTP 429 and a Retry-After header:
HTTP/1.1 429 Too Many Requests
Retry-After: 23
Content-Type: application/json
{
"data": null,
"error": "Rate limit exceeded. Retry after 23 seconds."
} Respect the Retry-After value and do not retry before it elapses.
Error format
Every error response uses the same envelope as a success response — the data field is null and error contains a human-readable message:
{
"data": null,
"error": "List not found"
} The error string is intended to be readable but should not be parsed programmatically — use the HTTP status code for branching logic.
HTTP status codes
| Code | Meaning | Common causes |
|---|---|---|
200 | OK | Request succeeded |
400 | Bad Request | Missing required field, invalid body |
401 | Unauthorized | Missing or invalid API key |
403 | Forbidden | Key lacks required scope, or access denied to that resource |
404 | Not Found | List or item does not exist or is not accessible |
422 | Unprocessable Entity | Well-formed request that fails domain validation (e.g. inviting an existing member) |
429 | Too Many Requests | Rate limit exceeded — check Retry-After |
500 | Internal Server Error | Something went wrong on our end |
Versioning
The current API version is v1. All routes are prefixed with /v1/.
Breaking changes will be introduced under a new version prefix (/v2/), and v1 will
remain available for a minimum of 12 months after a new version is released.
Non-breaking additions (new fields, new optional parameters) may be made to existing endpoints without a version bump.
Idempotency
POST requests to action endpoints are not idempotent by default —
sending the same add request twice will add the item twice.
If you need idempotent behaviour (e.g. retry after a network timeout), deduplicate on your end
before sending or check the list state first with GET /v1/lists/:id/items.