# Tracking-eventcodes

Live gegenereerd op https://api.superlabel.ca/api/documentation/tracking-events?lang=nl uit de gedeployde `tracking`-woordenboektabel (welke statuscodes bestaan en of klanten ze zien), TrackingEvent-sleutels en de gelokaliseerde `tracking.*`-beschrijvingsteksten. Altijd actueel met de database van deze omgeving.

## Eventzijde, niet ordertype

Dit woordenboek is **geen** ordertype-lijst. Dezelfde order kan zowel ophaal- als leveringszijde-events produceren — bijvoorbeeld een levering met ophaalstop, peer-to-peer (twee etappes), multi-leg transfer of magazijnoverhandiging. Instant Deliver gebruikt een apart woordenboek (hier niet vermeld). Elk tracking-event krijgt een **zijde** (ophalen of leveren) die beschrijving en zichtbaarheid voor die status kiest. De numerieke `status_id` en stabiele `key` komen overeen met `tracking_event_status_id` / `tracking_event_key` in API- en webhook-payloads; vertak op die velden (en de zijde als de tekst telt), nooit op ordertype en nooit op de gelokaliseerde beschrijvingstekst.

## Zichtbaarheid voor de klant (`tracking.visible`)

De openbare trackingpagina en de openbare tracking-API tonen alleen events waarvan de woordenboekrij `tracking.visible = 1` heeft, gekoppeld op statuscode **en** eventzijde (dezelfde zijde als op het tracking-event). Statussen gemarkeerd met **Nee** bestaan nog in het systeem (webhooks, operatiegeschiedenis, interne tools) maar zijn verborgen op de klantgerichte tijdlijn. Zichtbaarheid wordt live gelezen uit de `tracking`-tabel van deze installatie.

## Events aan de leveringszijde

Statussen wanneer een tracking-event aan de **leveringszijde** van de reis ligt (aflevering / last mile). Geldt voor pure leveringsorders, de leveringsetappe van peer-to-peer, levering met ophalen, multi-leg en vergelijkbare stromen — **niet alleen** „pure leveringsorders”. **Klantzichtbaar** is `tracking.visible` voor die status aan deze zijde.

| status_id | key | otep | otep phase | klantzichtbaar | description |
|---|---|---|---|---|---|
| 100 | `information_submitted` | `information_submitted` | `pre_shipment` | Ja | Uw verzendinformatie is ingediend. |
| 110 | `booking_confirmed` | `booking_confirmed` | `pre_shipment` | Ja | Uw zending is bevestigd. |
| 120 | `awaiting_pickup` | `awaiting_pickup` | `pre_shipment` | Ja | Uw pakket wacht op afhaling. |
| 200 | `pushed_successful` | — | — | Nee | Uw order is verzonden voor routeplanning. |
| 201 | `pushed_failed` | — | — | Nee | Uw order kon niet worden verzonden voor routeplanning. Er wordt opnieuw geprobeerd of herpland. |
| 300 | `received` | `received` | `inbound` | Ja | Uw pakket is veilig aangekomen bij {warehouse_name}. |
| 301 | `arrival_scan` | `arrival_scan` | `inbound` | Ja | Uw pakket is opgehaald en afgeleverd bij {warehouse_name}. |
| 400 | `planned` | `in_transit` | `transit` | Nee | Uw pakket is geladen en klaar voor bezorging. |
| 401 | `removed_from_route` | `removed_from_route` | `exception` | Nee | Uw bezorgplan wordt opnieuw ingepland, wacht op een update. |
| 402 | `route_cancelled` | `route_cancelled` | `exception` | Nee | Uw bezorgstatus wordt bijgewerkt, even geduld. |
| 430 | `in_transit` | `in_transit` | `transit` | Ja | Uw pakket is onderweg. |
| 431 | `on_hold` | `in_transit` | `transit` | Ja | Uw pakket is tijdelijk aangehouden. We informeren u binnenkort. |
| 432 | `customs_clearance` | `in_transit` | `transit` | Ja | Uw pakket wordt ingeklaard bij de douane. |
| 433 | `loaded` | `package_outbound` | `transit` | Ja | Uw pakket is geladen en vertrekt binnenkort. |
| 434 | `collection_on_hold` | `awaiting_pickup` | `pre_shipment` | Ja | Het ophalen van uw pakket is tijdelijk uitgesteld. We informeren u binnenkort. |
| 435 | `facility_received` | `in_transit` | `transit` | Ja | Uw pakket is ontvangen door het fulfilmentcentrum. |
| 436 | `arrived_at_facility` | `in_transit` | `transit` | Ja | Uw pakket is aangekomen bij een fulfilmentcentrum. |
| 450 | `start_delivery` | `out_for_delivery` | `out_for_delivery` | Ja | Uw pakket is onderweg voor bezorging. |
| 470 | `at_device` | `awaiting_pickup` | `pre_shipment` | Ja | Uw pakket ligt voor u klaar in een pakketautomaat. |
| 471 | `device_picked_up` | `delivered` | `delivered` | Ja | Uw pakket is opgehaald uit de pakketautomaat. |
| 472 | `device_expired` | `awaiting_pickup` | `pre_shipment` | Ja | Uw pakket is niet vóór de uiterste datum opgehaald en ligt nog in de pakketautomaat. |
| 473 | `device_removed` | `received` | `inbound` | Ja | Uw pakket is door medewerkers uit de pakketautomaat gehaald. |
| 500 | `deliver_success` | `delivered` | `delivered` | Ja | Uw pakket is succesvol afgeleverd, bedankt voor uw gebruik! |
| 501 | `need_rescheduled` | `delivery_rescheduled` | `exception` | Ja | Het spijt ons, we konden uw pakket niet bezorgen. |
| 502 | `redelivered_later` | `delivery_rescheduled` | `exception` | Ja | Het spijt ons, we konden uw pakket niet bezorgen. |
| 503 | `not_delivered` | `delivery_failed` | `exception` | Ja | Er is een probleem opgetreden tijdens de bezorging, neem contact op met de klantenservice. |
| 504 | `partial_deliver_success` | — | — | Ja | Dit pakket is bezorgd. De overige pakketten van uw zending zijn nog onderweg. |
| 510 | `pickuped` | `picked_up` | `pickup` | Ja | Het pakket is succesvol opgehaald door onze koerier. |
| 800 | `package_outbound` | `package_outbound` | `transit` | Ja | Uw pakket is vertrokken uit {warehouse_name}. |

## Events aan de ophaalzijde

Statussen wanneer een tracking-event aan de **ophaalzijde** van de reis ligt (ophalen-etappe). Geldt voor pure ophaalorders, de ophaaletappe van peer-to-peer, levering met ophalen, multi-leg en vergelijkbare stromen — **niet alleen** „pure ophaalorders”. **Klantzichtbaar** is `tracking.visible` voor die status aan deze zijde.

| status_id | key | otep | otep phase | klantzichtbaar | description |
|---|---|---|---|---|---|
| 100 | `information_submitted` | `information_submitted` | `pre_shipment` | Ja | Uw verzendverzoek is succesvol ingediend. |
| 110 | `booking_confirmed` | `booking_confirmed` | `pre_shipment` | Ja | Uw afhaalverzoek is bevestigd. |
| 120 | `awaiting_pickup` | `awaiting_pickup` | `pre_shipment` | Ja | Uw pakket wacht op afhaling. |
| 200 | `pushed_successful` | — | — | Nee | Uw ophaalorder is verzonden voor routeplanning. |
| 201 | `pushed_failed` | — | — | Nee | Uw ophaalorder kon niet worden verzonden voor routeplanning. Er wordt opnieuw geprobeerd of herpland. |
| 300 | `received` | `received` | `inbound` | Ja | Uw pakket is succesvol opgeslagen. |
| 301 | `arrival_scan` | `arrival_scan` | `inbound` | Ja | Order a-scan |
| 400 | `planned` | `in_transit` | `transit` | Nee | Uw pakket wordt verwerkt. |
| 401 | `removed_from_route` | `removed_from_route` | `exception` | Nee | Uw ophaalplan wordt opnieuw ingepland, wacht op bericht. |
| 402 | `route_cancelled` | `route_cancelled` | `exception` | Nee | Uw ophaalstatus wordt bijgewerkt, even geduld. |
| 430 | `in_transit` | `in_transit` | `transit` | Ja | Uw pakket is onderweg. |
| 431 | `on_hold` | `in_transit` | `transit` | Ja | Uw pakket is tijdelijk aangehouden. We informeren u binnenkort. |
| 432 | `customs_clearance` | `in_transit` | `transit` | Ja | Uw pakket wordt ingeklaard bij de douane. |
| 433 | `loaded` | `package_outbound` | `transit` | Ja | Uw pakket is geladen en vertrekt binnenkort. |
| 434 | `collection_on_hold` | `awaiting_pickup` | `pre_shipment` | Ja | Het ophalen van uw pakket is tijdelijk uitgesteld. We informeren u binnenkort. |
| 435 | `facility_received` | `in_transit` | `transit` | Ja | Uw pakket is ontvangen door het fulfilmentcentrum. |
| 436 | `arrived_at_facility` | `in_transit` | `transit` | Ja | Uw pakket is aangekomen bij een fulfilmentcentrum. |
| 450 | `start_delivery` | `out_for_delivery` | `out_for_delivery` | Ja | De koerier is onderweg om het pakket op te halen, bereid uw pakket voor. |
| 470 | `at_device` | `awaiting_pickup` | `pre_shipment` | Ja | Uw pakket ligt voor u klaar in een pakketautomaat. |
| 471 | `device_picked_up` | `delivered` | `delivered` | Ja | Uw pakket is opgehaald uit de pakketautomaat. |
| 472 | `device_expired` | `awaiting_pickup` | `pre_shipment` | Ja | Uw pakket is niet vóór de uiterste datum opgehaald en ligt nog in de pakketautomaat. |
| 473 | `device_removed` | `received` | `inbound` | Ja | Uw pakket is door medewerkers uit de pakketautomaat gehaald. |
| 500 | `deliver_success` | `delivered` | `delivered` | Ja | Uw pakket is succesvol opgehaald. |
| 501 | `need_rescheduled` | `delivery_rescheduled` | `exception` | Ja | Uw ophaling is opnieuw ingepland, we informeren u later over de nieuwe ophaaltijd. |
| 502 | `redelivered_later` | `delivery_rescheduled` | `exception` | Ja | Uw ophaling is opnieuw ingepland, we informeren u later over de nieuwe ophaaltijd. |
| 503 | `not_delivered` | `delivery_failed` | `exception` | Ja | Er is een probleem met uw pakket, neem contact op met de klantenservice. |
| 504 | `partial_deliver_success` | — | — | Ja | Dit pakket is opgehaald. De overige pakketten van uw zending worden binnenkort opgehaald. |
| 510 | `pickuped` | `picked_up` | `pickup` | Ja | Uw pakket is succesvol opgehaald. |
| 800 | `package_outbound` | `package_outbound` | `transit` | Ja | Uw pakket is vertrokken uit {warehouse_name}. |

De kolommen **otep** / **otep phase** worden live gegenereerd uit `OTEPStatusInput::FROM_TRACKING_EVENT` en `PHASES` — dezelfde brug die de openbare tracking-API als `otep_status` op elk event zet. Een streepje (—) betekent: geen OTEP-code in het parcel-profiel (bijv. routing-push 200/201); het event wordt wel opgeslagen en kan klantzichtbaar zijn bij `visible = 1`.

## Bouw je eigen trackingpagina

Gebruik de **openbare tracking-API** voor een pagina in jouw huisstijl op site of app — zonder login of token. Hetzelfde endpoint voedt de ingebouwde trackingpagina en de GraphQL-operatie `trackingPublic`. Combineer hem met het statuswoordenboek op deze pagina en de stromen hieronder.

### 1. Roep het openbare endpoint aan

Eén GET per trackingnummer. Zoekt op Superroute-nummers, externe nummers en sommige third-party-nummers zonder provider-id.

```
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. Kies de taal van beschrijvingen

`description`-teksten volgen de request-locale via `Accept-Language`. Stuur een projecttaalcode (`en`, `chs`, `nl`, …) of een alias zoals `zh-CN`. Zonder header geldt de standaardtaal.

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

### 3. Responsevelden om te tonen

Alleen het openbare oppervlak wordt teruggegeven — volledige afzender-/ontvangeradressen **niet** (alleen op het geauthenticeerde interne endpoint).

| 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. Aanbevolen UI-stroom

1. Vraag het nummer aan de bezoeker en roep de openbare GET aan (optioneel met `Accept-Language`).
2. Als `result` false is of HTTP 404, toon niet gevonden en stop.
3. Gebruik `data[0]` (nieuwste event) voor de kopstatus: tekst via `description`; iconen/voortgang via `tracking_event_status_id` of `otep_status`.
4. Render de volledige `data`-lijst als tijdlijn (al nieuwste eerst). Verzin geen ontbrekende stappen.
5. Als `proofs` niet leeg is en de laatste status een succes is (vaak 500 of 510), bied “bewijs tonen”; `signed_url` voor tijdelijke links, `full_url` voor het permanente pad.

### 5. Voortgangsbalken

Hardcode **geen** vaste keten voor elk pakket. Gebruik het woordenboek en de stromen op deze pagina. Vertak op `otep_status` of `tracking_event_status_id`; het nieuwste event is leidend.

### 6. Afleverbewijs

`proofs[]` bevat foto-/handtekeningmetadata wanneer beschikbaar. Je pagina mag nog steeds postcode vragen vóór weergave; de API levert een genormaliseerd `postcode`-veld. Zet geen volledige straatadressen op een volledig openbare pagina.

### 7. Gerelateerde openbare oppervlakken

Kies wat bij je stack past. Alle zijn openbaar (geen token) tenzij de API-docs anders zeggen.

| 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. Minimale voorbeelden

```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
}
```

## Veelvoorkomende tracking-stromen

Dit zijn **typische reeksen**, geen harde toestandsmachine. Echte tijdlijnen slaan stappen over, voegen uitzonderingen toe of wisselen ophaal- en leveringszijde-events op dezelfde order. Getallen zijn `tracking_event_status_id`; openbare tijdlijnen tonen alleen rijen met `tracking.visible = 1`. Vertak op `status_id` / `key` en beschouw het nieuwste event (hoogste id) als leidend.

### Magazijn → last-mile levering

Meest voorkomende eigen-vlootpad: order aangemaakt, pakket ontvangen, chauffeur start levering, dan succes of uitzondering. Planningscodes 400/401/402 bestaan vaak maar zijn **niet** klantzichtbaar.

```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
```

### Ophalen / pure ophaaletappe

Chauffeur gaat ophalen en registreert succes (POD mogelijk) of ophaaluitzondering. Pure ophaalorders blijven ophaalzijdig; dual-leg gaat na 510 naar leveringszijde.

```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
```

### Dubbele etappe (eerst ophalen, dan leveren)

Wanneer één rit zowel ophalen als afleveren heeft — levering met ophalen, peer-to-peer, veel multi-leg. De tijdlijn toont typisch eerst **ophaalzijde**-mijlpalen (460 → 510), daarna **leveringszijde** (450 → 500). Eventzijde kiest de beschrijving, niet het ordertype.

```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"]
```

### Derde partij / carrier-fulfilment

Carrier-boeking kan 110/120 geven; productbeleid houdt die **verborgen** op de openbare tijdlijn. Gedeelde zichtbare mijlpalen volgen magazijn + last mile (300/301 → 800 → 450 → 500). Terminale carrier-annulering gebruikt 403 (niet 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 (taakdispatch)

Eigen woordenboek (niet in de tabellen hierboven). Happy path: ingediend → koerier toegewezen → onderweg naar ophalen → opgehaald → in levering → geleverd. 411/412 kunnen vóór start lussen; 501 na mislukte poging.

```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"]
```

### Uitzonderings- en eindcodes (sneloverzicht)

| 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) |

### Vuistregels voor integrators

1. Happy-path ankers: **100** aangemaakt, **300/301** in faciliteit, **450** onderweg, **500** geleverd; ophalen **460** en **510**.
2. Ga niet uit van een vaste volledige keten — optionele scans, third-party hops (800) en zijdewisselingen zijn normaal.
3. Uitzonderingen (501–503, 512–513, 600, 700) kunnen na «onderweg…» komen; na herplannen opnieuw 450/460.
4. Negeer niet-zichtbare woordenboekrijen op de openbare pagina; webhooks kunnen ze nog sturen. Gebruik altijd de nieuwste event-id bij correcties.

Plaatshouders zoals `{warehouse_name}` worden runtime vervangen door de echte magazijn- of locatienaam. Nieuwe rijen en zichtbaarheidswijzigingen komen via migraties; de pagina leest de tabel bij elk verzoek opnieuw en kan niet verouderen t.o.v. deze omgeving.