Every error returns a 4xx or 5xx status and the same JSON body, whatever the operation: a stable code, to test in your code; a message for a human, in the Accept-Language language (en, fr, es, it, de, pt), which may change; sometimes details.
Error body
{
"error": {
"code": "string",
"message": "string",
"details": "(optional)"
}
}Example: invalid request
Response 400
{
"error": {
"code": "validation_error",
"message": "Some fields are invalid. Please check your input.",
"details": {
"target": "query",
"issues": [
{
"path": "department",
"message": "Invalid string: must match pattern /^(\\d{2}|2[AB])$/i"
}
]
}
}
}details.target says where the problem is (json for the body, query, param for the path); details.issues lists each problem, with path (the field) and message.
The 23 codes
| HTTP | Code | Meaning | What to do |
|---|---|---|---|
400 | validation_error | Some fields are invalid. Please check your input. | Fix the request; do not retry it unchanged |
400 | bad_request | Your request is incomplete or malformed. | Fix the request; do not retry it unchanged |
400 | invalid_cursor | This pagination cursor is invalid. Start the list again without “cursor”. | Start the list again from the first page |
401 | invalid_api_key | Missing or invalid API key. Add the header “Authorization: Bearer fw_live_…”. | Fix the request; do not retry it unchanged |
401 | api_key_revoked | This API key has been revoked. Ask contact@floweet.com for a new key. | Write to us (key, scopes, API account) |
403 | insufficient_scope | This API key does not have the scope required by this route. | Write to us (key, scopes, API account) |
403 | live_not_enabled | Production is not enabled for this account yet: use an fw_test_ key or ask contact@floweet.com to enable it. | Write to us (key, scopes, API account) |
403 | account_suspended | API access is suspended for this account. Write to contact@floweet.com. | Write to us (key, scopes, API account) |
403 | account_misconfigured | This organization's API account is misconfigured (designated member missing). Write to contact@floweet.com. | Write to us (key, scopes, API account) |
403 | plan_required | This module is not included in your organization's plan. | The module is not in the organization's plan: change plans |
404 | not_found | This resource could not be found. | Fix the request; do not retry it unchanged |
404 | sirene_not_found | Establishment not found in the SIRENE directory. | Fix the request; do not retry it unchanged |
409 | idempotency_in_progress | A request with the same idempotency key is in progress. Retry in a moment. | Retry after Retry-After (or a few seconds) |
422 | idempotency_key_mismatch | This idempotency key was already used for a different request (method, path or body). Use a new key. | Fix the request; do not retry it unchanged |
422 | prospect_limit | You have reached the limit of 200 prospects. Delete some before adding more. | Delete prospects before creating more |
429 | rate_limited | Too many requests. Please try again in a moment. | Retry after Retry-After (or a few seconds) |
429 | test_quota_exceeded | Sandbox quota reached (1,000 calls per day with an fw_test_ key). Try again tomorrow. | Retry after Retry-After (or a few seconds) |
500 | internal_error | An unexpected error occurred. Please try again. | Retry with a growing delay and the same Idempotency-Key |
500 | database_error | The data could not be read or saved. Please try again. | Retry with a growing delay and the same Idempotency-Key |
502 | geocode_unavailable | Geocoding is temporarily unavailable. | Retry with a growing delay and the same Idempotency-Key |
502 | route_unavailable | Route calculation is temporarily unavailable. | Retry with a growing delay and the same Idempotency-Key |
502 | upstream_error | A partner service is not responding. Please try again in a moment. | Retry with a growing delay and the same Idempotency-Key |
503 | unavailable | This service is temporarily unavailable. Please try again in a moment. | Retry after Retry-After (or a few seconds) |
New codes may appear for new cases: handle an unknown code according to its HTTP status.
What the details carry
insufficient_scope:details.required(the scope needed) anddetails.granted(the key's scopes) — see scopes.plan_required:details.moduleanddetails.tier(the minimum plan) — see plans and AI.rate_limitedandtest_quota_exceeded:details.retryAfter, in seconds, like theRetry-Afterheader.
Retrying safely
- 4xx: do not retry unchanged, fix the request first — except
429(wait forRetry-After) and409 idempotency_in_progress(retry in a second). - 500, 502, 503, timeout or dropped connection: retry with a growing delay (1 s, 5 s, 30 s…), with the same
Idempotency-Key. You do not know whether the first request went through; the key ensures it runs only once (idempotency). - Quote the response's
X-Request-Idheader if you write to us: it finds your request in our logs.