Errors & Rate Limits
Error format
Every error response has the same shape:
{
"success": false,
"code": "VALIDATION_ERROR",
"message": "Validation failed",
"details": { "keyword": ["String must contain at least 2 character(s)"] }
}details is only present on some errors. For validation errors, it maps each invalid field to
its messages.
Error codes
| HTTP | code | Meaning |
|---|---|---|
| 400 | VALIDATION_ERROR | The request body or query failed validation. See details. |
| 400 | BAD_REQUEST | The request is malformed, e.g. a missing x-workspace-id. |
| 401 | UNAUTHORIZED | The API key is missing, invalid, rotated, or revoked. |
| 402 | INSUFFICIENT_CREDITS | Not enough credits for this action. |
| 403 | FORBIDDEN | The key is valid but can’t access this resource, e.g. a workspace that isn’t yours. |
| 404 | NOT_FOUND | The site or article doesn’t exist in this workspace. |
| 409 | CONFLICT | The action conflicts with the current state. |
| 429 | RATE_LIMIT_EXCEEDED | Too many requests, or a daily limit was reached. |
| 500 | INTERNAL_ERROR | Something went wrong on our side. Retry with backoff. |
Rate limits
| Limit | Value |
|---|---|
| Per API key | 60 requests / minute |
| Per IP address (all routes) | 200 requests / minute |
| Article generation | Articles per site per day, depending on your plan. Resets at 00:00 UTC. |
Responses include standard RateLimit-Limit, RateLimit-Remaining, and RateLimit-Reset
headers. If you get a 429, wait until the reset time before retrying.
Last updated on