ULTINEO

Error codes

A failed call uses the same envelope as a successful one: read the HTTP status code, then read response for a message describing what went wrong. Messages are stable English sentences you can log and show to an operator, but branch on the status code.

application/json
{
  "code": 403,
  "title": "Forbidden",
  "response": "The API key is missing the required scope: order:write"
}
FieldTypeDescription
codeintegerThe HTTP status code, repeated in the body.
titlestringThe short status label.
responsestringWhat went wrong.

Note — The 404 for an unknown path and the 429 described below are answered before your request reaches an endpoint; in those two answers code is a string ("404", "429"). Rely on the HTTP status code rather than on the type of that field.

Status codes

CodeStatusDescription
200OKA read succeeded, or an import accepted at least one item. Read the report line by line: some items may still be refused, and check the dry_run field it returns.
301Moved PermanentlyYou called http://. Repeat the call on https://.
400Bad RequestA read named no record (the read parameter is missing), or the request body is not valid JSON.
401UnauthorizedNo key was sent, the Authorization header does not start with Bearer , or the key has expired.
403ForbiddenThe key is unknown or disabled, it does not hold the scope the call needs, or it was used for another shop.
404Not FoundThe record does not exist in your shop — including a record that belongs to another shop — or the path does not exist.
409ConflictThe same record is already being imported by another request, or a voucher code is already taken.
413Payload Too LargeThe request body is larger than 200,000 bytes. Send smaller batches.
422Unprocessable EntityThe whole batch was refused: every item was refused, items is missing or empty, or the batch is over the resource's limit.
429Too Many RequestsToo many requests in a short time. Wait for the number of seconds given in the Retry-After header, then retry.
503Service UnavailableThe service is temporarily unable to handle this resource for your shop. Retry later.

Authentication failures

These are checked before anything else, on every path.

CodeMessageCause
401No valid API key provided.The Authorization header is missing, does not start with Bearer , or does not carry a shop key.
401The API key has expired.The key had an expiry date and it has passed. A key with no expiry date never raises this.
403The API key doesn't have permissions to perform the request.The key is unknown or disabled, or its shop is no longer active.

Note — An unknown key and a disabled key give the same 403 with the same message, on purpose: the API never confirms whether a key exists.

Scope and shop failures

CodeMessageCause
403The API key is missing the required scope: <scope>The key holds neither *, nor <resource>:*, nor the scope named. Add the scope to the key, or stop calling that endpoint.
403This API key can only read and write its own project.The request named a project other than the key's own shop. Remove the project field: the key already designates your shop.
403This API key is not attached to a project.The key is not linked to a shop. Use a key created for your shop.

Request failures

CodeMessageCause
400Invalid JSON.The body is not parseable JSON, or is a JSON value that is not an object.
400Missing required parameter: <name>.A read gave neither the record's key nor its id. The topic of each resource lists its read parameters.
400Name the customer to read: … / Name the payment to read: …The same case on the customer and payment reads.
413Request body too large.The body exceeded 200,000 bytes.
422Missing required field: items (…).The body has no items list, or items is not a list. The wording varies slightly from one resource to another.
422items is empty.The items list holds no item.
422A batch carries at most <limit> <records>.The batch is over the resource's limit, given in each endpoint table. Split it.
422The parameters were valid but the request failed.The method is not supported on that path. Only GET and POST are served.

Not found

CodeMessageCause
404<Record> not found.No record of your shop matches the key or id you read, for example Order not found. A record of another shop answers the same way. Check the spelling of the reference.
404The requested resource was not found.The path itself does not exist. Check it against the endpoint tables.

Refusals inside a batch

An import checks each item on its own. An item that fails a check is reported in the response's data list with "action": "refused", the status code and label of the refusal in code and title, and what to correct in reason. The other items of the batch carry on.

application/json
{
  "index": 3,
  "external_id": "SHP-20931",
  "action": "refused",
  "id": null,
  "code": 409,
  "title": "Conflict",
  "reason": "Another import is already writing this shipment.",
  "notice": []
}
code in a refused itemMeaningWhat to do
422A value is invalid or a required field is missing; reason names the field.Correct the item and send it again.
404The item refers to a record that is not in your shop, such as an order whose customer was not imported.Import the record it refers to first.
409Another request is importing the same record right now, or a voucher code is already held by another code.Retry the item later, or choose another code.
500The item could not be saved.Send the item again; the import is safe to replay.

So a batch answers:

Retrying safely

A 429, a 503, a dropped connection or a refused item with code 409 or 500 can all be retried. Every import is recognised record by record, so sending the same batch again never creates a duplicate: records already saved come back as unchanged. Wait a few seconds between retries, and honour Retry-After when it is present.