BoxLatviaDevelopers
Get access
Guides

Authentication

Every request is authenticated with the credentials BoxLatvia issued to you. Use HTTP Basic for the simplest integration, or OAuth 2.0 if your tooling expects it. Both give the same access.

#HTTP Basic

Send the client ID as the user name and the client secret as the password on every request. Almost every HTTP library does this for you.

curl "$API/v1/me" \
  -u "$CLIENT_ID:$CLIENT_SECRET"

Always use HTTPS. The API never accepts credentials over plain HTTP.

#OAuth 2.0 client credentials

Exchange your credentials for a short-lived bearer token and send that instead. Tokens last 15 minutes: when the API answers 401, request a new one. Cache the token and renew it a minute early, rather than requesting one per call.

#Get an access token

POST/v1/oauth/tokenno scope needed

OAuth 2.0 client credentials: exchange your client id and secret for a bearer token valid for 15 minutes.

Send the credentials as HTTP Basic (as in the example) or as client_id and client_secret in the form body. Errors follow the OAuth standard (invalid_client, invalid_scope, …) rather than the usual problem format.

Request body (application/x-www-form-urlencoded)

NameTypeDescription
grant_type requiredstringAlways client_credentials.
scopestringSpace-separated scopes you want the token to carry. Default: everything your credentials allow. You cannot ask for more than that.

Examples

Request a token
curl -X POST "$API/v1/oauth/token" \
  -u "$CLIENT_ID:$CLIENT_SECRET" \
  -d grant_type=client_credentials \
  -d "scope=boxes:read boxes:write"
200 OK
{
  "access_token": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2FwaS5ib3hsYXR2aWEubHYi…",
  "token_type": "Bearer",
  "expires_in": 900,
  "scope": "boxes:read boxes:write"
}
Wrong 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."
}

Errors

StatusWhen
400invalid_request, unsupported_grant_type or invalid_scope.
401invalid_client: the id or secret is wrong, or the access was revoked or has expired.
429Too many failed attempts from your address.

#Use the token

curl "$API/v1/me" \
  -H "Authorization: Bearer $TOKEN"

The token only carries the scopes you asked for. Revoking your credentials or narrowing their scopes takes effect on the very next request, even for tokens that were already issued. The signing keys are published at /v1/.well-known/jwks.json.

#Scopes

Scopes decide what a set of credentials may do. Ask only for what the integration needs.

ScopeAllows
reference:readRead the reference lists (amenities, districts, price units, sizes).
supplier:readRead your supplier profile and GET /v1/me.
supplier:writeChange your profile's contact and address fields.
locations:readList and read locations and their pictures.
locations:writeCreate, change and delete locations.
boxes:readList and read boxes and their pictures.
boxes:writeCreate, change and delete boxes; submit and withdraw them.
images:writeUpload and delete pictures of boxes and locations.

A call without the right scope is answered with 403 and the missing scope in required_scope.

Missing scope
curl -X POST "$API/v1/boxes" \
  -u "$CLIENT_ID:$CLIENT_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Box",
  "location_id": "9d80d5f4-d17a-4f3e-99f6-4ab43b132bc3"
}'
403 Forbidden
{
  "type": "https://api.boxlatvia.lv/problems/insufficient-scope",
  "title": "Forbidden",
  "status": 403,
  "detail": "This operation needs the scope boxes:write.",
  "request_id": "d504c7e6-8458-456a-884d-0b4ba02be2d3",
  "required_scope": "boxes:write"
}

#Restrictions on credentials

#Failed logins

After 10 failed authentications within 5 minutes from one IP address, further calls from that address are answered with 429 and a Retry-After header (in seconds) until the window passes. Do not retry a 401 in a loop.

Locked out
curl "$API/v1/me" \
  -u "$CLIENT_ID:$CLIENT_SECRET"
429 Too Many RequestsRetry-After: 300
{
  "type": "https://api.boxlatvia.lv/problems/too-many-requests",
  "title": "Too many requests",
  "status": 429,
  "detail": "Too many failed authentication attempts. Try again later.",
  "request_id": "88b1f62d-3509-4d1f-b542-ff67a35787ae"
}

#Keeping secrets safe