FluentaAPI

Errors

The shape of every error response and each code the API can answer: its HTTP status, when it appears and what to do.

Every error response has the same shape:

{
  "statusCode": 404,
  "code": "ORGANIZATION_NOT_FOUND",
  "message": "Organización no encontrada"
}
  • Branch on code. A code keeps its name once published.
  • message is in Spanish and is for the person. Show it as it comes; do not parse it in your program.
  • Some codes add fields that name what failed: scope, feature, roles, field, maxDays, supported, reason, retryAfterSeconds, details. The tables say which.
  • A refused write changed nothing.

Requests that fail validation

A query or a body that fails its validation answers 400 INVALID_REQUEST with details: one row per failure.

curl 'https://api.fluenta.io/v1/external/me/usage?days=0' \
  -H 'Authorization: Bearer fluenta_live_xxxxxxxxxxxxxxxx'
{
  "statusCode": 400,
  "code": "INVALID_REQUEST",
  "details": [{ "field": "days", "message": "days must not be less than 1" }],
  "message": "La solicitud no es válida: revisa «days»."
}

field is the query parameter or the body field, as a path (page, items.0.name). It is null when the failure names none. Each row's message comes as the validation worded it.

400: the request

CodeWhenWhat to do
INVALID_REQUESTThe query or the body fails its validation. Carries details.Fix the fields details names. Do not retry the request unchanged.
INVALID_DAYday, from or to is not a real YYYY-MM-DD day. field says which.Send a real day, on the plant's clock.
RANGE_INVALIDfrom is after to.Swap the dates.
RANGE_TOO_LARGEThe range covers more days than maxDays: 92, or 31 in getPauses.Ask for a shorter range, or split it into several.
GROUP_BY_UNSUPPORTEDThe figure is not grouped by that groupBy. supported lists the ones it has.Use one from supported.
FILTER_UNSUPPORTEDA filter (moduleId, operatorId, operationId) the figure does not have under that grouping, or more than one filter at once.Send one filter and a grouping from supported. If supported comes empty, drop the filter.
OPERATION_REQUIREDgetStationActivity with view=events and no operationId.Add the operationId of the «puesto» (station).
INVALID_IDEMPOTENCY_KEYThe Idempotency-Key header is not 1 to 255 visible ASCII characters, without spaces.Send a valid key.

401: the credential

CodeWhenWhat to do
INVALID_API_TOKENThe header is missing, or the credential is not one of this API, is unknown, expired or revoked, or its user is inactive. One body for every case.Do not retry. Create a new token in «Configuración» (Settings) → «Tokens de API» (API tokens), or connect the app again.

402: the subscription

CodeWhenWhat to do
ORG_BLOCKEDThe organization's subscription is paused.Do not retry: the organization answers again once its subscription is no longer paused. Your other organizations are unaffected.

403: the permission, the plan or the role

CodeWhenWhat to do
INSUFFICIENT_SCOPEThe credential lacks the permission the route asks for. scope says which.A token never gains a permission: create a new one that has it. A connected app connects again with the permission ticked. See Permissions.
PLAN_LIMITThe organization's plan does not include what you asked for. feature names the plan feature that is missing.Do not retry. getPlan lists what the plan allows. See Plans.
ROLE_NOT_ALLOWEDOn a write: your role in that organization does not make that change in the dashboard. roles lists the roles that do.A permission never widens a role. Ask someone with one of those roles to make the change.

404: something that does not exist or is out of your reach

A row of another organization and a row that does not exist answer the same. The API does not say which of the two it is.

CodeWhenWhat to do
ORGANIZATION_NOT_FOUNDThe organization does not exist, or your user does not belong to it. Never a 403.Take the organizationId from getMe or listOrganizations.
MODULE_NOT_FOUNDThe «módulo» (production line) is not in that organization.Take the id from listModules or getFloor.
OPERATION_NOT_FOUNDThe «puesto» (stationId or operationId) is not in that organization.Take the id from listStations or listOrganizationStations.
OPERATOR_NOT_FOUNDThe «operario» (operator) is not in that organization.Take the id from listOperators.
REFERENCE_NOT_FOUNDThe «referencia» (an order lot) is not in that organization.Find it with searchReferences, getProgram or listOnHold.
CATALOGUE_ENTRY_NOT_FOUNDThat entry is not in the organization's catalogue.Take the id from listCatalogue.

409: still running, or already changed

CodeWhenWhat to do
IDEMPOTENCY_IN_PROGRESSThe same Idempotency-Key is still being answered. Carries Retry-After.Wait that many seconds and retry the same request with the same key.
PREVIEW_STALEOn a delete: the confirmation ran out (it lasts 15 minutes), or what the preview showed has changed. reason is expired or changed.Ask for the preview again and show it to the person.

422: a write that cannot be done as sent

CodeWhenWhat to do
CONFIRMATION_REQUIREDA delete without the confirmationToken of its preview, or with one that is not this delete's. reason is missing or invalid.Call previewDeleteReference or previewDeleteCatalogueEntry, show the answer to the person, and send the confirmationToken unchanged.
IDEMPOTENCY_KEY_REUSEDThat Idempotency-Key already answered another request.Use a new key for each distinct write.

429: the rate limit

CodeWhenWhat to do
RATE_LIMITEDThe credential spent a budget of its rate limit. Carries the Retry-After header, and retryAfterSeconds in the body.Wait that many seconds and retry. See Rate limits.

503: the query took too long

CodeWhenWhat to do
ANALYTICS_TIMEOUTA range of getEfficiency, getProduction or getBilling ran past its time limit.Ask for a shorter range.

What to retry

  • Yes: a 429, after Retry-After. A 409 IDEMPOTENCY_IN_PROGRESS, with the same key.
  • Yes, with care: a write that ended in a timeout or a 5xx may have run or not. If you sent it with an Idempotency-Key, retry that same request with the same key: the API returns the first answer, with Idempotency-Replayed: true, and does not write twice. That is why it pays to send a fresh key with every write.
  • No: any other 4xx. Repeating the same request answers the same.

A write can also answer a refusal of the dashboard's own rules, with a code of its own that is not in these tables. Handle it by its HTTP status and show its message.

On this page