Basileus Public API · v1
Přepravní REST API pro balíky, palety a výdejní místa
Veřejné přepravní API systému IPS. Vytvářejte zásilky, tiskněte štítky (PDF i ZPL), sledujte stav, stornujte, registrujte webhooky a posílejte nebezpečné zboží (ADR) — vše přes jeden konzistentní kontrakt.
01Úvod#
Tato dokumentace popisuje veřejné přepravní API systému IPS.
Kontrakt je kompatibilní s dřívějším Basileus ERP API (které jste testovali na basileus.docs.apiary.io) — stejné endpointy, pole, tělo, stavové kódy, autentizace X-API-KEY i chování štítků / storna / trackingu. Vůči vaší integraci se mění pouze base URL a API klíč; logika běží nově v IPS.
Balíky, palety, výdejní místa, štítky (PDF i ZPL), tracking, storno, dry-run validace, webhooky stavů, veřejná tracking URL, ADR — hotovo.
02Base URL a prostředí#
| Prostředí | Base URL |
|---|---|
| Produkce | https://ips.basileus.cz/public-api/v1 |
| Test (sandbox) | stejný host, klíč s příznakem sandbox (zásilky se nezařadí do ostrého provozu) |
Všechny cesty níže jsou relativní k base URL.
curl https://ips.basileus.cz/public-api/v1/places \
-H "X-API-KEY: <váš_api_klíč>"
03Autentizace#
Každý požadavek musí obsahovat hlavičku:
X-API-KEY: <váš_api_klíč>
Klíč si vygenerujete sami po přihlášení do partnerského portálu eshop.basileus.cz → sekce API (klíč se zobrazí jen jednou, uložte si ho). Klíč lze omezit na konkrétní zdrojové IP (doporučeno).
Chybný / chybějící klíč → 401. Nedostatečné oprávnění nebo nepovolená IP → 403.
04Formát odpovědí#
Každá odpověď API má jednotný obal. Úspěšná odpověď obsahuje ok: true a objekt data, chybová ok: false a objekt error.
ok— boolean, zda požadavek uspěl.data— užitečná data odpovědi (jen u úspěchu).error—code,messagea případnědetails(jen u chyby).timestamp— čas zpracování (ISO 8601, UTC).
Příklady
{ "ok": true, "data": { }, "timestamp": "2026-06-29T10:00:00.000Z" }
{ "ok": false, "error": { "code": "VALIDATION_ERROR", "message": "Popis chyby", "timestamp": "..." } }
05HTTP status kódy#
| HTTP | Význam |
|---|---|
| 200 | OK (tracking, storno, idempotentní opakování) |
| 201 | Zásilka vytvořena |
| 400 | Neplatné JSON tělo |
| 401 | Chybí / neplatný klíč |
| 403 | Bez oprávnění / IP není povolena |
| 404 | Zásilka nenalezena |
| 409 | Konflikt (např. storno už doručené zásilky) |
| 422 | Chyba validace (error.details.errors) |
| 429 | Překročen limit požadavků |
| 500 | Interní chyba (error.details.error_id pro reklamaci) |
06Idempotence#
U POST posílejte buď stabilní external_id v těle, nebo hlavičku Idempotency-Key: <uuid>.
- Stejné
external_id→ vrátí původní zásilku (HTTP200,data.idempotent: true), žádný duplikát. - Stejný
Idempotency-Keys jiným tělem →409.
Idempotency-Key: 7f1c9b2e-3a4d-4f5e-8a9b-0c1d2e3f4a5b
07Rate limit#
Rate limit je nastaven individuálně podle vašeho objemu (pro agregátor řádově tisíce req/min). Aktuální hodnotu hlásí hlavičky X-RateLimit-Limit / X-RateLimit-Remaining; při překročení 429 + Retry-After (sekundy do dalšího pokusu).
Pro snížení počtu dotazů na stav doporučujeme webhooky místo pollingu.
X-RateLimit-Limit: 6000
X-RateLimit-Remaining: 5993
Retry-After: 12
08Limity zásilek#
Validace probíhá při vytvoření i při dry-run. Co projde check, projde i create.
| Co | Doručení na adresu (HD) | Výdejní box (BOX) | Paleta |
|---|---|---|---|
| Max váha | 31,5 kg | 20 kg | dle dohody |
| Max rozměr | jedna strana ≤ 180 cm | kus se vejde do 50 × 40 × 30 cm | — |
| Dobírka (COD) | ≤ 150 000 Kč | ≤ 150 000 Kč | ≤ 250 000 Kč |
| Připojištění | ≤ 1 000 000 Kč | ≤ 1 000 000 Kč | ≤ 1 000 000 Kč |
| Počet kusů | 1–100 | 1 | počet palet 1–33 |
Velikostní kategorie (S/M/L/XL) se u balíku dopočítá automaticky z váhy a slouží jen pro interní přehled — při importu / přes API stačí poslat váhu, kategorii ani size_type posílat nemusíte:
| Váha | Kategorie |
|---|---|
| do 5 kg | S |
| do 10 kg | M |
| do 15 kg | L |
| do 31,5 kg | XL |
PSČ = 5 číslic (mezery se ignorují). Doručujeme i odesíláme v rámci ČR (CZ → CZ).
09Validační tabulka polí#
Min/max a pravidla pro jednotlivá pole (porušení → 422 VALIDATION_ERROR, seznam v error.details.errors):
| Field | Type | Required | Min | Max | Validation |
|---|---|---|---|---|---|
| sender_name | string | ● | 2 | 100 | název / jméno odesílatele |
| recipient_name | string | ● | 2 | 100 | název / jméno příjemce (u palety receiver_company) |
| sender_street / recipient_street | string | u HD (u VM/BOX adresu dá výdejna) | 2 | 120 | ulice (+ *_h_number = č.p.) |
| sender_city / recipient_city | string | u HD | 1 | 80 | město |
| sender_psc / recipient_psc | string | u HD | 5 | 5 | přesně 5 číslic ^\d{5}$ (mezery se ignorují); paleta: *_zip |
| sender_phone / recipient_phone | string | odesílatel; u BOXU i příjemce | — | — | + volitelně, 9–15 číslic; povolené mezery ( ) / - |
| *_country | string | – (def. CZ) | 2 | 2 | jen CZ (CZ → CZ) |
| note | string | – | — | 500 | volná poznámka |
| external_id | string | doporučeno | — | 80 | vaše ID objednávky (idempotence) |
| reference | string | – | — | 64 | volná reference (paleta: customer_reference) |
| cod | number | – | 0 | 150 000 (balík) / 250 000 (paleta) | dobírka v Kč |
| insurance | number | – | 0 | 1 000 000 | připojištění v Kč (paleta: extra_insurance_value) |
| packs[].weight | number | ● > 0 | > 0 | 31,5 (balík) / 20 (BOX) | kg |
| packs[].x / y / z | number | – | 1 | 180 (HD/VM); BOX: kus do 50×40×30 cm | cm |
| place_id | string | u VM/BOX | — | — | musí existovat a být aktivní (GET /places) |
| tracking_number | string | — (read-only) | — | — | generuje IPS, nezadáváte — vrací se v odpovědi create |
Velikostní kategorie (size_category S/M/L/XL) se nezadává — dopočítá se z váhy (viz Limity).
10Vytvoření zásilky#
Vytvoří novou zásilku. Tělo je ploché pole.
| Pole | Typ | Povinné | Pozn. |
|---|---|---|---|
| type | enum | ● | VM (výdejní místo) / BOX (výdejní box) / HD (doručení na adresu) |
| entry_type | enum | – | alias k type |
| place_id | string | u VM/BOX | ID výdejního místa (viz GET /places); musí existovat a být aktivní |
| size_type | 1/2/3 | – | nepovinné, kategorie se dopočítá z váhy |
| external_id | string | doporučeno | vaše ID objednávky (idempotence) |
| sender_name … sender_email | string | ● | sender_name/country/psc/city/street/h_number/phone povinné, email volitelné |
| recipient_name … recipient_email | string | viz níže | u HD povinná adresa; u VM/BOX stačí recipient_name + recipient_phone (adresu doplní výdejní místo) |
| currency | string | – | výchozí czk |
| cod | number | – | dobírka (0 = bez); limity viz §8 |
| insurance | number | – | připojištění |
| note | string | – | poznámka |
| packs | array | ● | kusy: { weight, x, y, z }; weight (kg) povinná, rozměry (cm) volitelné |
| adr | object | – | nebezpečné zboží (viz ADR) |
| files | array | – | přílohy v Base64 (viz Přílohy) |
Stačí place_id + jméno a telefon příjemce. Adresu doručení převezmeme z katalogu výdejen. Telefon je u boxu nutný (SMS s kódem). U boxu platí limit kusu 50 × 40 × 30 cm a 20 kg.
Request / Response
{
"type": "BOX",
"place_id": "P12345",
"external_id": "OBJ-2026-0001",
"sender_name": "Sklad s.r.o.", "sender_country": "CZ", "sender_psc": "13000",
"sender_city": "Praha", "sender_street": "Jiřího z Poděbrad", "sender_h_number": "123",
"sender_phone": "+420777111222",
"recipient_name": "Jan Novák", "recipient_phone": "+420777123456",
"recipient_email": "jan@example.cz",
"currency": "czk", "cod": 1290,
"packs": [ { "weight": 2.5, "x": 30, "y": 20, "z": 15 } ]
}
{
"ok": true,
"data": {
"package_id": "8f3c…",
"tracking_number": "IPS-…",
"state": 0,
"type": "BOX",
"price": null,
"price_currency": "CZK",
"external_id": "OBJ-2026-0001",
"labels_url": "https://ips.basileus.cz/public-api/v1/shipments/IPS-…/label",
"idempotent": false
},
"timestamp": "..."
}
curl -X POST https://ips.basileus.cz/public-api/v1/shipments \
-H "X-API-KEY: <váš_api_klíč>" \
-H "Content-Type: application/json" \
-d @shipment.json
10.2Validace bez vytvoření (dry-run)#
Stejné tělo jako POST /shipments, ale nic se nevytvoří — jen se ověří. Validuje přesně jako create (sdílená logika), takže co projde checkem, projde i createm.
Response
{ "ok": true, "data": { "valid": true, "errors": [] }, "timestamp": "..." }
{ "ok": true, "data": { "valid": false, "errors": [
{ "field": "weight_kg", "code": "range", "message": "Do boxu max 20 kg." }
] }, "timestamp": "..." }
10.3Stav a detail zásilky#
Vrátí aktuální stav a detail zásilky.
payed_cod: "0" = dobírka nezaplacena (vybere kurýr), "1" = zaplacena předem.
Stavové kódy state
| state | Význam |
|---|---|
| 0 | Přijetí dat o zásilce |
| 2 | Vyzvednuto / přijato do přepravy |
| 3 | Přijato na příjmovém depu |
| 4 | V přepravě / expediční depo |
| 5 | Předáno na doručení |
| 6 | Připraveno k vyzvednutí (výdejní místo) |
| 7 | Doručeno |
| 8 | Nedoručeno / kontroling |
| 9 | Vrácení odesílateli |
| 11 | Storno |
Response
{
"ok": true,
"data": {
"tracking_number": "IPS-…",
"external_id": "OBJ-2026-0001",
"state": 5,
"type": "BOX",
"cod": 1290,
"payed_cod": "0",
"sender": { "name": "Sklad s.r.o." },
"recipient": { "name": "Jan Novák" },
"items": [ { "weight": 2.5, "x": 30, "y": 20, "z": 15 } ]
},
"timestamp": "..."
}
10.4Storno zásilky#
Stornuje zásilku.
Doručenou zásilku nelze stornovat → 409.
Response
{ "ok": true, "data": { "tracking_number": "IPS-…", "state": 11, "message": "Zásilka byla zrušena." }, "timestamp": "..." }
10.5Štítek zásilky#
| Parametr | Výsledek |
|---|---|
| (bez parametru) nebo ?format=pdf | PDF (A6, logo, adresa, dobírka, Code128) |
| ?format=zpl | ZPL II (Zebra, termální tiskárny), text/plain |
Stahujte serverově s hlavičkou X-API-KEY. Stejná adresa je v labels_url z odpovědi vytvoření. Endpoint je idempotentní (re-print kdykoli vrátí aktuální štítek).
Příklad
curl https://ips.basileus.cz/public-api/v1/shipments/IPS-…/label?format=pdf \
-H "X-API-KEY: <váš_api_klíč>" \
-o stitek.pdf
curl https://ips.basileus.cz/public-api/v1/shipments/IPS-…/label?format=zpl \
-H "X-API-KEY: <váš_api_klíč>"
11Nebezpečné zboží (ADR)#
Zásilka může obsahovat nebezpečné zboží — přidejte do těla POST /shipments blok adr:
Pole adr.* | Povinné | Pozn. |
|---|---|---|
| un_number | ● | musí být z číselníku (GET /adr) |
| class | – | doplní se z číselníku, lze přepsat |
| quantity | ● | kladné množství (jinak se vezme hmotnost kusů) |
| unit | – | L / KG (doplní se z číselníku) |
| packing_group | – | I / II / III |
Při vyplněném adr jede zásilka v ADR režimu (automaticky se objedná svoz). Název látky, jednotka a typický obal se doplní z číselníku podle un_number. (U paletových zásilek se nebezpečné zboží značí přes goods_character: "adr".)
Číselník UN kódů#
Vrátí povolené UN kódy (třída, oficiální název, jednotka, typický obal). Filtry: ?class=3, ?q=benzín.
Request / Response
{
"type": "HD",
"external_id": "OBJ-ADR-1",
"sender_name": "...", "sender_psc": "13000", "sender_city": "Praha",
"sender_street": "...", "sender_h_number": "1", "sender_country": "CZ", "sender_phone": "+420…",
"recipient_name": "...", "recipient_psc": "60200", "recipient_city": "Brno",
"recipient_street": "...", "recipient_h_number": "2", "recipient_country": "CZ", "recipient_phone": "+420…",
"packs": [ { "weight": 20, "x": 60, "y": 40, "z": 40 } ],
"adr": { "un_number": "1170", "class": "3", "quantity": 20, "unit": "L", "packing_group": "II" }
}
{ "ok": true, "data": { "count": 34, "codes": [
{ "un_number": "1203", "class": "3", "name": "BENZÍN", "unit": "L", "uom_note": "čistý objem", "packaging": "3H1 (Plast. kanystr)" }
] }, "timestamp": "..." }
12Přílohy (files / Base64)#
K zásilce lze přiložit dokumenty (např. ADR doklad, faktura) jako Base64 v poli files (alias attachments) v těle POST /shipments.
| Vlastnost | Hodnota |
|---|---|
| Podporované formáty | PDF (application/pdf), JPG/JPEG (image/jpeg), PNG (image/png) |
| Max. velikost 1 souboru | 5 MB |
| Max. celkem | 15 MB |
| Max. počet souborů | 5 |
Struktura jedné položky: name (název s příponou — z ní se odvodí formát) a data (Base64 obsah; akceptujeme i prefix data:…;base64,). Volitelně lze poslat content_type.
Nepovolený formát / překročení limitů → 422 VALIDATION_ERROR (error.details.errors).
Request
{
"type": "HD",
"external_id": "OBJ-FILES-1",
"sender_name": "Sklad s.r.o.", "sender_country": "CZ", "sender_psc": "13000",
"sender_city": "Praha", "sender_street": "Jiřího z Poděbrad", "sender_h_number": "123", "sender_phone": "+420777111222",
"recipient_name": "Jan Novák", "recipient_country": "CZ", "recipient_psc": "11000",
"recipient_city": "Praha 1", "recipient_street": "Václavské nám.", "recipient_h_number": "1", "recipient_phone": "+420777123456",
"packs": [ { "weight": 2.0, "x": 30, "y": 20, "z": 15 } ],
"files": [
{ "name": "adr-document.pdf", "data": "JVBERi0xLjQKJeLjz9MKMy..." },
{ "name": "faktura.pdf", "data": "JVBERi0xLjQKJ..." }
]
}
13Výdejní místa#
Parametry: q, city, postalCode, country, active (1/0), type (1 = VM výdejní místo, 2 = box), limit (≤1000, def. 200), offset.
Vrací jen místa aktivní na straně IPS (provozovatel může jednotlivá místa ručně vypnout — pak je v create nelze použít).
Doručování do výdejních míst (type 1, VM) je připravené, ale aktuálně může být dočasně vypnuté — proto vám v některých městech vrací katalog jen boxy (type 2). Doručujeme tedy na adresu (HD) a do boxu (BOX); jakmile se VM zapnou, fungují beze změny integrace.
Response
{
"ok": true,
"data": {
"count": 1,
"places": [
{
"type": 2, "active": 1, "name": "Box Praha 1", "place_id": "P12345",
"partner": "alza", "address": "Václavské nám. 1", "city": "Praha",
"postalCode": "11000", "country": "CZ",
"gps": { "lat": 50.08, "lng": 14.42 }, "operatingHours": null
}
]
},
"timestamp": "..."
}
14Paletové zásilky#
Vytvoření paletové zásilky. Plochá pole dle ERP.
Skupiny sender_* (fakturační), pickup_* (pickup_same_as_sender), receiver_*, delivery_* (delivery_same_as_receiver); goods_character, cod, extra_insurance_value, customer_reference, external_id; packs[].
goods_character (enum)
neam · potraviny_ambient · cham · adr · fresh · frozen
packs[].package_type (enum)
CL · EP · CP · BL · JEDNOCESTNA · DS · ROLE · GITTERBOX · BIGBAG — plus weight, x, y, z, protective_wrap.
Odpověď 201 — pole v data
package_id, tracking_number, load_type:"pallet", state, sender_*, recipient_*, number_of_packages, cod, external_id, price, labels_url.
Když pickup_same_as_sender / delivery_same_as_receiver = true (nebo je vynecháte), převezme se nakládka z odesílatele a doručení z příjemce — pak pickup_* / delivery_* neposílejte. Dobírka palety až 250 000 Kč.
Request — oddělené adresy
{
"external_id": "OBJ-PAL-SEP-0001",
"sender_company": "Fakturační s.r.o.", "sender_street": "Účetní 1", "sender_city": "Praha",
"sender_zip": "11000", "sender_country": "CZ", "sender_phone": "+420777000001",
"pickup_same_as_sender": false,
"pickup_company": "Sklad Plzeň", "pickup_street": "Skladová 99", "pickup_city": "Plzeň",
"pickup_zip": "30100", "pickup_country": "CZ", "pickup_phone": "+420777000002",
"receiver_company": "Příjemce a.s.", "receiver_street": "Hlavní 5", "receiver_city": "Brno",
"receiver_zip": "60200", "receiver_country": "CZ", "receiver_phone": "+420777000003",
"delivery_same_as_receiver": false,
"delivery_company": "Pobočka Ostrava", "delivery_street": "Nádražní 10", "delivery_city": "Ostrava",
"delivery_zip": "70200", "delivery_country": "CZ", "delivery_phone": "+420777000004",
"goods_character": "neam",
"cod": 12000, "extra_insurance_value": 50000, "customer_reference": "REF-2026-1",
"packs": [
{ "package_type": "EP", "weight": 240, "x": 120, "y": 80, "z": 100, "protective_wrap": "stretch_foil" }
]
}
14.2Stav / storno / štítek palety#
Pro paletu fungují obě varianty cest — buď přes zásilky, nebo přes /palets:
| Akce | Cesta |
|---|---|
| Stav | GET /palets/{trackingNumber} (nebo GET /shipments/{trackingNumber}) |
| Storno | DELETE /palets/{trackingNumber} (nebo DELETE /shipments/{trackingNumber}) |
| Štítek | GET /palets/{trackingNumber}/label (?format=zpl též) |
Dobírka palety až 250 000 Kč (viz Limity).
15Ochranné balení — protective_wrap#
Volitelné pole na úrovni kusu (packs[].protective_wrap), string / enum. Default = neuvedeno (bez ochranného balení, none). Povolené hodnoty (reálné backend hodnoty):
| Hodnota | Význam |
|---|---|
| none | bez ochranného balení |
| bubble_wrap | bublinková fólie |
| stretch_foil | stretch fólie |
| cardboard | kartonová ochrana / proložky |
| wooden_crate | dřevěná bedna / klec |
| edge_protectors | ochranné rohy / hranové chrániče |
Jiná hodnota → 422 VALIDATION_ERROR. Stejný číselník platí i pro goods_lines[].protective_wrap u balíkových zásilek.
16Webhooky (push změn stavu)#
Místo pravidelného dotazování na stav si zaregistrujte webhook — IPS vám sám pošle POST na vaši URL při změně stavu zásilky, kterou jste vytvořili.
Registrace
Odpověď 201 vrací mj. secret (zobrazí se jen jednou — uložte si ho pro ověření podpisu). Když secret nepošlete, vygeneruje se.
Správa odběrů
- GET
/webhooks— seznam vašich odběrů +available_events. - PATCH
/webhooks/{id}—{ active?, events?, description?, rotate_secret? }. - DELETE
/webhooks/{id}— zrušení odběru.
Dostupné události
shipment.created · shipment.status_changed · shipment.out_for_delivery · shipment.delivered · shipment.failed · shipment.cancelled · shipment.eta_updated
Registrace
{ "url": "https://vase-domena.cz/ips-webhook", "events": ["shipment.status_changed"], "secret": "volitelný_vlastní_secret" }
Tvar callbacku#
IPS pošle POST na vaši URL s tělem (viz vpravo). Hlavičky: X-IPS-Event, X-IPS-Delivery, X-IPS-Signature = HMAC-SHA256(tělo, secret).
Ověřte podpis a vraťte 2xx. Při neúspěchu IPS opakuje s exponenciálním odstupem (po vyčerpání pokusů → dead-letter, lze přehrát).
Callback
{
"event": "shipment.status_changed",
"delivery_id": "…",
"data": {
"tracking_number": "IPS-…",
"state": 7,
"status": "delivered",
"status_label": "Doručeno",
"carrier_code": "DELIVERED",
"at": "2026-06-29T10:00:00.000Z"
}
}
X-IPS-Event: shipment.status_changed
X-IPS-Delivery: …
X-IPS-Signature: HMAC-SHA256(tělo, secret)
17Veřejné sledování pro zákazníka#
Pro koncového příjemce existuje veřejná (bez přihlášení) tracking stránka:
https://ips.basileus.cz/sledovat/{tracking_number}
https://ips.basileus.cz/sledovat?id={tracking_number}
(Po nasměrování domény funguje i tvar https://tracking.basileus.cz/?id={tracking_number}.)
Tahle stránka je určená lidem (zobrazuje stav + mapu). Strojové dotazy na stav dělejte přes GET /shipments/{trackingNumber} s X-API-KEY.
18Odlišnosti od starého ERP#
Drobné, vědomé odchylky implementace IPS (přečtěte si!):
package_idje textový identifikátor (ne číslo). Pro všechna další volání (stav/storno/štítek) používejtetracking_number— to platilo i dřív.priceve vytvoření vracímenull— cena se počítá dle ceníku per partner až ve fakturaci, ne při založení zásilky. (U palet sepricedopočítá, je-li ceník.)- Velikostní kategorie se dopočítá z váhy — při importu stačí poslat váhu (viz Limity).
- Číselné stavy
stateviz tabulka v §10.3 (mapováno 1:1 na interní stavy IPS). - Celní pole se nepoužívají —
custom_code(PackageItem) anicustoms_shipment(paleta) nejsou potřeba, protože doručujeme jen v rámci ČR (CZ → CZ, bez cla). Pokud je pošlete, ignorují se.
Vše ostatní (názvy polí, struktura těla i odpovědí, autentizace, štítky, storno) je shodné. Pokud narazíte na jakýkoli rozdíl oproti tomu, co jste testovali, dejte vědět — doladíme.
19Bezpečnost a izolace dat#
- Každá zásilka je svázaná s vaším klíčem. Přes API vidíte a spravujete výhradně vlastní zásilky — tracking ani storno cizí zásilky není možné, ani při znalosti cizího tracking čísla.
- Doporučujeme klíč omezit na vaše zdrojové IP.
- Každý požadavek má
request_id(v hlavičceX-Request-Id) pro rychlou reklamaci.
20Doporučený postup nasazení#
- Vyžádejte si sandbox klíč (nebo si ho vygenerujte na eshop.basileus.cz).
- Pusťte svou stávající integraci proti base URL IPS se sandbox klíčem, ověřte odpovědi (
check→ vytvoření → štítek PDF/ZPL → tracking → storno → places → palets → webhook callback). - Po potvrzení přepněte na produkční klíč. Žádné přepisování integrace.
21Kontakt#
Napište nám — rádi vám pomůžeme s napojením na Basileus Public API.