# Kody zdarzeń śledzenia

Generowane na żywo pod https://api.superlabel.ca/api/documentation/tracking-events?lang=pl z wdrożonej tabeli słownika `tracking` (które kody statusu istnieją i czy klienci je widzą), kluczy TrackingEvent oraz zlokalizowanych opisów `tracking.*`. Zawsze zgodne z bazą tego środowiska.

## Strona zdarzenia, nie typ zamówienia

Ten słownik **nie** jest listą typów zamówień. To samo zamówienie może emitować zdarzenia strony odbioru i strony dostawy — np. dostawa z przystankiem odbioru, peer-to-peer (dwa odcinki), transfer wieloodcinkowy lub przekazanie magazynowe. Instant Deliver używa osobnego słownika (nie wymienionego tutaj). Każde zdarzenie śledzenia ma **stronę** (odbiór lub dostawa), która wybiera opis i widoczność dla tego statusu. Numeryczny `status_id` i stabilny `key` odpowiadają `tracking_event_status_id` / `tracking_event_key` w ładunkach API i webhooków; rozgałęziaj logikę po tych polach (i stronie, gdy liczy się tekst), nigdy po typie zamówienia i nigdy po zlokalizowanym tekście opisu.

## Widoczność dla klienta (`tracking.visible`)

Publiczna strona śledzenia i publiczne API śledzenia pokazują tylko zdarzenia, których wiersz słownika ma `tracking.visible = 1`, połączone przez kod statusu **oraz** stronę zdarzenia (tę samą stronę co na zdarzeniu). Statusy oznaczone **Nie** nadal istnieją w systemie (webhooki, historia operacji, narzędzia wewnętrzne), ale są ukryte na osi czasu skierowanej do klienta. Widoczność jest odczytywana na żywo z tabeli `tracking` tej instalacji.

## Zdarzenia strony dostawy

Statusy, gdy zdarzenie śledzenia jest po **stronie dostawy** podróży (dostawa / last mile). Dotyczy czystych dostaw, odcinka dostawy peer-to-peer, dostawy z odbiorem, multi-leg i podobnych przepływów — **nie tylko** „czystych zamówień dostawy”. **Widoczne dla klienta** to `tracking.visible` tego statusu po tej stronie.

| status_id | key | otep | otep phase | widoczne dla klienta | description |
|---|---|---|---|---|---|
| 100 | `information_submitted` | `information_submitted` | `pre_shipment` | Tak | Twoje informacje o przesyłce zostały przesłane. |
| 110 | `booking_confirmed` | `booking_confirmed` | `pre_shipment` | Tak | Twoja przesyłka została potwierdzona. |
| 120 | `awaiting_pickup` | `awaiting_pickup` | `pre_shipment` | Tak | Twoja paczka oczekuje na odbiór. |
| 200 | `pushed_successful` | — | — | Nie | Twoje zamówienie zostało wysłane do planowania trasy. |
| 201 | `pushed_failed` | — | — | Nie | Nie udało się wysłać Twojego zamówienia do planowania trasy. Zostanie ponowione lub przeplanowane. |
| 300 | `received` | `received` | `inbound` | Tak | Twoja paczka dotarła bezpiecznie do {warehouse_name}. |
| 301 | `arrival_scan` | `arrival_scan` | `inbound` | Tak | Twoja paczka została odebrana i dotarła do {warehouse_name}. |
| 400 | `planned` | `in_transit` | `transit` | Nie | Twoja paczka jest załadowana i gotowa do dostawy. |
| 401 | `removed_from_route` | `removed_from_route` | `exception` | Nie | Twoja dostawa zostanie wkrótce przełożona; proszę czekać na aktualizację. |
| 402 | `route_cancelled` | `route_cancelled` | `exception` | Nie | Status Twojej dostawy zostanie wkrótce zaktualizowany. |
| 430 | `in_transit` | `in_transit` | `transit` | Tak | Twoja paczka jest w drodze. |
| 431 | `on_hold` | `in_transit` | `transit` | Tak | Twoja paczka jest tymczasowo wstrzymana. Wkrótce przekażemy aktualizację. |
| 432 | `customs_clearance` | `in_transit` | `transit` | Tak | Twoja paczka jest w trakcie odprawy celnej. |
| 433 | `loaded` | `package_outbound` | `transit` | Tak | Twoja paczka została załadowana i wkrótce wyruszy. |
| 434 | `collection_on_hold` | `awaiting_pickup` | `pre_shipment` | Tak | Odbiór Twojej paczki jest tymczasowo wstrzymany. Wkrótce przekażemy aktualizację. |
| 435 | `facility_received` | `in_transit` | `transit` | Tak | Twoja paczka została przyjęta przez centrum logistyczne. |
| 436 | `arrived_at_facility` | `in_transit` | `transit` | Tak | Twoja paczka dotarła do centrum logistycznego. |
| 450 | `start_delivery` | `out_for_delivery` | `out_for_delivery` | Tak | Twoja paczka jest obecnie w drodze do dostawy. |
| 470 | `at_device` | `awaiting_pickup` | `pre_shipment` | Tak | Twoja paczka czeka na Ciebie w automacie paczkowym. |
| 471 | `device_picked_up` | `delivered` | `delivered` | Tak | Twoja paczka została odebrana z automatu paczkowego. |
| 472 | `device_expired` | `awaiting_pickup` | `pre_shipment` | Tak | Twoja paczka nie została odebrana w terminie i nadal znajduje się w automacie paczkowym. |
| 473 | `device_removed` | `received` | `inbound` | Tak | Twoja paczka została wyjęta z automatu paczkowego przez personel. |
| 500 | `deliver_success` | `delivered` | `delivered` | Tak | Twoja paczka została dostarczona pomyślnie. Dziękujemy! |
| 501 | `need_rescheduled` | `delivery_rescheduled` | `exception` | Tak | Niestety, nie udało nam się dostarczyć Twojej paczki. |
| 502 | `redelivered_later` | `delivery_rescheduled` | `exception` | Tak | Niestety, nie udało nam się dostarczyć Twojej paczki. |
| 503 | `not_delivered` | `delivery_failed` | `exception` | Tak | Napotkaliśmy problem z Twoją dostawą. Skontaktuj się z naszym zespołem wsparcia. |
| 504 | `partial_deliver_success` | — | — | Tak | Ta paczka została dostarczona. Pozostałe paczki Twojej przesyłki są nadal w drodze. |
| 510 | `pickuped` | `picked_up` | `pickup` | Tak | Paczka została pomyślnie odebrana przez naszego kuriera. |
| 800 | `package_outbound` | `package_outbound` | `transit` | Tak | Twoja paczka opuściła {warehouse_name}. |

## Zdarzenia strony odbioru

Statusy, gdy zdarzenie śledzenia jest po **stronie odbioru** podróży (odcinek odbioru). Dotyczy czystych odbiorów, odcinka odbioru peer-to-peer, dostawy z odbiorem, multi-leg i podobnych przepływów — **nie tylko** „czystych zamówień odbioru”. **Widoczne dla klienta** to `tracking.visible` tego statusu po tej stronie.

| status_id | key | otep | otep phase | widoczne dla klienta | description |
|---|---|---|---|---|---|
| 100 | `information_submitted` | `information_submitted` | `pre_shipment` | Tak | Twoje żądanie paczki zostało pomyślnie otrzymane. |
| 110 | `booking_confirmed` | `booking_confirmed` | `pre_shipment` | Tak | Twoje zlecenie odbioru zostało potwierdzone. |
| 120 | `awaiting_pickup` | `awaiting_pickup` | `pre_shipment` | Tak | Twoja paczka oczekuje na odbiór. |
| 200 | `pushed_successful` | — | — | Nie | Twoje zamówienie odbioru zostało wysłane do planowania trasy. |
| 201 | `pushed_failed` | — | — | Nie | Nie udało się wysłać Twojego zamówienia odbioru do planowania trasy. Zostanie ponowione lub przeplanowane. |
| 300 | `received` | `received` | `inbound` | Tak | Otrzymaliśmy Twoją paczkę w naszym obiekcie. |
| 301 | `arrival_scan` | `arrival_scan` | `inbound` | Tak | Order a-scan |
| 400 | `planned` | `in_transit` | `transit` | Nie | Twoja paczka jest obecnie przetwarzana. |
| 401 | `removed_from_route` | `removed_from_route` | `exception` | Nie | Odbiór Twojej paczki zostanie wkrótce przełożony. |
| 402 | `route_cancelled` | `route_cancelled` | `exception` | Nie | Status odbioru zostanie wkrótce zaktualizowany. |
| 430 | `in_transit` | `in_transit` | `transit` | Tak | Twoja paczka jest w drodze. |
| 431 | `on_hold` | `in_transit` | `transit` | Tak | Twoja paczka jest tymczasowo wstrzymana. Wkrótce przekażemy aktualizację. |
| 432 | `customs_clearance` | `in_transit` | `transit` | Tak | Twoja paczka jest w trakcie odprawy celnej. |
| 433 | `loaded` | `package_outbound` | `transit` | Tak | Twoja paczka została załadowana i wkrótce wyruszy. |
| 434 | `collection_on_hold` | `awaiting_pickup` | `pre_shipment` | Tak | Odbiór Twojej paczki jest tymczasowo wstrzymany. Wkrótce przekażemy aktualizację. |
| 435 | `facility_received` | `in_transit` | `transit` | Tak | Twoja paczka została przyjęta przez centrum logistyczne. |
| 436 | `arrived_at_facility` | `in_transit` | `transit` | Tak | Twoja paczka dotarła do centrum logistycznego. |
| 450 | `start_delivery` | `out_for_delivery` | `out_for_delivery` | Tak | Kurier jest w drodze po Twoją paczkę. |
| 470 | `at_device` | `awaiting_pickup` | `pre_shipment` | Tak | Twoja paczka czeka na Ciebie w automacie paczkowym. |
| 471 | `device_picked_up` | `delivered` | `delivered` | Tak | Twoja paczka została odebrana z automatu paczkowego. |
| 472 | `device_expired` | `awaiting_pickup` | `pre_shipment` | Tak | Twoja paczka nie została odebrana w terminie i nadal znajduje się w automacie paczkowym. |
| 473 | `device_removed` | `received` | `inbound` | Tak | Twoja paczka została wyjęta z automatu paczkowego przez personel. |
| 500 | `deliver_success` | `delivered` | `delivered` | Tak | Twoja paczka została pomyślnie odebrana. |
| 501 | `need_rescheduled` | `delivery_rescheduled` | `exception` | Tak | Odbiór paczki został przełożony. Wkrótce poinformujemy Cię o nowym terminie. |
| 502 | `redelivered_later` | `delivery_rescheduled` | `exception` | Tak | Odbiór paczki został przełożony. Wkrótce poinformujemy Cię o nowym terminie. |
| 503 | `not_delivered` | `delivery_failed` | `exception` | Tak | Napotkaliśmy problem z Twoją paczką. Skontaktuj się z naszym zespołem wsparcia. |
| 504 | `partial_deliver_success` | — | — | Tak | Ta paczka została odebrana. Pozostałe paczki Twojej przesyłki zostaną odebrane wkrótce. |
| 510 | `pickuped` | `picked_up` | `pickup` | Tak | Twoja paczka została pomyślnie odebrana. |
| 800 | `package_outbound` | `package_outbound` | `transit` | Tak | Twoja paczka opuściła {warehouse_name}. |

Kolumny **otep** / **otep phase** są generowane na żywo z `OTEPStatusInput::FROM_TRACKING_EVENT` i `PHASES` — ten sam most, który publiczne API śledzenia zapisuje jako `otep_status` na każdym zdarzeniu. Myślnik (—) oznacza brak kodu OTEP w profilu parcel (np. push routingu 200/201); zdarzenie i tak jest zapisywane i może być widoczne dla klienta przy `visible = 1`.

## Zbuduj własną stronę śledzenia

Użyj **publicznego API śledzenia**, by napędzić stronę z Twoją marką na witrynie lub w aplikacji — bez logowania i tokena. Ten sam endpoint zasila wbudowaną stronę i operację GraphQL `trackingPublic`. Połącz go ze słownikiem statusów na tej stronie i wzorcami przepływu poniżej.

### 1. Wywołaj publiczny endpoint

Jeden GET na numer śledzenia. Wyszukiwanie obejmuje numery Superroute, zewnętrzne i niektóre numery stron trzecich bez id dostawcy.

```
GET https://api.superlabel.ca/api/v1/tracking/{tracking_number}
```

- No authentication — public, rate-limited with the rest of the API.
- Path parameter: the Superroute tracking number, external tracking number, or (when applicable) third-party tracking number without a third-party provider id.
- HTTP **200** with `"result": true` when found; **404** with `"result": false` when not found or the order is cancelled.

### 2. Wybierz język opisów

Teksty `description` podążają za locale żądania przez nagłówek `Accept-Language`. Wyślij kod języka projektu (`en`, `chs`, `pl`, …) lub alias, np. `zh-CN`. Bez nagłówka używana jest domyślna locale.

```
Accept-Language: chs
Accept-Language: zh-CN
Accept-Language: de
```

### 3. Pola odpowiedzi do renderowania

Zwracana jest tylko powierzchnia publiczna — pełne adresy nadawcy/odbiorcy **nie** są dołączone (tylko na uwierzytelnionym endpointcie wewnętrznym).

| field | meaning |
|---|---|
| `result` | `true` when a live order was found |
| `data` | Event timeline (newest first) |
| `data[].tracking_event_status_id` | Numeric code — match the dictionary on this page |
| `data[].otep_status` | Open tracking code when mapped (same bridge as the **otep** column) |
| `data[].description` | Localized customer text for this event |
| `data[].updated_at` / `timestamp` / `updated_at_localized` | When it happened (UTC string, unix, local clock) |
| `data[].location_*` / `operation_location` | Where it happened, when known |
| `data[].reason` | Public return/failure reason text when present |
| `deliveried` / `returntosender` / `rejectedbyrecipient` | Coarse final-state flags for header chips |
| `postcode` | Normalized delivery postcode (for POD gate on your side if you need it) |
| `proofs[]` | Signature / photo files (`url`, `full_url`, `signed_url`, `type`, `file_id`) |
| `is_third_party_tracking` / `third_party_info` | Present when a label/carrier timeline was merged in |

### 4. Zalecany przepływ UI

1. Zbierz numer od odwiedzającego i wywołaj publiczny GET (opcjonalnie z `Accept-Language`).
2. Jeśli `result` jest false lub HTTP to 404, pokaż nie znaleziono i zatrzymaj się.
3. Użyj `data[0]` (najnowsze zdarzenie) do statusu nagłówka: tekst z `description`; ikony/postęp z `tracking_event_status_id` lub `otep_status`.
4. Wyrenderuj całą listę `data` jako oś czasu (już od najnowszych). Nie wymyślaj brakujących kroków.
5. Jeśli `proofs` nie jest puste, a ostatni status to sukces (zwykle 500 lub 510), zaproponuj podgląd dowodu; `signed_url` dla wygasających linków, `full_url` dla trwałej ścieżki.

### 5. Wskaźniki postępu

**Nie** hardkoduj jednego łańcucha dla każdej paczki. Użyj słownika i przepływów na tej stronie. Rozgałęziaj po `otep_status` lub `tracking_event_status_id`; najnowsze zdarzenie jest autorytatywne.

### 6. Dowód dostawy

`proofs[]` niesie metadane zdjęcia/podpisu, gdy są dostępne. Twoja strona może nadal wymagać kodu pocztowego przed pokazaniem; API zwraca znormalizowane pole `postcode`. Nie umieszczaj pełnych adresów ulicznych na w pełni publicznej stronie.

### 7. Powiązane powierzchnie publiczne

Wybierz pasującą do Twojego stacka. Wszystkie są publiczne (bez tokena), o ile dokumentacja API nie stanowi inaczej.

| surface | when to use |
|---|---|
| `GET https://api.superlabel.ca/api/v1/tracking/{tracking_number}` | Default branded tracking page (this guide) |
| GraphQL `trackingPublic(trackingNumber: …)` at `https://api.superlabel.ca/graphql` | Same payload when your stack is GraphQL-first |
| `GET https://api.superlabel.ca/api/v1/otep/trackings/{tracking_number}` | Vendor-neutral OTEP timeline / EPCIS / ONE Record / UN-CEFACT projections |

### 8. Minimalne przykłady

```bash
curl -sS -H "Accept-Language: en" \
  "https://api.superlabel.ca/api/v1/tracking/SR1234567890"
```

```javascript
const res = await fetch(`https://api.superlabel.ca/api/v1/tracking/${encodeURIComponent(tn)}`, {
  headers: { "Accept-Language": "chs" },
});
const body = await res.json();
if (!body.result) {
  // show "not found"
} else {
  const events = body.data || [];          // newest first
  const latest = events[0];
  const proofs = body.proofs || [];
  // render latest.description, map latest.tracking_event_status_id or otep_status for the stepper
}
```

## Typowe wzorce przepływu śledzenia

To **typowe sekwencje**, nie twarda maszyna stanów. Rzeczywiste osie czasu pomijają kroki, wstawiają wyjątki lub przeplatają zdarzenia strony odbioru i dostawy na tym samym zamówieniu. Liczby to `tracking_event_status_id`; publiczna oś pokazuje tylko wiersze z `tracking.visible = 1`. Rozgałęziaj po `status_id` / `key` i traktuj najnowsze zdarzenie (najwyższe id) jako autorytatywne.

### Magazyn → dostawa last-mile

Najczęstsza ścieżka własnej floty: zamówienie utworzone, paczka przyjęta, kierowca w dostawie, potem sukces lub wyjątek. Kody planowania 400/401/402 często istnieją, ale **nie** są widoczne dla klienta.

```mermaid
flowchart LR
  s100["100 information_submitted"] --> s300["300 received / 301 arrival_scan"]
  s300 --> s450["450 start_delivery"]
  s450 --> s500["500 deliver_success"]
  s450 --> s501["501 need_rescheduled"]
  s450 --> s502["502 redelivered_later"]
  s450 --> s503["503 not_delivered"]
  s450 --> s700["700 rejected_by_recipient"]
  s501 --> s450
  s502 --> s450
```

### Odbiór / czysty odcinek odbioru

Kierowca jedzie po paczkę i rejestruje sukces (POD możliwy) lub wyjątek odbioru. Czyste odbiory zostają po stronie odbioru; dwuodcinkowe przechodzą na stronę dostawy po 510.

```mermaid
flowchart LR
  s100["100 information_submitted"] --> s460["460 start_pickup"]
  s460 --> s510["510 pickuped"]
  s460 --> s512["512 repickup_later"]
  s460 --> s513["513 not_pickuped"]
  s512 --> s460
```

### Dwa odcinki (najpierw odbiór, potem dostawa)

Gdy podróż ma odbiór i dostawę — dostawa z odbiorem, peer-to-peer, wiele multi-leg. Oś czasu zwykle pokazuje najpierw kamienie milowe **strony odbioru** (460 → 510), potem **strony dostawy** (450 → 500). Strona zdarzenia wybiera opis, nie typ zamówienia.

```mermaid
flowchart LR
  s100["100 information_submitted"] --> pickup["Pickup-side: 460 → 510"]
  pickup --> delivery["Delivery-side: 450 → 500"]
  pickup --> pFail["Pickup exception: 512 / 513"]
  delivery --> dFail["Delivery exception: 501 / 502 / 503 / 700"]
```

### Realizacja przez stronę trzecią / przewoźnika

Rezerwacja przewoźnika może emitować 110/120; polityka produktu trzyma je **ukryte** na publicznej osi. Wspólne widoczne kamienie milowe idą za magazynem + last mile (300/301 → 800 → 450 → 500). Terminalne anulowanie używa 403 (nie 402).

```mermaid
flowchart LR
  s100["100 information_submitted"] --> s110["110 / 120 hidden on public timeline"]
  s110 --> s300["300 / 301 warehouse"]
  s300 --> s800["800 package_outbound"]
  s800 --> s450["450 start_delivery"]
  s450 --> s500["500 deliver_success"]
  s450 --> sFail["501 / 503 / 600 / 700"]
```

### Instant Deliver (dyspozycja zadaniami)

Własny słownik (nie w tabelach powyżej). Szczęśliwa ścieżka: złożone → kurier przypisany → w drodze po odbiór → odebrane → w dostawie → dostarczone. 411/412 mogą się zapętlać przed startem; 501 po nieudanej próbie.

```mermaid
flowchart LR
  s100["100 information_submitted"] --> s410["410 rider_assigned"]
  s410 --> s411["411 reassigned optional"]
  s410 --> s412["412 assignment_cancelled"]
  s412 --> s410
  s410 --> s460["460 start_pickup"]
  s460 --> s510["510 pickuped"]
  s510 --> s450["450 start_delivery"]
  s450 --> s500["500 deliver_success"]
  s450 --> s501["501 need_rescheduled"]
```

### Kody wyjątków i terminalne (szybka mapa)

| status_id | key | typical meaning |\n|---|---|---|\n| 501 | need_rescheduled | Delivery failed; needs a new plan |\n| 502 | redelivered_later | Retry on the same route / later attempt |\n| 503 | not_delivered | Delivery problem / failed attempt |\n| 512 | repickup_later | Pickup failed; try again later |\n| 513 | not_pickuped | Pickup problem |\n| 600 | return_to_sender | Returned to shipper |\n| 700 | rejected_by_recipient | Recipient refused |\n| 403 | cancelled | Terminal cancel (distinct from 402 route cancel) |\n| 402 | route_cancelled | Route cancelled / re-plan (usually not customer-visible) |

### Zasady praktyczne dla integratorów

1. Kotwice szczęśliwej ścieżki: **100** utworzone, **300/301** w obiekcie, **450** w dostawie, **500** dostarczone; odbiór **460** i **510**.
2. Nie zakładaj stałego pełnego łańcucha — opcjonalne skany, hop-y trzecich stron (800) i zmiany strony są normalne.
3. Wyjątki (501–503, 512–513, 600, 700) mogą pojawić się po „w drodze…“; po replanowaniu znowu 450/460.
4. Ignoruj niewidoczne wiersze na stronie publicznej; webhooki i tak mogą je wysyłać. Przy korektach zawsze preferuj najnowsze id zdarzenia.

Placeholdery takie jak `{warehouse_name}` są w czasie wykonania zastępowane prawdziwą nazwą magazynu lub lokalizacji. Nowe wiersze i zmiany widoczności przychodzą migracjami; strona odczytuje tabelę przy każdym żądaniu i nie może się zestarzeć względem tego środowiska.