Prevod radi praktičnosti — merodavna je verzija na engleskom jeziku.
Status: Nacrt v0.1 · Otvorena, vendor-neutralna specifikacija · Licenca: otvorena (vidi §10)
OTEP je otvoren, vendor-neutralan protokol za životni ciklus bilo kog predmeta koji se može pratiti. Definiše jedan model događaja i jedan rečnik statusa tako da se događaji praćenja iz bilo kog izvora — dostava sopstvenom flotom, kuriri trećih strana, oznake prevoznika i šire — mogu razmenjivati, razumeti i projektovati na međunarodne standarde bez ponovne integracije za svaku stranu.
Ovaj dokument je specifikacija: struktura, polja, tabele statusa, automat stanja, mapiranja na spoljne standarde i pravila usaglašenosti za izgradnju usaglašene implementacije. Nezavisan je od implementacije — opisuje protokol, a ne interne mehanizme bilo kog konkretnog vendora. Ključne reči RFC-2119 (MUST / SHOULD / MAY) su normativne.
Praćenje je fragmentisano: svaki prevoznik drugačije imenuje polja i statusne kodove, svaki kanal dostave izveštava u sopstvenom obliku, a povezivanje sa globalnim standardima znači ponovnu integraciju iznova i iznova. OTEP daje proizvođačima i potrošačima jedan zajednički jezik: proizvođač jednom emituje OTEP događaje, a svaki OTEP potrošač ih razume i može ih projektovati na standard koji mu je potreban.
Vremenska linija je omotač koji nosi praćeni predmet i uređenu listu događaja.
{
"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"
}
}
Svako polje osim subject, occurred_at, status_code i source je opciono —
delimični izvori popunjavaju ono što imaju. Skeniranja na čvorovima/habovima postavljaju location na objekat skeniranja.
Visokofrekventna GPS telemetrija NIJE OTEP događaj; događaj se emituje pri promeni statusa ili
skeniranju na čvoru.
20 kanonskih kodova životnog ciklusa. phase se uvek može izvesti iz koda.
| code | phase | terminalno | POD | značenje |
|---|---|---|---|---|
information_submitted |
pre_shipment | informacije o porudžbini primljene | ||
booking_confirmed |
pre_shipment | prevoznik/rezervacija potvrđen | ||
awaiting_pickup |
pre_shipment | spremno za preuzimanje | ||
out_for_pickup |
pickup | na putu radi preuzimanja | ||
picked_up |
pickup | ✓ | preuzeto od pošiljaoca | |
pickup_failed |
exception | pokušaj preuzimanja neuspešan | ||
pickup_rescheduled |
exception | preuzimanje će se ponoviti | ||
received |
inbound | primljeno u objektu | ||
arrival_scan |
inbound | skeniranje dolaska na čvoru | ||
in_transit |
transit | u kretanju | ||
package_outbound |
transit | napustilo objekat | ||
removed_from_route |
exception | uklonjeno sa rute | ||
route_cancelled |
exception | ruta otkazana | ||
out_for_delivery |
out_for_delivery | u vozilu | ||
delivered |
delivered | ✓ | ✓ | isporučeno primaocu |
delivery_failed |
exception | pokušaj isporuke neuspešan | ||
delivery_rescheduled |
exception | ponoviće se / ponovna isporuka | ||
return_to_sender |
return | ✓ | vraćanje na poreklo | |
rejected_by_recipient |
return | ✓ | primalac odbio | |
cancelled |
return | ✓ | porudžbina otkazana |
pre_shipment · preparing · pickup · inbound · in_custody · transit ·
out_for_delivery · delivered · exception · return. (preparing i in_custody
rezervisani su za neparcel profile — §8.)
source.type: self_delivery · third_party_delivery · carrier_label.
time_type: actual · estimated · scheduled (podrazumevano actual).
Kada je događaj u fazi exception, SHOULD nositi incident_reason iz ovog
normalizovanog rečnika:
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, unknownFaze napreduju unapred; izuzeci ih prekidaju i vraćaju nazad. Terminalna stanja (delivered,
return_to_sender, rejected_by_recipient, cancelled) zatvaraju predmet.
pre_shipment → preparing → pickup → inbound → in_custody → transit → out_for_delivery → delivered ✓
└──────────── exception ──────────┘
└──────────── return / cancelled ✓
Pravila:
occurred_at i MUST tolerisati dolazak van redosleda.OTEP-ove četiri dimenzije poklapaju se polje-za-polje sa glavnim standardima, tako da je svaki izlazna projekcija OTEP događaja.
| 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 | — |
| subjekat (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 |
Vrednosti po kodu (EPCIS CBV bizStep/disposition, ONE Record eventCode, UN/CEFACT kod)
objavljene su u mašinski čitljivom kodeksu. Pored ovih međunarodnih standarda, OTEP
vremenska linija se takođe može projektovati na OpenTelemetry tragove, OGC SensorThings opservacije i
uobičajene komercijalne platforme (AfterShip, Shopify, Amazon, Walmart, BigCommerce, Magento,
WooCommerce, Etsy).
Pouzdanost: EPCIS CBV vrednosti su stabilni standardni URN-ovi. ONE Record i UN/CEFACT kodne vrednosti najbolje su prilagođene poslednjoj milji i treba ih proveriti u odnosu na zvanične kodne liste pre spoljne upotrebe. „Isporučeno primaocu“ nema tačan CBV bizStep — koristi se najbliže rešenje (
receiving+received), ili URN ekstenzije korisničkog rečnika.
OTEP se konzumira preko male HTTP površine samo za čitanje; sve krajnje tačke su javne.
| Verb | Path | Vraća |
|---|---|---|
| GET | /api/v1/otep/trackings/{tracking_number} |
vremensku liniju za broj za praćenje |
| GET | /api/v1/otep/trackings/{tracking_number}/events |
samo događaje |
| POST | /api/v1/otep/trackings/batch |
mnogo brojeva za praćenje u jednom pozivu |
| POST | /api/v1/otep/validate |
proveru usaglašenosti za poslatu vremensku liniju (§9) |
Dostupan je i GraphQL upit koji izlaže istu vremensku liniju.
Ista vremenska linija se serijalizuje u bilo koju reprezentaciju koju zatražite, preko ?format=
upitnog parametra ili Accept profila:
| Zahtev | Reprezentacija |
|---|---|
?format=otep (podrazumevano) |
izvorna OTEP vremenska linija |
?format=epcis |
GS1 EPCIS 2.0 (JSON-LD ObjectEvents) |
?format=onerecord |
IATA ONE Record (LogisticsEvents) |
?format=uncefact |
UN/CEFACT transportni status |
?format=otlp |
OpenTelemetry tragovi |
?format=sensorthings |
OGC SensorThings opservacije |
?format=aftership | shopify | amazon | walmart | bigcommerce | magento | woocommerce | etsy |
oblik praćenja/ispunjenja platforme |
Događaji kojima se ne može dodeliti kod u projekciji se preskaču i broje (nikada se tiho ne odbacuju).
OTEP je opšti protokol, a ne protokol za pakete. Sloj protokola (omotač događaja, kičma faza,
automat stanja) je univerzalan; konkretni statusni kodovi pripadaju profilu deklarisanom na
vremenskoj liniji preko profile. Kodovi u §4 su profil parcel. Drugi domeni —
selidbe, dostava hrane, skladištenje i šire — dodaju svoje skupove kodova pod svojim profilom,
sa prostorom imena otep:<profile>:<code>, svaki mapiran na istu kičmu faza. Dodavanje profila
je ekstenzija, a ne promena protokola.
Proizvođač ili potrošač je OTEP-usaglašen kada svaki događaj koji emituje ili prihvata zadovoljava ove tabele i pravila.
| Polje | Tip | Obav. | Ograničenja |
|---|---|---|---|
otep_version |
string | MUST | semver, npr. 0.1 |
profile |
string | MUST | registrovan profil |
subject |
object | MUST | §9.2 |
current_status |
string|null | SHOULD | statusni kod (§4) |
current_phase |
string|null | SHOULD | MUST biti jednako fazi koda current_status ako su oba prisutna |
delivered |
boolean | SHOULD | true ako i samo ako je current_status = delivered |
events |
array | MUST | objekti događaja (§9.3), sortirljivi po occurred_at |
subjectNajmanje JEDNO od tracking_number / order_id / package_id MUST biti prisutno.
| Polje | Tip | Ograničenja |
|---|---|---|
tracking_number |
string | nije prazno |
order_id / package_id |
integer|null | |
external_tracking_number |
string|null | |
gs1_sscc |
string|null | 18 cifara |
piece_id |
string|null |
| # | Polje | Tip | Obav. | Ograničenja |
|---|---|---|---|---|
| 1 | occurred_at |
string | MUST | ISO-8601 sa ofsetom |
| 2 | recorded_at |
string|null | SHOULD | ISO-8601 |
| 3 | time_type |
string | MAY (podrazumevano actual) |
actual | estimated | scheduled |
| 4 | status_code |
string|null | MUST¹ | kod iz §4.1 |
| 5 | phase |
string|null | SHOULD | MUST biti jednako fazi koda status_code |
| 6 | incident_reason |
string|null | SHOULD² | razlog iz §4.4 |
| 7 | description |
string|null | MAY | čitljivo za čoveka |
| 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? } |
¹ Kodirani događaj MUST nositi statusni kod iz §4.1. Sirovo skeniranje koje još ne možete klasifikovati MAY postaviti
status_code = null, ali MUST sačuvati izvorni kod u source.external_event_code i MUST
biti izbrojano, nikada odbačeno.
² Događaj u fazi exception SHOULD nositi incident_reason.
³ Događaji sa status_code ∈ {delivered, picked_up} SHOULD nositi pod.
locationname (string) · code (string) · gln (GS1 GLN, 13 cifara) · lat / lng (WGS-84) ·
country (ISO 3166-1 alpha-2). Sve opciono.
source| Polje | Tip | Obav. | Ograničenja |
|---|---|---|---|
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⁴ | vaš sirovi statusni kod |
raw |
object|null | MAY | originalni payload |
⁴ MUST biti prisutno kada je status_code null, tako da se izvorni kod nikada ne izgubi.
occurred_at MUST se parsirati kao ISO-8601. Normalizujte numeričke epohe i .NET /Date(ms)/
pri unosu; nemojte emitovati te oblike.occurred_at, tolerisati dolazak van redosleda
i deduplikovati po (subject, status_code, occurred_at).phase, current_status, current_phase, delivered su projekcije — ako su
prisutni MUST biti konzistentni sa vremenskom linijom događaja.Proverite svoj izlaz slanjem vremenske linije na POST /api/v1/otep/validate. Tretirajte svaku
grešku (errors) kao blokirajuću; rešite upozorenja (warnings). Mašinski čitljiva JSON Schema i kompletan
kodeks (svaki statusni kod, faza i spoljno mapiranje) objavljeni su za oflajn validaciju.
OTEP je otvorena specifikacija, besplatna za implementaciju bilo kojoj strani.
otep:<profile>:<code>, faze kao
otep:phase:<name>. Jednom objavljeno u izdatoj verziji, značenje identifikatora je nepromenljivo.otep_version).x-
(otep:parcel:x-my_code) dok se ne registruju.OTEP poziva druge vendore da donesu sopstveni standard događaja praćenja kako bi OTEP mogao da interoperira sa njim, u oba smera:
source.external_event_code; nemapirani kodovi se broje, nikada ne odbacuju.Čak i ako ne možete direktno usvojiti OTEP, dobrodošli ste da dodate jedan normalizovani otep_status
sopstvenim API odgovorima i da podelite svoje kodove događaja praćenja za ukršteno mapiranje. Predložite
mapiranja u odnosu na ovu specifikaciju (umesto forkovanja) kako bi se implementatori približili; novi formati se priključuju
istom ?format= pregovaranju o sadržaju i nikada ne narušavaju postojećeg potrošača.