Errors & Rate Limits
The API uses standard HTTP status codes. Error responses always include a JSON body with an error key and a human-readable message.
Error response format
{
"error": "forbidden",
"message": "This API key does not have the required scope: invoices:write",
"required_scope": "invoices:write",
"key_scopes": ["invoices:read", "clients:read"]
}Validation errors (422)
{
"message": "The given data was invalid.",
"errors": {
"email": ["The email field is required."],
"due_date": ["The due date must be after the issue date."]
}
}HTTP status codes
| Code | Status | Meaning |
|---|---|---|
| 400 | Bad Request | The request was malformed. |
| 401 | Unauthorized | Missing or invalid API key. |
| 403 | Forbidden | Your key lacks the required scope. |
| 404 | Not Found | The resource does not exist or belongs to another business. |
| 422 | Unprocessable Entity | Validation failed. Check the errors field. |
| 429 | Too Many Requests | Rate limit exceeded. Retry after the Retry-After header value. |
| 500 | Server Error | Something went wrong on our end. Reported to Sentry automatically. |
Rate limits
Each API key is limited to 120 requests per minute. When exceeded, the API returns 429 with these headers:
X-RateLimit-Limit: 120 X-RateLimit-Remaining: 0 Retry-After: 60
Implement exponential backoff when you receive a 429. The window resets every 60 seconds.
Ping endpoint
Use this to verify your key is valid before making other requests.
GET
https://api.tryesperworks.com/api/v1/pingVerify your API key and inspect its scopes.