Getting started
This page takes you from nothing to a box waiting for review. It uses real requests and the real answers the API gives.
You need credentials first. Everything below uses placeholders:
export API="https://api.boxlatvia.lv"
export CLIENT_ID="bxc_..." # the client ID BoxLatvia gave you
export CLIENT_SECRET="bxs_..." # the secret shown to you once-
#Get credentials
Credentials are issued by BoxLatvia, for one supplier. Each set has a client ID (public), a secret (shown once, store it like a password) and a list of scopes. Ask for separate credentials for each system you connect, so each can be revoked on its own. How to request access.
-
#Make your first call
Check that your credentials work. The answer shows who you are, which scopes you have and your supplier profile.
Who am Icurl "$API/v1/me" \ -u "$CLIENT_ID:$CLIENT_SECRET"const API = "https://api.boxlatvia.lv"; const auth = "Basic " + btoa(`${CLIENT_ID}:${CLIENT_SECRET}`); const res = await fetch(`${API}/v1/me`, { headers: { Authorization: auth }, }); console.log(res.status, await res.json());import requests API = "https://api.boxlatvia.lv" r = requests.get( f"{API}/v1/me", auth=(CLIENT_ID, CLIENT_SECRET), ) print(r.status_code, r.json())200 OK{ "client": { "client_id": "bxc_8F2ZPMcAmQZzr243", "scopes": [ "reference:read", "supplier:read", "supplier:write", "locations:read", "locations:write", "boxes:read", "boxes:write", "images:write" ] }, "supplier": { "id": "9fbb9ba2-6be5-4ae3-9b54-9fd36e889130", "name": "Imanta Storage SIA", "reg_nr": "40103456789", "vat_reg_nr": "LV40103456789", "address": "Kurzemes prospekts 1", "address_city": "Rīga", "address_country": "Latvija", "country": "LV", "person_type": "legal", "contact_person_name": "Anna Bērziņa", "contact_person_email": "anna@imantastorage.example", "contact_person_phone": "+371 20000000", "created_at": "2026-11-07T09:30:12.418Z", "updated_at": "2026-11-07T09:30:12.418Z" } } -
#Look up the codes you need
Amenities, districts and price units are sent as stable codes. Fetch the lists once and keep them. Reference data
curl "$API/v1/reference/districts" \ -u "$CLIENT_ID:$CLIENT_SECRET"const API = "https://api.boxlatvia.lv"; const auth = "Basic " + btoa(`${CLIENT_ID}:${CLIENT_SECRET}`); const res = await fetch(`${API}/v1/reference/districts`, { headers: { Authorization: auth }, }); console.log(res.status, await res.json());import requests API = "https://api.boxlatvia.lv" r = requests.get( f"{API}/v1/reference/districts", auth=(CLIENT_ID, CLIENT_SECRET), ) print(r.status_code, r.json()) -
#Create a location
A location is a place with boxes in it. Only
nameis required; the answer'smissinglist tells you what customers still cannot see. At least five amenities (features) are needed for the location to be found.Create a locationcurl -X POST "$API/v1/locations" \ -u "$CLIENT_ID:$CLIENT_SECRET" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: ebfa60c9-5887-4526-9615-2d2ebdd9a0ed" \ -d '{ "name": "Imanta noliktava", "external_id": "WH-IMANTA", "description": "Sausa, apsildāma noliktava ar 24/7 piekļuvi", "address": "Kurzemes prospekts 1, Rīga", "district": "riga-imanta", "latitude": 56.9496, "longitude": 24.0536, "features": [ "24-7-piekluve", "apkure", "video-noverosana", "viedatslega", "autostavvieta" ] }'const API = "https://api.boxlatvia.lv"; const auth = "Basic " + btoa(`${CLIENT_ID}:${CLIENT_SECRET}`); const res = await fetch(`${API}/v1/locations`, { method: "POST", headers: { Authorization: auth, "Content-Type": "application/json", "Idempotency-Key": "ebfa60c9-5887-4526-9615-2d2ebdd9a0ed" }, body: JSON.stringify({ "name": "Imanta noliktava", "external_id": "WH-IMANTA", "description": "Sausa, apsildāma noliktava ar 24/7 piekļuvi", "address": "Kurzemes prospekts 1, Rīga", "district": "riga-imanta", "latitude": 56.9496, "longitude": 24.0536, "features": [ "24-7-piekluve", "apkure", "video-noverosana", "viedatslega", "autostavvieta" ] }), }); console.log(res.status, await res.json());import requests API = "https://api.boxlatvia.lv" r = requests.post( f"{API}/v1/locations", auth=(CLIENT_ID, CLIENT_SECRET), headers={"Idempotency-Key": "ebfa60c9-5887-4526-9615-2d2ebdd9a0ed"}, json={ "name": "Imanta noliktava", "external_id": "WH-IMANTA", "description": "Sausa, apsildāma noliktava ar 24/7 piekļuvi", "address": "Kurzemes prospekts 1, Rīga", "district": "riga-imanta", "latitude": 56.9496, "longitude": 24.0536, "features": [ "24-7-piekluve", "apkure", "video-noverosana", "viedatslega", "autostavvieta", ], }, ) print(r.status_code, r.json())201 CreatedETag: W/"a15c541949287f3563009a45"Location: https://api.boxlatvia.lv/v1/locations/9d80d5f4-d17a-4f3e-99f6-4ab43b132bc3{ "id": "9d80d5f4-d17a-4f3e-99f6-4ab43b132bc3", "external_id": "WH-IMANTA", "name": "Imanta noliktava", "description": "Sausa, apsildāma noliktava ar 24/7 piekļuvi", "address": "Kurzemes prospekts 1, Rīga", "district": "riga-imanta", "district_name": "Rīga - Imanta", "latitude": 56.9496, "longitude": 24.0536, "box_count": 0, "features": [ "24-7-piekluve", "apkure", "autostavvieta", "video-noverosana", "viedatslega" ], "missing": [], "created_at": "2026-11-07T09:30:12.418Z", "updated_at": "2026-11-07T09:30:12.418Z" } -
#Create a box
Point the box at its location by BoxLatvia's id or by your own id for it (
location_external_id). New boxes start as drafts.Create a boxcurl -X POST "$API/v1/boxes" \ -u "$CLIENT_ID:$CLIENT_SECRET" \ -H "Content-Type: application/json" \ -d '{ "name": "Box 3 m²", "description": "Sausa un apsildāma telpa pirmajā stāvā", "location_external_id": "WH-IMANTA", "external_id": "SKU-3M", "price": 29.9, "price_unit": "menesi", "price_period_3": 79, "price_period_12": 290, "size": 3, "size_length": 2, "size_width": 1.5, "size_height": 2.4, "door_width": 0.9, "door_height": 2, "total_units": 10, "available_units": 10, "max_advance_days": 60, "features": [ "apkure", "viedatslega" ] }'const API = "https://api.boxlatvia.lv"; const auth = "Basic " + btoa(`${CLIENT_ID}:${CLIENT_SECRET}`); const res = await fetch(`${API}/v1/boxes`, { method: "POST", headers: { Authorization: auth, "Content-Type": "application/json" }, body: JSON.stringify({ "name": "Box 3 m²", "description": "Sausa un apsildāma telpa pirmajā stāvā", "location_external_id": "WH-IMANTA", "external_id": "SKU-3M", "price": 29.9, "price_unit": "menesi", "price_period_3": 79, "price_period_12": 290, "size": 3, "size_length": 2, "size_width": 1.5, "size_height": 2.4, "door_width": 0.9, "door_height": 2, "total_units": 10, "available_units": 10, "max_advance_days": 60, "features": [ "apkure", "viedatslega" ] }), }); console.log(res.status, await res.json());import requests API = "https://api.boxlatvia.lv" r = requests.post( f"{API}/v1/boxes", auth=(CLIENT_ID, CLIENT_SECRET), json={ "name": "Box 3 m²", "description": "Sausa un apsildāma telpa pirmajā stāvā", "location_external_id": "WH-IMANTA", "external_id": "SKU-3M", "price": 29.9, "price_unit": "menesi", "price_period_3": 79, "price_period_12": 290, "size": 3, "size_length": 2, "size_width": 1.5, "size_height": 2.4, "door_width": 0.9, "door_height": 2, "total_units": 10, "available_units": 10, "max_advance_days": 60, "features": [ "apkure", "viedatslega", ], }, ) print(r.status_code, r.json())201 CreatedETag: W/"2daf00d492dd4f4cd82f2113"Location: https://api.boxlatvia.lv/v1/boxes/c4883b4a-4e38-47bf-8a69-ef025917e022{ "id": "c4883b4a-4e38-47bf-8a69-ef025917e022", "external_id": "SKU-3M", "location_id": "9d80d5f4-d17a-4f3e-99f6-4ab43b132bc3", "name": "Box 3 m²", "description": "Sausa un apsildāma telpa pirmajā stāvā", "status": "DRAFT", "price": 29.9, "promotional_price": null, "price_period_1": null, "price_period_3": 79, "price_period_6": null, "price_period_12": 290, "price_unit": "menesi", "size": 3, "size_length": 2, "size_width": 1.5, "size_height": 2.4, "door_width": 0.9, "door_height": 2, "total_units": 10, "available_units": 10, "max_advance_days": 60, "features": [ "apkure", "viedatslega" ], "missing": [], "created_at": "2026-11-07T09:30:12.418Z", "updated_at": "2026-11-07T09:30:12.418Z" } -
#Add pictures
Upload JPEG, PNG, WebP or GIF files as
multipart/form-data, up to 5 per request.Upload two picturescurl -X POST "$API/v1/boxes/c4883b4a-4e38-47bf-8a69-ef025917e022/images" \ -u "$CLIENT_ID:$CLIENT_SECRET" \ -F "file=@front.jpg" \ -F "file=@inside.png"const API = "https://api.boxlatvia.lv"; const auth = "Basic " + btoa(`${CLIENT_ID}:${CLIENT_SECRET}`); const form = new FormData(); form.append("file", frontFile); // a File or Blob form.append("file", insideFile); // a File or Blob const res = await fetch(`${API}/v1/boxes/c4883b4a-4e38-47bf-8a69-ef025917e022/images`, { method: "POST", headers: { Authorization: auth }, body: form, }); console.log(res.status, await res.json());import requests API = "https://api.boxlatvia.lv" r = requests.post( f"{API}/v1/boxes/c4883b4a-4e38-47bf-8a69-ef025917e022/images", auth=(CLIENT_ID, CLIENT_SECRET), files=[("file", open("front.jpg", "rb")), ("file", open("inside.png", "rb"))], ) print(r.status_code, r.json())201 Created{ "data": [ { "id": "eb28418e-6710-4ba2-aee5-f15b53c02d8f", "url": "https://gnfvochksxcodgoqdgxx.supabase.co/storage/v1/object/public/box-images/sup-1/c4883b4a-4e38-47bf-8a69-ef025917e022/e8219951-043a-45bd-a9ee-0c75a6819510.png", "created_at": "2026-11-07T09:30:12.418Z" }, { "id": "ae6e8d2e-da66-4026-bb04-9418e52a7c43", "url": "https://gnfvochksxcodgoqdgxx.supabase.co/storage/v1/object/public/box-images/sup-1/c4883b4a-4e38-47bf-8a69-ef025917e022/4f380fb3-d246-4c5b-b6d0-37d7fa8b5523.png", "created_at": "2026-11-07T09:30:12.418Z" } ] } -
#Submit for review
When the box has a description, a price and price unit, a size and at least one amenity, ask BoxLatvia to publish it. The API can only ask: BoxLatvia staff review and publish. You can withdraw the box at any time.
Submit a boxcurl -X POST "$API/v1/boxes/c4883b4a-4e38-47bf-8a69-ef025917e022/submit" \ -u "$CLIENT_ID:$CLIENT_SECRET"const API = "https://api.boxlatvia.lv"; const auth = "Basic " + btoa(`${CLIENT_ID}:${CLIENT_SECRET}`); const res = await fetch(`${API}/v1/boxes/c4883b4a-4e38-47bf-8a69-ef025917e022/submit`, { method: "POST", headers: { Authorization: auth }, }); console.log(res.status, await res.json());import requests API = "https://api.boxlatvia.lv" r = requests.post( f"{API}/v1/boxes/c4883b4a-4e38-47bf-8a69-ef025917e022/submit", auth=(CLIENT_ID, CLIENT_SECRET), ) print(r.status_code, r.json())200 OKETag: W/"052468fbc2a710d35f026e30"{ "id": "c4883b4a-4e38-47bf-8a69-ef025917e022", "external_id": "SKU-3M", "location_id": "9d80d5f4-d17a-4f3e-99f6-4ab43b132bc3", "name": "Box 3 m²", "description": "Sausa un apsildāma telpa pirmajā stāvā", "status": "REVIEW", "price": 31.5, "promotional_price": null, "price_period_1": null, "price_period_3": 79, "price_period_6": null, "price_period_12": 290, "price_unit": "menesi", "size": 3, "size_length": 2, "size_width": 1.5, "size_height": 2.4, "door_width": 0.9, "door_height": 2, "total_units": 10, "available_units": 6, "max_advance_days": 60, "features": [ "apkure", "viedatslega" ], "missing": [], "created_at": "2026-11-07T09:30:12.418Z", "updated_at": "2026-11-07T14:05:41.092Z" }
#What next
- Keep prices and stock current with one call per box using your own id.
- Read Core concepts: conditional updates, safe retries, dry runs.
- Read Limits & best practices before you automate.