Errors

The status codes the API returns, the shape of the error body and what to do in each case.

When something goes wrong, the API responds with an HTTP status code and a body with a single field:

{
  "message": "Client not found"
}

The message is text for the developer, not for showing to the user: it can change without notice. What your code should look at is the status code.

Status codes

CodeWhat it meansWhat to do
200It worked.
201The resource was created. Both Consumptions endpoints return this.
400The request could not be processed: the benefit was already used, it is not valid, or the user's points fall short.Read the message to know which case it is. Do not retry as is.
401The credential is missing, expired, or does not work for this endpoint.With an API key, check it is the right one. With an end-user token, renew it.
403The client exists but cannot have consumptions.Do not retry.
404The resource does not exist: client, benefit or commerce.Check the code or the id you sent.
422The body or the headers failed validation.See Validation errors.

Validation errors

The 422 is different from the rest: it does not carry a message but a detail with the list of everything that is wrong, one item per field.

{
  "detail": [
    {
      "loc": ["body", "amount"],
      "msg": "Input should be a valid integer",
      "type": "int_parsing"
    }
  ]
}

Each item of detail

locarrayrequired

Where the problem is. The first element says which part of the request (body, query, header, path) and the rest is the path to the field.

msgstringrequired

What is wrong with it.

typestringrequired

The kind of validation error.

The most frequent cause of a 422 is not the body: it is the missing X-Commerce-Id header. It is required on every endpoint of Authentication, My account and Public.

Two cases that are not errors

Requesting a code always answers 200

POST /v1/auth/otp/request answers 200 even if the email has no Loybox account. That is deliberate: if it answered differently, anyone could use the endpoint to find out which emails are registered. Do not use it to check whether a user exists.

No tier assigned is a 404

GET /v1/me/level returns 404 when the user does not have a tier yet, or when the commerce does not use tiers. It is the normal case for a new member, not a failure: in the UI the right move is to hide the tiers section, not to show an error.

Retries

Buying a benefit moves points, so a blind retry can charge them twice. That is what POST /v1/me/benefits/exchange accepts the Idempotency-Key header for: if you send the same value again, the purchase does not repeat.

Idempotency-Key: 8f14e45f-ea0f-4d1c-9a1b-2c3d4e5f6a7b

Use a different value for each purchase the user starts (a UUID is enough) and the same one across every retry of that purchase.