Překlad pro pohodlí — anglická verze je závazná.
Stav: Draft v0.1 · Otevřená, na dodavatelích nezávislá specifikace · Licence: otevřená (viz §10)
OTEP je otevřený, na dodavatelích nezávislý protokol pro životní cyklus libovolného sledovatelného předmětu. Definuje jeden model událostí a jeden slovník stavů, takže sledovací události z libovolného zdroje — doručení vlastní flotilou, kurýři třetích stran, přepravní štítky a další — lze vyměňovat, chápat a promítat do mezinárodních standardů bez nutnosti znovu integrovat každou stranu zvlášť.
Tento dokument je specifikace: struktura, pole, tabulky stavů, stavový automat, mapování na externí standardy a pravidla shody pro vytvoření kompatibilní implementace. Je nezávislá na implementaci — popisuje protokol, nikoli vnitřní mechanismy konkrétního dodavatele. Klíčová slova RFC-2119 (MUST / SHOULD / MAY) jsou normativní.
Sledování je roztříštěné: každý dopravce pojmenovává pole a stavové kódy odlišně, každý doručovací kanál hlásí ve svém vlastním tvaru a propojení s globálními standardy znamená opakovanou integraci. OTEP dává producentům a konzumentům jeden společný jazyk: producent vydá události OTEP jednou a každý konzument OTEP jim porozumí a dokáže je promítnout do standardu, který potřebuje.
Časová osa je obálka nesoucí sledovaný předmět a uspořádaný seznam událostí.
{
"otep_version": "0.1",
"profile": "parcel", // domain profile (§8)
"subject": {
"tracking_number": "SR123...", // ≥1 identifier required
"order_id": 12345, // optional
"package_id": 67890, // optional
"external_tracking_number": "1Z...",// optional
"gs1_sscc": "00...", // optional — enables EPCIS epcList
"piece_id": "..." // optional — enables ONE Record linkage
},
"current_status": "delivered", // projection of the latest event
"delivered": true,
"events": [ /* OTEP events, §4 */ ]
}
{
// WHAT — carried once at the timeline level (subject above)
// WHEN
"occurred_at": "2026-06-10T09:30:00-04:00", // event instant, ISO-8601 with offset
"recorded_at": "2026-06-10T09:45:23-04:00", // ingestion instant (optional)
"time_type": "actual", // actual | estimated | scheduled
// WHERE
"location": {
"name": "Toronto Hub",
"code": "YYZ-2",
"gln": "0614141000005", // GS1 GLN → EPCIS SGLN
"lat": 43.6777, "lng": -79.6248,
"country": "CA" // ISO 3166-1 alpha-2
},
// WHY / WHAT HAPPENED
"status_code": "out_for_delivery", // an OTEP status code (§4)
"phase": "out_for_delivery", // derived from status_code
"incident_reason": null, // an OTEP incident reason (§4) when exception
// WHO
"actor": { "type": "driver", "name": "Jane D.", "phone": "+1..." },
// PROVENANCE
"source": {
"type": "self_delivery", // self_delivery | third_party_delivery | carrier_label
"provider_id": null,
"carrier_code": null,
"external_event_code": null, // your raw status code (preserve it)
"raw": { /* original payload */ }
},
// PROOF
"pod": {
"photos": [ { "url": "...", "content_base64": null } ],
"signature": [ { "url": "...", "content_base64": null } ],
"recipient": "John Smith"
}
}
Každé pole kromě subject, occurred_at, status_code a source je volitelné —
částečné zdroje vyplní, co mají. Skeny v uzlu/hubu nastaví location na skenující zařízení.
Vysokofrekvenční GPS telemetrie NENÍ událostí OTEP; událost je vydána při změně stavu nebo
při skenu v uzlu.
20 kanonických kódů životního cyklu. phase je vždy odvoditelná z kódu.
| code | phase | terminální | POD | význam |
|---|---|---|---|---|
information_submitted |
pre_shipment | informace o objednávce přijaty | ||
booking_confirmed |
pre_shipment | dopravce/rezervace potvrzena | ||
awaiting_pickup |
pre_shipment | připraveno k vyzvednutí | ||
out_for_pickup |
pickup | na cestě k vyzvednutí | ||
picked_up |
pickup | ✓ | vyzvednuto od odesílatele | |
pickup_failed |
exception | pokus o vyzvednutí selhal | ||
pickup_rescheduled |
exception | vyzvednutí bude opakováno | ||
received |
inbound | přijato v zařízení | ||
arrival_scan |
inbound | sken při příjezdu do uzlu | ||
in_transit |
transit | v pohybu | ||
package_outbound |
transit | opustilo zařízení | ||
removed_from_route |
exception | staženo z trasy | ||
route_cancelled |
exception | trasa zrušena | ||
out_for_delivery |
out_for_delivery | ve vozidle | ||
delivered |
delivered | ✓ | ✓ | doručeno příjemci |
delivery_failed |
exception | pokus o doručení selhal | ||
delivery_rescheduled |
exception | bude opakováno / znovu doručeno | ||
return_to_sender |
return | ✓ | vrací se k odesílateli | |
rejected_by_recipient |
return | ✓ | příjemce odmítl | |
cancelled |
return | ✓ | objednávka zrušena |
pre_shipment · preparing · pickup · inbound · in_custody · transit ·
out_for_delivery · delivered · exception · return. (preparing a in_custody
jsou vyhrazeny pro neparcelní profily — §8.)
source.type: self_delivery · third_party_delivery · carrier_label.
time_type: actual · estimated · scheduled (výchozí actual).
Když je událost ve fázi exception, SHOULD nést incident_reason z tohoto
normalizovaného slovníku:
carrier_damaged_parcel, carrier_sorting_error, carrier_address_not_found,
carrier_parcel_lost, carrier_not_enough_time, carrier_vehicle_issue,
carrier_capacity_exceeded, carrier_mechanical_delayretailer_cancelled, retailer_incorrect_data, retailer_not_ready,
retailer_incorrect_parcel, retailer_incorrect_dimensions, retailer_packaging_issueconsignee_refused, consignee_business_closed, consignee_not_available,
consignee_not_home, consignee_cancelled, consignee_verification_failed,
consignee_incorrect_address, consignee_access_restricted, consignee_safe_place_unavailablecustoms_delay, customs_documentation, customs_duties_unpaid,
customs_prohibited, customs_inspectionweather_delay, natural_disaster, force_majeureparcel_being_researched, security_issue, regulatory_hold, unknownFáze postupují vpřed; výjimky je přerušují a vracejí se zpět. Terminální stavy (delivered,
return_to_sender, rejected_by_recipient, cancelled) uzavírají předmět.
pre_shipment → preparing → pickup → inbound → in_custody → transit → out_for_delivery → delivered ✓
└──────────── exception ──────────┘
└──────────── return / cancelled ✓
Pravidla:
occurred_at a MUST tolerovat příchod mimo pořadí.Čtyři dimenze OTEP odpovídají pole po poli hlavním standardům, takže každý je výstupní projekcí události OTEP.
| OTEP | GS1 EPCIS 2.0 | IATA ONE Record | UN/CEFACT |
|---|---|---|---|
occurred_at (+offset) |
eventTime + eventTimeZoneOffset |
eventDate + eventTimeType=Actual |
Event Date/Time |
recorded_at |
recordTime |
recordedAt | — |
| subject (sscc/piece) | epcList (SSCC URN) |
linkedObject → Piece/Shipment |
Consignment |
location (gln/lat/lng) |
readPoint / bizLocation (SGLN) |
recordedAtLocation → Location |
Location |
status_code |
bizStep + disposition |
eventCode |
Transport status code |
actor |
sourceList / extension | Actor / Party | Party |
incident_reason |
disposition / ErrorDeclaration | event remark | Status reason code |
Hodnoty pro jednotlivé kódy (EPCIS CBV bizStep/disposition, ONE Record eventCode, kód UN/CEFACT)
jsou publikovány ve strojově čitelném číselníku. Kromě těchto mezinárodních standardů lze časovou osu
OTEP promítnout také do OpenTelemetry trasování, OGC SensorThings pozorování a
běžných obchodních platforem (AfterShip, Shopify, Amazon, Walmart, BigCommerce, Magento,
WooCommerce, Etsy).
Spolehlivost: Hodnoty EPCIS CBV jsou stabilní standardní URN. Hodnoty kódů ONE Record a UN/CEFACT jsou nejlepší možnou volbou pro poslední míli a před externím použitím by měly být ověřeny vůči oficiálním seznamům kódů. „Doručeno příjemci“ nemá přesný CBV bizStep — používá se nejbližší odpovídající (
receiving+received) nebo rozšiřující URN z uživatelského slovníku.
OTEP je konzumováno přes malé read-only HTTP rozhraní; všechny koncové body jsou veřejné.
| Sloveso | Cesta | Vrací |
|---|---|---|
| GET | /api/v1/otep/trackings/{tracking_number} |
časovou osu pro sledovací číslo |
| GET | /api/v1/otep/trackings/{tracking_number}/events |
pouze události |
| POST | /api/v1/otep/trackings/batch |
mnoho sledovacích čísel v jednom volání |
| POST | /api/v1/otep/validate |
kontrolu shody pro odeslanou časovou osu (§9) |
K dispozici je také GraphQL dotaz vystavující tutéž časovou osu.
Tatáž časová osa je serializována do té reprezentace, kterou si vyžádáte, prostřednictvím
dotazového parametru ?format= nebo profilu Accept:
| Požadavek | Reprezentace |
|---|---|
?format=otep (výchozí) |
nativní časová osa OTEP |
?format=epcis |
GS1 EPCIS 2.0 (JSON-LD ObjectEvents) |
?format=onerecord |
IATA ONE Record (LogisticsEvents) |
?format=uncefact |
UN/CEFACT transport status |
?format=otlp |
OpenTelemetry trasování |
?format=sensorthings |
OGC SensorThings pozorování |
?format=aftership | shopify | amazon | walmart | bigcommerce | magento | woocommerce | etsy |
tvar sledování/plnění dané platformy |
Události, kterým nelze v projekci přiřadit kód, jsou přeskočeny a započítány (nikdy nejsou tiše zahozeny).
OTEP je obecný protokol, nikoli parcelní. Protokolová vrstva (obálka událostí, páteř fází,
stavový automat) je univerzální; konkrétní stavové kódy patří do profilu deklarovaného na
časové ose pomocí profile. Kódy v §4 jsou profil parcel. Další domény —
stěhování, doručování jídla, skladování a další — přidávají vlastní sady kódů pod svým profilem,
s jmenným prostorem otep:<profile>:<code>, přičemž každý se mapuje na tutéž páteř fází. Přidání profilu
je rozšíření, nikoli změna protokolu.
Producent nebo konzument je OTEP-konformní, když každá událost, kterou vydá nebo přijme, splňuje tyto tabulky a pravidla.
| Pole | Typ | Pož. | Omezení |
|---|---|---|---|
otep_version |
string | MUST | semver, např. 0.1 |
profile |
string | MUST | registrovaný profil |
subject |
object | MUST | §9.2 |
current_status |
string|null | SHOULD | stavový kód (§4) |
current_phase |
string|null | SHOULD | MUST se rovnat fázi current_status, pokud jsou přítomny obě |
delivered |
boolean | SHOULD | true právě když current_status = delivered |
events |
array | MUST | objekty událostí (§9.3), seřaditelné podle occurred_at |
subjectAlespoň JEDEN z tracking_number / order_id / package_id MUST být přítomen.
| Pole | Typ | Omezení |
|---|---|---|
tracking_number |
string | neprázdné |
order_id / package_id |
integer|null | |
external_tracking_number |
string|null | |
gs1_sscc |
string|null | 18 číslic |
piece_id |
string|null |
| # | Pole | Typ | Pož. | Omezení |
|---|---|---|---|---|
| 1 | occurred_at |
string | MUST | ISO-8601 s offsetem |
| 2 | recorded_at |
string|null | SHOULD | ISO-8601 |
| 3 | time_type |
string | MAY (výchozí actual) |
actual | estimated | scheduled |
| 4 | status_code |
string|null | MUST¹ | kód v §4.1 |
| 5 | phase |
string|null | SHOULD | MUST se rovnat fázi status_code |
| 6 | incident_reason |
string|null | SHOULD² | důvod v §4.4 |
| 7 | description |
string|null | MAY | čitelné člověkem |
| 8 | location |
object|null | MAY | §9.4 |
| 9 | actor |
object|null | MAY | { type, name?, phone? }; type ∈ {driver, operator, carrier, system} |
| 10 | source |
object | MUST | §9.5 |
| 11 | pod |
object|null | MAY³ | { photos[], signature[], recipient? } |
¹ Kódovaná událost MUST nést stavový kód z §4.1. Surový sken, který zatím nemůžete klasifikovat, MAY nastavit
status_code = null, ale MUST zachovat nativní kód v source.external_event_code a MUST
být započítán, nikdy nezahozen.
² Událost ve fázi exception SHOULD nést incident_reason.
³ Události se status_code ∈ {delivered, picked_up} SHOULD nést pod.
locationname (string) · code (string) · gln (GS1 GLN, 13 číslic) · lat / lng (WGS-84) ·
country (ISO 3166-1 alpha-2). Vše volitelné.
source| Pole | Typ | Pož. | Omezení |
|---|---|---|---|
type |
string | MUST | self_delivery | third_party_delivery | carrier_label |
provider_id |
integer|null | MAY | |
carrier_code |
string|null | MAY | |
external_event_code |
string|null | SHOULD⁴ | váš surový stavový kód |
raw |
object|null | MAY | původní payload |
⁴ MUST být přítomen, když je status_code null, aby se nativní kód nikdy neztratil.
occurred_at MUST být zpracovatelný jako ISO-8601. Při příjmu normalizujte číselné epochy a .NET /Date(ms)/;
tyto formy nevydávejte.occurred_at, tolerovat příchod mimo pořadí
a deduplikovat podle (subject, status_code, occurred_at).phase, current_status, current_phase, delivered jsou projekce — pokud
jsou přítomny, MUST být konzistentní s časovou osou událostí.Ověřte svůj výstup odesláním časové osy na POST /api/v1/otep/validate. Jakékoli
errors považujte za blokující; řešte warnings. Pro offline validaci jsou publikovány strojově
čitelné JSON Schema a kompletní číselník (každý stavový kód, fáze a externí mapování).
OTEP je otevřená specifikace, kterou může implementovat kdokoli zdarma.
otep:<profile>:<code>, fáze jako
otep:phase:<name>. Jakmile je identifikátor publikován ve vydané verzi, jeho význam je neměnný.otep_version).x-
(otep:parcel:x-my_code), dokud nejsou registrovány.OTEP vítá další dodavatele, aby přinesli svůj vlastní standard sledovacích událostí, aby s ním OTEP mohl interoperovat, v obou směrech:
source.external_event_code; nenamapované kódy jsou započítány, nikdy zahozeny.I když nemůžete přijmout OTEP přímo, jste vítáni přidat jediný normalizovaný otep_status
do svých vlastních API odpovědí a sdílet své kódy sledovacích událostí pro převodní mapování. Navrhujte
mapování vůči této specifikaci (místo forkování), aby implementátoři konvergovali; nové formáty se zapojí do
stejného vyjednávání obsahu ?format= a nikdy nenaruší existujícího konzumenta.