Fordítás a kényelem érdekében — az angol változat a hiteles.
Állapot: Tervezet v0.1 · Nyílt, szállítófüggetlen specifikáció · Licenc: nyílt (lásd §10)
Az OTEP egy nyílt, szállítófüggetlen protokoll bármely követhető alany életciklusához. Egyetlen eseménymodellt és egyetlen állapotszótárt határoz meg, hogy a követési események bármilyen forrásból — saját flottás kézbesítés, harmadik feles futárok, fuvarozói címkék és azon túl — cserélhetők, érthetők és nemzetközi szabványokra vetíthetők legyenek anélkül, hogy minden féllel újra kellene integrálni.
Ez a dokumentum a specifikáció: a struktúra, a mezők, az állapottáblák, az állapotgép, a külső szabványokra való leképezések és a megfelelőségi szabályok egy megfelelő implementáció megépítéséhez. Implementációfüggetlen — a protokollt írja le, nem valamely konkrét szállító belső működését. Az RFC-2119 kulcsszavak (MUST / SHOULD / MAY) normatívak.
A követés széttöredezett: minden fuvarozó másként nevezi el a mezőit és állapotkódjait, minden kézbesítési csatorna a saját formájában jelent, és a globális szabványokhoz való csatlakozás azt jelenti, hogy újra és újra integrálni kell. Az OTEP egyetlen közös nyelvet ad a producereknek és a fogyasztóknak: egy producer egyszer bocsát ki OTEP eseményeket, és minden OTEP fogyasztó megérti őket, és arra a szabványra vetítheti, amelyikre szüksége van.
Az idővonal egy boríték, amely a követett alanyt és egy rendezett eseménylistát hordoz.
{
"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"
}
}
A subject, occurred_at, status_code és source kivételével minden mező opcionális — a
részleges források azt töltik ki, amijük van. A csomópont/hub szkennelések a location mezőt a
szkennelő létesítményre állítják. A nagyfrekvenciás GPS-telemetria NEM OTEP esemény; egy esemény
állapotváltozáskor vagy csomópont-szkenneléskor keletkezik.
20 kanonikus életciklus-kód. A phase mindig levezethető a kódból.
| kód | phase | terminális | POD | jelentés |
|---|---|---|---|---|
information_submitted |
pre_shipment | rendelési információ beérkezett | ||
booking_confirmed |
pre_shipment | fuvarozó/foglalás visszaigazolva | ||
awaiting_pickup |
pre_shipment | gyűjtésre kész | ||
out_for_pickup |
pickup | úton a felvételhez | ||
picked_up |
pickup | ✓ | feladótól átvéve | |
pickup_failed |
exception | felvételi kísérlet sikertelen | ||
pickup_rescheduled |
exception | felvétel újrapróbálkozik | ||
received |
inbound | létesítményben átvéve | ||
arrival_scan |
inbound | beérkezési szkennelés a csomópontnál | ||
in_transit |
transit | mozgásban | ||
package_outbound |
transit | létesítményből elindult | ||
removed_from_route |
exception | útvonalról levéve | ||
route_cancelled |
exception | útvonal törölve | ||
out_for_delivery |
out_for_delivery | a járművön | ||
delivered |
delivered | ✓ | ✓ | címzettnek kézbesítve |
delivery_failed |
exception | kézbesítési kísérlet sikertelen | ||
delivery_rescheduled |
exception | újrapróbálkozik / újrakézbesít | ||
return_to_sender |
return | ✓ | visszatérés a feladóhoz | |
rejected_by_recipient |
return | ✓ | címzett visszautasította | |
cancelled |
return | ✓ | rendelés törölve |
pre_shipment · preparing · pickup · inbound · in_custody · transit ·
out_for_delivery · delivered · exception · return. (A preparing és az in_custody a
nem-csomag profilok számára van fenntartva — §8.)
source.type: self_delivery · third_party_delivery · carrier_label.
time_type: actual · estimated · scheduled (alapértelmezett actual).
Amikor egy esemény az exception fázisban van, SHOULD hordoznia egy incident_reason értéket
ebből a normalizált szókészletből:
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, unknownA fázisok előre haladnak; a kivételek megszakítják, majd visszaoldódnak. A terminális állapotok
(delivered, return_to_sender, rejected_by_recipient, cancelled) lezárják az alanyt.
pre_shipment → preparing → pickup → inbound → in_custody → transit → out_for_delivery → delivered ✓
└──────────── exception ──────────┘
└──────────── return / cancelled ✓
Szabályok:
occurred_at szerint rendezniük az eseményeket, és MUST tolerálniuk a
sorrenden kívüli érkezést.Az OTEP négy dimenziója mezőről mezőre illeszkedik a fő szabványokhoz, így mindegyik egy OTEP esemény kimeneti vetülete.
| 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 |
A kódonkénti értékek (EPCIS CBV bizStep/disposition, ONE Record eventCode, UN/CEFACT kód) a
gépi olvasású kódkönyvben kerülnek közzétételre. E nemzetközi szabványokon túl egy OTEP idővonal
OpenTelemetry trace-ekre, OGC SensorThings megfigyelésekre és gyakori kereskedelmi platformokra
(AfterShip, Shopify, Amazon, Walmart, BigCommerce, Magento, WooCommerce, Etsy) is vetíthető.
Bizonyosság: az EPCIS CBV értékek stabil szabványos URN-ek. A ONE Record és UN/CEFACT kódértékek a végső kézbesítésre vett legjobb illeszkedések, és külső használat előtt ellenőrizni kell őket a hivatalos kódlistákkal szemben. A „címzettnek kézbesítve” esetnek nincs pontos CBV
bizStep-je — a legközelebbi illeszkedés (receiving+received) használatos, vagy egy felhasználói szókészlet-kiterjesztés URN.
Az OTEP egy kis, csak olvasható HTTP felületen keresztül fogyasztható; minden végpont nyilvános.
| Ige | Útvonal | Visszaad |
|---|---|---|
| GET | /api/v1/otep/trackings/{tracking_number} |
egy követési szám idővonalát |
| GET | /api/v1/otep/trackings/{tracking_number}/events |
csak az eseményeket |
| POST | /api/v1/otep/trackings/batch |
sok követési szám egy hívásban |
| POST | /api/v1/otep/validate |
megfelelőségi ellenőrzés egy beküldött idővonalra (§9) |
Egy GraphQL lekérdezés, amely ugyanazt az idővonalat teszi elérhetővé, szintén rendelkezésre áll.
Ugyanaz az idővonal abba a reprezentációba szerializálódik, amelyiket kérsz, egy ?format=
lekérdezési paraméteren vagy egy Accept profilon keresztül:
| Kérés | Reprezentáció |
|---|---|
?format=otep (alapértelmezett) |
natív OTEP idővonal |
?format=epcis |
GS1 EPCIS 2.0 (JSON-LD ObjectEvent-ek) |
?format=onerecord |
IATA ONE Record (LogisticsEvent-ek) |
?format=uncefact |
UN/CEFACT szállítási állapot |
?format=otlp |
OpenTelemetry trace-ek |
?format=sensorthings |
OGC SensorThings megfigyelések |
?format=aftership | shopify | amazon | walmart | bigcommerce | magento | woocommerce | etsy |
a platform követési/teljesítési formája |
Azok az események, amelyekhez egy vetületben nem rendelhető kód, kihagyásra és megszámolásra kerülnek (soha nem dobódnak el csendben).
Az OTEP egy általános protokoll, nem csomagprotokoll. A protokollréteg (eseményboríték,
fázisgerinc, állapotgép) univerzális; a konkrét állapotkódok egy profilhoz tartoznak, amelyet
az idővonalon a profile deklarál. A §4 kódjai a parcel profil. Más domainek — költöztetés,
ételszállítás, tárolás és azon túl — saját kódkészleteket adnak a profiljuk alatt,
otep:<profile>:<code> névtérrel, mindegyik ugyanahhoz a fázisgerinchez illeszkedve. Egy profil
hozzáadása kiterjesztés, nem protokollváltozás.
Egy producer vagy fogyasztó akkor OTEP-megfelelő, ha minden esemény, amelyet kibocsát vagy elfogad, kielégíti ezeket a táblákat és szabályokat.
| Mező | Típus | Köt. | Megszorítások |
|---|---|---|---|
otep_version |
string | MUST | semver, pl. 0.1 |
profile |
string | MUST | regisztrált profil |
subject |
object | MUST | §9.2 |
current_status |
string|null | SHOULD | egy állapotkód (§4) |
current_phase |
string|null | SHOULD | MUST egyezzen a current_status fázisával, ha mindkettő jelen van |
delivered |
boolean | SHOULD | true akkor és csak akkor, ha current_status = delivered |
events |
array | MUST | eseményobjektumok (§9.3), occurred_at szerint rendezhetők |
subjectA tracking_number / order_id / package_id közül legalább EGY MUST jelen legyen.
| Mező | Típus | Megszorítások |
|---|---|---|
tracking_number |
string | nem üres |
order_id / package_id |
integer|null | |
external_tracking_number |
string|null | |
gs1_sscc |
string|null | 18 számjegy |
piece_id |
string|null |
| # | Mező | Típus | Köt. | Megszorítások |
|---|---|---|---|---|
| 1 | occurred_at |
string | MUST | ISO-8601 eltolással |
| 2 | recorded_at |
string|null | SHOULD | ISO-8601 |
| 3 | time_type |
string | MAY (alapértelmezett actual) |
actual | estimated | scheduled |
| 4 | status_code |
string|null | MUST¹ | egy kód a §4.1-ben |
| 5 | phase |
string|null | SHOULD | MUST egyezzen a status_code fázisával |
| 6 | incident_reason |
string|null | SHOULD² | egy ok a §4.4-ben |
| 7 | description |
string|null | MAY | ember által olvasható |
| 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? } |
¹ Egy kódolt esemény MUST hordozzon egy állapotkódot a §4.1-ből. Egy nyers szkennelés, amelyet
még nem tudsz besorolni, MAY status_code = null értékre állítsa, de MUST megőrizze a natív kódot
a source.external_event_code mezőben, és MUST megszámolódjon, soha ne dobódjon el.
² Egy exception-fázisú esemény SHOULD hordozzon egy incident_reason értéket.
³ Azok az események, ahol status_code ∈ {delivered, picked_up}, SHOULD hordozzanak egy pod
értéket.
locationname (string) · code (string) · gln (GS1 GLN, 13 számjegy) · lat / lng (WGS-84) ·
country (ISO 3166-1 alpha-2). Mind opcionális.
source| Mező | Típus | Köt. | Megszorítások |
|---|---|---|---|
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⁴ | a nyers állapotkódod |
raw |
object|null | MAY | eredeti payload |
⁴ MUST jelen legyen, amikor a status_code null, így a natív kód soha nem vész el.
occurred_at MUST ISO-8601 formátumként értelmezhető legyen. A numerikus epoch
értékeket és a .NET /Date(ms)/ formákat normalizáld a beolvasáskor; ne ezeket a formákat
bocsásd ki.occurred_at szerint rendezniük, tolerálniuk
a sorrenden kívüli érkezést, és deduplikálniuk a (subject, status_code, occurred_at)
alapján.phase, current_status, current_phase, delivered vetületek — ha jelen
vannak, MUST konzisztensek legyenek az eseményidővonallal.Ellenőrizd a kimenetedet egy idővonal beküldésével a POST /api/v1/otep/validate végpontra.
Minden errors értéket kezelj blokkolóként; foglalkozz a warnings értékekkel. Egy gépi olvasású
JSON Schema és a teljes kódkönyv (minden állapotkód, fázis és külső leképezés) offline validációhoz
közzétételre kerül.
Az OTEP egy nyílt specifikáció, amelyet bármely fél szabadon implementálhat.
otep:<profile>:<code>, a fázisok otep:phase:<name> formában
címezhetők. Ha egyszer egy kiadott verzióban közzétételre kerül, egy azonosító jelentése
megváltoztathatatlan.otep_version).x- előtagot
használjanak (otep:parcel:x-my_code), amíg regisztrálva nincsenek.Az OTEP üdvözli, hogy más szállítók behozzák a saját követésiesemény-szabványukat, hogy az OTEP együttműködhessen vele, mindkét irányban:
source.external_event_code mezőben; a nem leképezett kódok megszámolódnak, soha nem dobódnak el.Még ha nem is tudod közvetlenül átvenni az OTEP-et, szívesen látott, hogy egyetlen normalizált
otep_status értéket adj a saját API-válaszaidhoz, és megoszd a követésiesemény-kódjaidat
megfeleltetési leképezéshez. A leképezéseket e specifikáció ellenében javasold (nem forkolva), hogy
az implementálók konvergáljanak; az új formátumok ugyanabba a ?format= tartalomegyeztetésbe
csatlakoznak, és soha nem törnek meg egy meglévő fogyasztót.