title: Rate Limits & Errors description: Limits, error conventions, and how to handle them gracefully.

Rate Limits & Errors

Rate limits

Limits are layered to protect the platform and keep usage fair:

  • Per IP for public submission endpoints.
  • Per workspace and per API key for authenticated endpoints.
  • Cost-based caps on expensive paths (AI scoring, email sending).

When you exceed a limit you receive 429 Too Many Requests. Back off exponentially and retry.

Error format

All errors share one shape:

{
  "error": "Human-readable message",
  "code": "MACHINE_CODE",
  "requestId": "req_..."
}
  • error is safe to surface to users — it never contains secrets, PII, or internal detail.
  • code is stable and meant for programmatic handling.
  • requestId maps the failure to a server-side log entry — include it when you contact support.

Common codes

| Code | Status | Meaning | | --- | --- | --- | | VALIDATION | 400 | Input failed validation; see details. | | UNAUTHORIZED | 401 | No valid session or API key. | | FORBIDDEN | 403 | Authenticated, but not allowed. | | NOT_FOUND | 404 | Resource does not exist (or belongs to another tenant). | | PLAN_LIMIT | 402 | The account's plan limit was reached. | | CONFLICT | 409 | Concurrent edit / duplicate. | | INTERNAL | 500 | Unexpected failure — see requestId. |

Handling 5xx errors

5xx responses mean something went wrong on our side. They are safe to retry with exponential backoff and jitter. If a failure persists, note the requestId and contact support.