BoxLatviaDevelopers
Get access
Guides

Errors

Errors are returned in the standard problem details format with the content type application/problem+json. Check the HTTP status first; use type to tell causes apart.

Note
The explanatory texts in error responses (detail, message) are in English and may be reworded. Base your code on status and type, not on the text.

#The format

A validation error

Validation reports every problem at once, so you can fix them in one go.

curl -X POST "$API/v1/locations" \
  -u "$CLIENT_ID:$CLIENT_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "",
  "latitude": 95,
  "longitude": 24.0536
}'
422 Unprocessable Content
{
  "type": "https://api.boxlatvia.lv/problems/validation-failed",
  "title": "Validation failed",
  "status": 422,
  "detail": "One or more fields are invalid.",
  "request_id": "5f22a099-b84d-48eb-b078-6c5423a2175e",
  "errors": [
    {
      "field": "name",
      "message": "must not be empty"
    },
    {
      "field": "latitude",
      "message": "Number must be less than or equal to 90"
    }
  ]
}
FieldMeaning
typeA stable identifier for the kind of problem (see the table below). Match on this, not on the text.
title, detailA short, human-readable explanation. The wording may improve over time.
statusThe HTTP status, repeated.
request_idA unique id of this request, also in the X-Request-Id header. Quote it when you contact support.
errorsOnly on 422: a list of { field, message }, one per problem.

#Problem types

Every type starts with https://api.boxlatvia.lv/problems/. These are identifiers, not web pages.

TypeStatusMeaning
bad-request400The body is not valid JSON, or a parameter such as cursor cannot be read.
unauthorized401Missing, wrong, expired or revoked credentials, or an expired token.
forbidden403The IP address is not allowed for these credentials, or the action is not available to suppliers.
insufficient-scope403The credentials lack the scope the call needs; required_scope names it.
not-found404No such object of yours. Other suppliers' objects look exactly the same.
conflict / duplicate-external-id409The external_id is taken (existing_id names the other object).
location-has-boxes409The location still has boxes.
box-has-orders409The box has orders and cannot be deleted.
box-already-published409A published box cannot be submitted; withdraw it first.
image-limit409More than 20 pictures; limit and existing tell you the numbers.
request-in-progress409Your earlier call with the same Idempotency-Key is still running.
precondition-failed412If-Match is out of date: read the object again.
payload-too-large413The request is larger than 27 MB.
unsupported-media-type415Pictures must be sent as multipart/form-data.
validation-failed422A value is invalid; errors lists every problem.
box-incomplete422The box cannot be submitted yet; missing lists what it needs.
idempotency-key-reused422That Idempotency-Key was already used for a different request.
precondition-required428If-Match is missing.
too-many-requests429Too many failed authentications from your address; wait Retry-After seconds.
internal-error / timeout / storage-unavailable500Something went wrong on our side (timeout is 503, storage-unavailable is 502). Retry with the same Idempotency-Key.

#Examples

Wrong or missing credentials
curl "$API/v1/me"
401 UnauthorizedWww-Authenticate: Basic realm="BoxLatvia Supplier API", Bearer realm="BoxLatvia Supplier API"
{
  "type": "https://api.boxlatvia.lv/problems/unauthorized",
  "title": "Authentication required",
  "status": 401,
  "detail": "Send HTTP Basic credentials or a Bearer token.",
  "request_id": "3f502d49-40f5-43e8-8004-dc4bb2f28a99"
}
Object not found
curl "$API/v1/boxes/e8e189c3-3ac4-47d0-8ff1-584221c4e1ae" \
  -u "$CLIENT_ID:$CLIENT_SECRET"
404 Not Found
{
  "type": "https://api.boxlatvia.lv/problems/not-found",
  "title": "Not found",
  "status": 404,
  "detail": "No such box.",
  "request_id": "734e0d86-9a60-4107-9997-c9f0bcf77610"
}
A box that is not ready
curl -X POST "$API/v1/boxes/9d7f53d3-a9cd-4ee1-b9cf-470a572f8b4e/submit" \
  -u "$CLIENT_ID:$CLIENT_SECRET"
422 Unprocessable Content
{
  "type": "https://api.boxlatvia.lv/problems/box-incomplete",
  "title": "Box is incomplete",
  "status": 422,
  "detail": "Fill in description, price, price_unit, size, features before submitting this box for review.",
  "request_id": "f48c9ebd-fa4f-4b14-be21-b98154de2c1e",
  "missing": [
    "description",
    "price",
    "price_unit",
    "size",
    "features"
  ]
}
Rules between fields
curl -X POST "$API/v1/boxes" \
  -u "$CLIENT_ID:$CLIENT_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Box 2 m²",
  "location_id": "9d80d5f4-d17a-4f3e-99f6-4ab43b132bc3",
  "price": 10,
  "promotional_price": 12,
  "total_units": 5,
  "available_units": 8,
  "price_unit": "gadsimts",
  "features": [
    "sauna"
  ]
}'
422 Unprocessable Content
{
  "type": "https://api.boxlatvia.lv/problems/validation-failed",
  "title": "Validation failed",
  "status": 422,
  "detail": "One or more fields are invalid.",
  "request_id": "ce26822d-d546-4254-a374-08549ad6e04b",
  "errors": [
    {
      "field": "price_unit",
      "message": "is not a known price unit code"
    },
    {
      "field": "features",
      "message": "unknown or inactive feature code(s): sauna"
    },
    {
      "field": "promotional_price",
      "message": "must be lower than price"
    },
    {
      "field": "available_units",
      "message": "cannot be greater than total_units"
    }
  ]
}

#OAuth errors

The token endpoint follows the OAuth 2.0 standard instead: a JSON body with error and error_description.

Wrong client credentials
curl -X POST "$API/v1/oauth/token" \
  -u "$CLIENT_ID:$CLIENT_SECRET" \
  -d grant_type=client_credentials
401 Unauthorized
{
  "error": "invalid_client",
  "error_description": "Invalid client credentials."
}
Note
Treat 5xx and timeouts as temporary: retry with the same Idempotency-Key and growing pauses. Do not retry other 4xx errors without changing the request (except 412, after re-reading, and 429, after waiting).