Errors and codes
Every API v1 error comes back in the same envelope:
{
"message": "Valor original deve ser positivo",
"code": "VALIDATION_ERROR",
"details": { "...": "opcional; ex.: erros de validacao campo a campo" }
}
message is human-readable (and may change); code is stable — program against the code, not the message. Handle any unknown code by its HTTP status.
Codes by HTTP status
400 — invalid request
| Code | When |
|---|---|
VALIDATION_ERROR | Invalid body or query; details carries the fields |
INVALID_ID | ID not in UUID format |
INVALID_WEBHOOK_URL | Webhook URL refused (non-HTTPS or internal network) |
INVALID_WEBHOOK_AUTH | Incomplete webhook authentication configuration |
SSRF_BLOCKED | URL resolves to a blocked destination |
INVALID_RECIPIENT | Invalid recipient for the notification's channel |
INVALID_STATUS_FOR_RESEND | Notification in a status that does not allow resending |
MISSING_CONTENT_PLACEHOLDER | Email layout without {{content}} |
SELF_DEACTIVATION / SELF_ROLE_CHANGE | Attempt to deactivate your own account / change your own role |
EMAIL_EXISTS | Email already registered |
401 — not authenticated
| Code | When |
|---|---|
UNAUTHORIZED | Key missing, invalid, revoked or expired; invalid session |
403 — no permission
| Code | When |
|---|---|
FORBIDDEN | The actor lacks the required permission |
API_KEY_FORBIDDEN | API key attempting an administrative resource or one outside its scope; required indicates the missing permission |
404 — not found
| Code | When |
|---|---|
NOT_FOUND | Nonexistent resource (or belonging to another organization) |
PERSON_NOT_FOUND, CHARGE_NOT_FOUND, CLASSIFICATION_NOT_FOUND, COLLECTION_RULE_NOT_FOUND, STEP_NOT_FOUND, MESSAGE_TEMPLATE_NOT_FOUND, NOTIFICATION_NOT_FOUND | Specific variants when the route validates a relationship |
409 — state conflict
| Code | When |
|---|---|
CONFLICT / DUPLICATE | Record conflicts with an existing one (document, name...) or with the current state — e.g. accepting an agreement that is no longer proposed (already accepted or a concurrent acceptance) |
USER_EXISTS / INVITATION_EXISTS | Invitation for an email that is already a user / already invited |
LAST_ADMIN | Downgrading or deactivating the last administrator |
ROLE_IN_USE, RULE_IN_USE, STEP_IN_USE, WORKSPACE_IN_USE, COMPANY_IN_USE, HAS_BRANCHES | Deletion blocked: the resource is in use |
CHARGE_HAS_RELATED_RECORDS | A charge with notifications/interactions/negativations/protests cannot be deleted; details carries the counts |
ENDPOINT_INACTIVE | Webhook redelivery to an inactive endpoint |
IDEMPOTENCY_KEY_REUSED | Same X-Idempotency-Key with a different body |
IDEMPOTENCY_REQUEST_IN_PROGRESS | Concurrent request with the same key still in flight |
NOT_READY | Resource not ready yet (e.g. export still processing) |
410, 413, 422
| Status | Code | When |
|---|---|---|
| 410 | EXPIRED | Expired resource (e.g. export download past its deadline) |
| 413 | FILE_TOO_LARGE | Import file above the limit |
| 422 | DEFAULT_IMMUTABLE | The main workspace / headquarters company cannot be removed |
| 422 | SYSTEM_ROLE_IMMUTABLE | System roles cannot be edited/deleted |
429 and 500
| Status | Code | When |
|---|---|---|
| 429 | RATE_LIMITED | The key's request limit was exceeded; retry with backoff (details) |
| 500 | INTERNAL_ERROR | Unexpected server failure; retry with the same X-Idempotency-Key |
Handling recipe
- 4xx except 409/429: your mistake; fix the request before repeating.
- 409: read the code; it is almost always a business rule protecting state (retrying does not fix it).
- 429 and 5xx: retry with exponential backoff and the same idempotency key — idempotency guarantees nothing executes twice.