# Códigos de eventos de seguimiento

Generado en vivo en https://api.superlabel.ca/api/documentation/tracking-events?lang=es a partir de la tabla de diccionario `tracking` desplegada (qué códigos de estado existen y si los clientes los ven), las claves de TrackingEvent y las cadenas localizadas de descripción `tracking.*`. Siempre al día con la base de datos de este entorno.

## Lado del evento, no tipo de pedido

Este diccionario **no** es una lista de tipos de pedido. Un mismo pedido puede emitir eventos del lado recogida y del lado entrega — por ejemplo una entrega con parada de recogida, peer-to-peer (dos tramos), transferencia multi-tramo o traspasos de almacén. Instant Deliver usa un diccionario aparte (no listado aquí). Cada evento de seguimiento lleva un **lado** (recogida o entrega) que elige la descripción y la visibilidad de ese estado. El `status_id` numérico y la `key` estable coinciden con `tracking_event_status_id` / `tracking_event_key` en las cargas de API y webhooks; ramifique sobre esos campos (y el lado si importa el texto), nunca sobre el tipo de pedido ni sobre el texto localizado de la descripción.

## Visibilidad para el cliente (`tracking.visible`)

La página pública de seguimiento y la API pública de seguimiento solo muestran eventos cuya fila de diccionario tiene `tracking.visible = 1`, enlazados por código de estado **y** lado del evento (el mismo lado marcado en el evento). Los estados marcados **No** siguen existiendo en el sistema (webhooks, historial de operaciones, herramientas internas) pero se ocultan de la línea de tiempo orientada al cliente. La visibilidad se lee en vivo de la tabla `tracking` de este despliegue.

## Eventos del lado entrega

Estados usados cuando un evento de seguimiento está en el **lado entrega** del trayecto (entrega / última milla). Aplica a pedidos solo entrega, el tramo de entrega de peer-to-peer, entrega con recogida, multi-tramo y flujos similares — **no solo** a «pedidos solo entrega». **Visible al cliente** es `tracking.visible` de ese estado en este lado.

| status_id | key | otep | otep phase | visible al cliente | description |
|---|---|---|---|---|---|
| 100 | `information_submitted` | `information_submitted` | `pre_shipment` | Sí | Tu información de envío ha sido enviada. |
| 110 | `booking_confirmed` | `booking_confirmed` | `pre_shipment` | Sí | Tu envío ha sido confirmado. |
| 120 | `awaiting_pickup` | `awaiting_pickup` | `pre_shipment` | Sí | Tu paquete está pendiente de recogida. |
| 200 | `pushed_successful` | — | — | No | Su pedido se ha enviado a la planificación de rutas. |
| 201 | `pushed_failed` | — | — | No | No se pudo enviar su pedido a la planificación de rutas. Se reintentará o se replanificará. |
| 300 | `received` | `received` | `inbound` | Sí | Tu paquete ha llegado con éxito a {warehouse_name}. |
| 301 | `arrival_scan` | `arrival_scan` | `inbound` | Sí | Tu paquete ha sido recogido y ha llegado a {warehouse_name}. |
| 400 | `planned` | `in_transit` | `transit` | No | Tu paquete está cargado y listo para ser entregado. |
| 401 | `removed_from_route` | `removed_from_route` | `exception` | No | Tu entrega será reprogramada pronto; por favor espera la actualización. |
| 402 | `route_cancelled` | `route_cancelled` | `exception` | No | El estado de tu entrega se actualizará en breve. |
| 430 | `in_transit` | `in_transit` | `transit` | Sí | Su paquete está en tránsito. |
| 431 | `on_hold` | `in_transit` | `transit` | Sí | Su paquete está temporalmente retenido. Le informaremos en breve. |
| 432 | `customs_clearance` | `in_transit` | `transit` | Sí | Su paquete está en proceso de despacho aduanero. |
| 433 | `loaded` | `package_outbound` | `transit` | Sí | Su paquete ha sido cargado y saldrá en breve. |
| 434 | `collection_on_hold` | `awaiting_pickup` | `pre_shipment` | Sí | La recogida de su paquete está temporalmente en espera. Le informaremos en breve. |
| 435 | `facility_received` | `in_transit` | `transit` | Sí | Su paquete ha sido recibido por el centro logístico. |
| 436 | `arrived_at_facility` | `in_transit` | `transit` | Sí | Su paquete ha llegado a un centro logístico. |
| 450 | `start_delivery` | `out_for_delivery` | `out_for_delivery` | Sí | Tu paquete está actualmente en camino para la entrega. |
| 470 | `at_device` | `awaiting_pickup` | `pre_shipment` | Sí | Su paquete le espera en una taquilla automática. |
| 471 | `device_picked_up` | `delivered` | `delivered` | Sí | Su paquete ha sido retirado de la taquilla automática. |
| 472 | `device_expired` | `awaiting_pickup` | `pre_shipment` | Sí | Su paquete no se retiró antes de la fecha límite y sigue en la taquilla automática. |
| 473 | `device_removed` | `received` | `inbound` | Sí | El personal ha sacado su paquete de la taquilla automática. |
| 500 | `deliver_success` | `delivered` | `delivered` | Sí | Tu paquete ha sido entregado con éxito. ¡Gracias! |
| 501 | `need_rescheduled` | `delivery_rescheduled` | `exception` | Sí | Lamentablemente, no pudimos entregar tu paquete. |
| 502 | `redelivered_later` | `delivery_rescheduled` | `exception` | Sí | Lamentablemente, no pudimos entregar tu paquete. |
| 503 | `not_delivered` | `delivery_failed` | `exception` | Sí | Hemos encontrado un problema con tu entrega. Por favor, contacta a nuestro equipo de soporte. |
| 504 | `partial_deliver_success` | — | — | Sí | Este paquete ha sido entregado. El resto de los paquetes de su envío sigue en camino. |
| 510 | `pickuped` | `picked_up` | `pickup` | Sí | El paquete ha sido recogido exitosamente por nuestro mensajero. |
| 800 | `package_outbound` | `package_outbound` | `transit` | Sí | Su paquete ha salido de {warehouse_name}. |

## Eventos del lado recogida

Estados usados cuando un evento de seguimiento está en el **lado recogida** del trayecto (tramo de recogida). Aplica a pedidos solo recogida, el tramo de recogida de peer-to-peer, entrega con recogida, multi-tramo y flujos similares — **no solo** a «pedidos solo recogida». **Visible al cliente** es `tracking.visible` de ese estado en este lado.

| status_id | key | otep | otep phase | visible al cliente | description |
|---|---|---|---|---|---|
| 100 | `information_submitted` | `information_submitted` | `pre_shipment` | Sí | Hemos recibido con éxito tu solicitud de recogida del paquete. |
| 110 | `booking_confirmed` | `booking_confirmed` | `pre_shipment` | Sí | Tu solicitud de recogida ha sido confirmada. |
| 120 | `awaiting_pickup` | `awaiting_pickup` | `pre_shipment` | Sí | Tu paquete está pendiente de recogida. |
| 200 | `pushed_successful` | — | — | No | Su pedido de recogida se ha enviado a la planificación de rutas. |
| 201 | `pushed_failed` | — | — | No | No se pudo enviar su pedido de recogida a la planificación de rutas. Se reintentará o se replanificará. |
| 300 | `received` | `received` | `inbound` | Sí | Hemos recibido tu paquete en nuestras instalaciones. |
| 301 | `arrival_scan` | `arrival_scan` | `inbound` | Sí | Order a-scan |
| 400 | `planned` | `in_transit` | `transit` | No | Tu paquete está siendo procesado actualmente. |
| 401 | `removed_from_route` | `removed_from_route` | `exception` | No | La recogida de tu paquete será reprogramada pronto. |
| 402 | `route_cancelled` | `route_cancelled` | `exception` | No | El estado de la recogida de tu paquete se actualizará en breve. |
| 430 | `in_transit` | `in_transit` | `transit` | Sí | Su paquete está en tránsito. |
| 431 | `on_hold` | `in_transit` | `transit` | Sí | Su paquete está temporalmente retenido. Le informaremos en breve. |
| 432 | `customs_clearance` | `in_transit` | `transit` | Sí | Su paquete está en proceso de despacho aduanero. |
| 433 | `loaded` | `package_outbound` | `transit` | Sí | Su paquete ha sido cargado y saldrá en breve. |
| 434 | `collection_on_hold` | `awaiting_pickup` | `pre_shipment` | Sí | La recogida de su paquete está temporalmente en espera. Le informaremos en breve. |
| 435 | `facility_received` | `in_transit` | `transit` | Sí | Su paquete ha sido recibido por el centro logístico. |
| 436 | `arrived_at_facility` | `in_transit` | `transit` | Sí | Su paquete ha llegado a un centro logístico. |
| 450 | `start_delivery` | `out_for_delivery` | `out_for_delivery` | Sí | Un mensajero está en camino para recoger tu paquete. |
| 470 | `at_device` | `awaiting_pickup` | `pre_shipment` | Sí | Su paquete le espera en una taquilla automática. |
| 471 | `device_picked_up` | `delivered` | `delivered` | Sí | Su paquete ha sido retirado de la taquilla automática. |
| 472 | `device_expired` | `awaiting_pickup` | `pre_shipment` | Sí | Su paquete no se retiró antes de la fecha límite y sigue en la taquilla automática. |
| 473 | `device_removed` | `received` | `inbound` | Sí | El personal ha sacado su paquete de la taquilla automática. |
| 500 | `deliver_success` | `delivered` | `delivered` | Sí | Tu paquete ha sido recogido exitosamente. |
| 501 | `need_rescheduled` | `delivery_rescheduled` | `exception` | Sí | La recogida del paquete ha sido reprogramada. Te informaremos pronto del nuevo horario. |
| 502 | `redelivered_later` | `delivery_rescheduled` | `exception` | Sí | La recogida del paquete ha sido reprogramada. Te informaremos pronto del nuevo horario. |
| 503 | `not_delivered` | `delivery_failed` | `exception` | Sí | Hemos encontrado un problema con tu paquete. Por favor, contacta a nuestro equipo de soporte. |
| 504 | `partial_deliver_success` | — | — | Sí | Este paquete ha sido recogido. El resto de los paquetes de su envío se recogerá en breve. |
| 510 | `pickuped` | `picked_up` | `pickup` | Sí | Tu paquete ha sido recogido exitosamente. |
| 800 | `package_outbound` | `package_outbound` | `transit` | Sí | Su paquete ha salido de {warehouse_name}. |

Las columnas **otep** / **otep phase** se generan en vivo desde `OTEPStatusInput::FROM_TRACKING_EVENT` y `PHASES` — el mismo puente que la API pública de seguimiento escribe como `otep_status` en cada evento. Un guion (—) significa que este estado interno no tiene código OTEP en el perfil parcel (p. ej. push de enrutado 200/201); el evento se guarda igual y puede ser visible al cliente si `visible = 1`.

## Crear tu propia página de seguimiento

Usa la **API pública de seguimiento** para una página con tu marca en tu sitio o app — sin inicio de sesión ni token. El mismo endpoint alimenta la página integrada y la operación GraphQL `trackingPublic`. Combínalo con el diccionario de estados de esta página y los patrones de flujo de abajo.

### 1. Llamar al endpoint público

Un GET por número de seguimiento. Busca números Superroute, externos y algunos de terceros sin id de proveedor.

```
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. Elegir el idioma de las descripciones

Las cadenas `description` siguen la configuración regional del request mediante `Accept-Language`. Envía un código del proyecto (`en`, `chs`, `es`, …) o un alias como `zh-CN`. Si falta, se usa el idioma predeterminado.

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

### 3. Campos de respuesta a mostrar

Solo se devuelve la superficie pública — las direcciones completas de remitente/destinatario **no** se incluyen (solo en el endpoint interno autenticado).

| 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. Flujo de UI recomendado

1. Recoge el número del visitante y llama al GET público (opcionalmente con `Accept-Language`).
2. Si `result` es false o HTTP es 404, muestra no encontrado y detente.
3. Usa `data[0]` (evento más reciente) para el estado principal: texto con `description`; iconos/progreso con `tracking_event_status_id` u `otep_status`.
4. Renderiza la lista completa `data` como línea de tiempo (ya de más reciente a más antiguo). No inventes pasos que no existan.
5. Si `proofs` no está vacío y el último estado es de éxito (típicamente 500 o 510), ofrece ver la prueba; `signed_url` para enlaces con caducidad, `full_url` para la ruta permanente.

### 5. Indicadores de progreso

**No** codifiques una sola cadena para todos los envíos. Usa el diccionario y los flujos de esta página. Bifurca por `otep_status` o `tracking_event_status_id`; el evento más reciente es la autoridad.

### 6. Prueba de entrega

`proofs[]` lleva metadatos de foto/firma cuando existen. Puedes exigir el código postal antes de mostrarlos; la API devuelve `postcode` normalizado. No pongas direcciones calle completas en una página totalmente pública.

### 7. Superficies públicas relacionadas

Elige la que encaje con tu stack. Todas son públicas (sin token) salvo que la documentación indique lo contrario.

| 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. Ejemplos mínimos

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

## Patrones comunes de flujo de seguimiento

Son **secuencias típicas**, no una máquina de estados rígida. Las líneas de tiempo reales omiten pasos, insertan excepciones o intercalan eventos de recogida y entrega en el mismo pedido. Los números son `tracking_event_status_id`; la línea pública solo muestra filas con `tracking.visible = 1`. Ramifique por `status_id` / `key` y tome el evento más reciente (id más alto) como autoritativo.

### Almacén → entrega de última milla

Ruta propia más común: pedido creado, paquete recibido en instalación, conductor en ruta de entrega, luego éxito o excepción. Códigos de planificación 400/401/402 suelen existir pero **no** son visibles al cliente.

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

### Recogida / tramo solo recogida

El conductor sale a recoger y registra éxito (con POD posible) o excepción de recogida. Los pedidos solo recogida permanecen en el lado recogida; los de dos tramos continúan al lado entrega tras 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
```

### Viajes de dos tramos (recoger y luego entregar)

Cuando un viaje tiene recogida y entrega — entrega con recogida, peer-to-peer, muchos multi-tramo. La línea de tiempo suele mostrar hitos del **lado recogida** primero (460 → 510), luego del **lado entrega** (450 → 500). El lado del evento elige la descripción, no el tipo de pedido.

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

### Cumplimiento de terceros / transportista

La reserva del transportista puede emitir 110/120; la política de producto los mantiene **ocultos** en la línea pública. Los hitos visibles compartidos coinciden con almacén + última milla (300/301 → 800 → 450 → 500). La cancelación terminal usa 403 (no 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 (despacho por tareas)

Diccionario propio (no en las tablas de arriba). Camino feliz: enviado → mensajero asignado → hacia recogida → recogido → en entrega → entregado. 411/412 pueden ciclar antes de salir; 501 tras un intento fallido.

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

### Códigos de excepción y terminales (mapa rápido)

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

### Reglas prácticas para integradores

1. Anclas del camino feliz: **100** creado, **300/301** en instalación, **450** en entrega, **500** entregado; en recogida **460** y **510**.
2. No asuma una cadena fija completa: escaneos opcionales, saltos de terceros (800) y cambios de lado son normales.
3. Las excepciones (501–503, 512–513, 600, 700) pueden seguir a un código «en ruta…»; el pedido puede volver a 450/460 tras replanificar.
4. Ignore filas no visibles en la página pública; webhooks e internos pueden recibirlas. Prefiera siempre el id de evento más reciente al corregir.

Marcadores como `{warehouse_name}` se sustituyen en tiempo de ejecución por el nombre real del almacén o ubicación. Las filas nuevas y los cambios de visibilidad se publican por migraciones; la página relee la tabla en cada solicitud y no puede quedar obsoleta respecto a este entorno.