Docs · Errors
Error envelope
Every non-2xx response uses RFC 7807 problem-details JSON:
{
"type": "https://lumirecrm.com/errors/validation-error",
"title": "validation-error",
"status": 400,
"detail": "body.amount must be a positive decimal string",
"instance": "/v1/payments/deposits",
"errors": [ { "path": "body.amount", "message": "..." } ],
"request_id": "req_01H..."
}SDKs surface this as a typed exception (Python LumireCRMError, PHP LumireCRMException, Go *APIError) — always inspect .status and.detail rather than the message.
Status reference
| Status | Title | Meaning |
|---|---|---|
| 400 | validation-error | Body or query failed Zod validation. Field-level details in payload.errors. |
| 401 | unauthenticated | Missing / expired session cookie or invalid API key. |
| 403 | forbidden | Authenticated but the role/scope does not permit this operation. |
| 404 | not-found | Resource does not exist or is not visible to your tenant. |
| 409 | conflict | Unique-constraint violation (e.g. duplicate email, slug, ticket). |
| 422 | unprocessable-entity | Request was well-formed but semantically invalid (state machine violation). |
| 429 | rate-limit-exceeded | Too many requests. See X-RateLimit-* headers and the X-RateLimit-Tracker bucket id. |
| 500 | internal-error | Unexpected failure. Always logged with a request id; retry is safe for idempotent ops. |
| 503 | upstream-unavailable | A required upstream (LumireOne, gateway, S3) is down. Retry with backoff. |
Retry policy
- GETs and idempotent operations: retry on
500,502,503,504,408,425,429. Use exponential backoff. - POSTs without an Idempotency-Key header: do not retry blindly; inspect the error first.
- The official SDKs do not retry by default — wrap calls in your own retry policy that fits your latency budget.