Skip to main content

Error response format

When a request fails, the Flextell API returns a JSON object with two fields:
FieldTypeDescription
errorstringA machine-readable error code.
messagestringA human-readable description of what went wrong.
{
  "error": "invalid_token",
  "message": "The bearer token is expired or malformed."
}
Error responses never include a data field. Always check the HTTP status code before attempting to parse a response as a success.

HTTP status codes

StatusMeaningWhat to do
400 Bad RequestThe request body or query parameters are invalid or missing required fields.Fix the request — check required fields and data types.
401 UnauthorizedThe Authorization header is missing or the bearer token is invalid or expired.Refresh your access token and retry.
403 ForbiddenThe token is valid, but it lacks the required scope or permissions.Re-authorize with the correct OAuth scopes.
404 Not FoundThe requested resource does not exist.Check the resource ID and endpoint path.
409 ConflictThe resource already exists, or the requested state change conflicts with current state.Adjust your request to avoid the conflict (e.g., use a unique identifier).
422 Unprocessable EntityThe request is well-formed but fails validation rules.Read the message field for details on which field failed validation.
429 Too Many RequestsYou have exceeded the rate limit.Wait for the duration specified in the Retry-After response header, then retry.
500 Internal Server ErrorAn unexpected server-side error occurred.Retry with exponential backoff. If the issue persists, contact support.
503 Service UnavailableThe service is temporarily unavailable.Retry with exponential backoff.

Example error responses

401 Unauthorized
{
  "error": "invalid_token",
  "message": "The bearer token is expired or malformed."
}
422 Unprocessable Entity
{
  "error": "validation_error",
  "message": "The 'email' field must be a valid email address."
}
429 Too Many Requests
{
  "error": "rate_limit_exceeded",
  "message": "You have exceeded the allowed request rate. Please retry after 30 seconds."
}

Retry strategy

For 429 and 5xx responses, retry the request using exponential backoff with jitter:
1

Check the status code

Only retry on 429, 500, or 503. Do not retry 4xx errors other than 429 — they indicate a problem with your request that will not resolve on its own.
2

Respect Retry-After for 429 responses

When you receive a 429, read the Retry-After response header. It contains the number of seconds to wait before retrying. Do not retry sooner than this value.
3

Use exponential backoff for 5xx responses

For 500 and 503 responses, wait before retrying. Double the wait time on each subsequent failure, starting from a base of 1 second.
4

Add jitter

Add a small random delay (jitter) to your backoff interval. This prevents multiple clients from retrying simultaneously and overwhelming the server.
5

Set a maximum retry limit

Stop retrying after a reasonable number of attempts (for example, 5 retries). Surface the error to the user or your own error reporting system.
Example backoff intervals (with jitter):
AttemptBase waitWith jitter (±500ms)
11s0.5s – 1.5s
22s1.5s – 2.5s
34s3.5s – 4.5s
48s7.5s – 8.5s
516s15.5s – 16.5s
Never retry a 400, 401, 403, 404, 409, or 422 response automatically. These indicate a problem with the request itself. Retrying without fixing the underlying issue will produce the same error.

Common mistakes

Bearer tokens expire. When you receive a 401 with error: "invalid_token", refresh your access token using the OAuth 2.0 refresh token flow and retry the original request with the new token.
If you receive a 403, your token does not have the required permission for the action. Re-initiate the OAuth Authorization Code Flow and request the correct scopes. Check the API reference for each endpoint to confirm which scopes are required.
Check the message field in the error response. It describes which field is missing or malformed. Compare your request body against the API reference for that endpoint.
Verify that the resource ID in your request path is correct and that the resource has not been deleted. IDs are case-sensitive.