Webhooks de tracking

Última actualización: 2026-11-11 · Base URL: https://api.shalom-api.lat

En lugar de consultar el estado en bucle, registra tu URL y suscribe las guías que te interesan. Cuando el estado cambia, la plataforma envía un POST JSON firmado con HMAC-SHA256 (formato tipo Stripe), con reintentos automáticos y deduplicación por ID de evento. Recibes cada hito del envío: despacho, llegada a la agencia destino, salida a reparto y entrega. Tu endpoint solo tiene que validar la firma y responder 200.

PUT/webhooks

Configurar webhook

Registra la URL de webhook de la cuenta y genera un secreto de firma. El secreto se devuelve completo solo aquí. Usa rotateSecret=true para rotarlo.

ParámetroDescripción
url*URL destino (formato uri, https recomendado).
rotateSecretRegenerar el secreto de firma (boolean, default false).
{
  "url": "https://tu-servidor.com/webhooks/shalom"
}
Respuesta (ejemplo)
{
  "success": true,
  "message": "Webhook configurado.",
  "webhook": {
    "url": "https://tu-servidor.com/webhooks/shalom",
    "secret": "whsec_...",
    "enabled": true
  }
}

Nota: El secreto solo se devuelve completo en esta respuesta; en GET se muestra enmascarado.

GET/webhooks

Consultar webhook

Devuelve la configuración de webhook de la cuenta (secreto enmascarado).

curl -X GET "https://api.shalom-api.lat/webhooks" \
  -H "x-api-key: TU_API_KEY"
Respuesta (ejemplo)
{
  "success": true,
  "configured": true,
  "webhook": {
    "url": "https://tu-servidor.com/webhooks/shalom",
    "enabled": true,
    "secretPreview": "whsec_9f2b7c…"
  }
}

Nota: Si no hay webhook configurado: { success: true, configured: false, webhook: null }.

DELETE/webhooks

Eliminar webhook

Elimina la configuración de webhook de la cuenta.

curl -X DELETE "https://api.shalom-api.lat/webhooks" \
  -H "x-api-key: TU_API_KEY"
Respuesta (ejemplo)
{
  "success": true,
  "message": "Webhook eliminado."
}
GET/webhooks/deliveries

Historial de entregas del webhook

Lista las últimas entregas del webhook de la cuenta: evento, guía, estado, intentos, código de respuesta y último error. Sirve para verificar si un aviso llegó y qué contestó tu servidor.

ParámetroDescripción
pagePágina (default 1).
per_pageEntregas por página (default 20, máximo 50).
statusFiltrar por SUCCESS, FAILED o PENDING.
curl -X GET "https://api.shalom-api.lat/webhooks/deliveries?per_page=5" \
  -H "x-api-key: TU_API_KEY"
Respuesta (ejemplo)
{
  "success": true,
  "total": 38,
  "page": 1,
  "per_page": 20,
  "data": [
    {
      "event": "tracking.status_changed",
      "orderNumber": "98197156",
      "orderCode": "K9HN",
      "transition": "En tránsito/IN_TRANSIT->En destino/AT_DESTINATION",
      "status": "SUCCESS",
      "responseCode": 200,
      "attempts": 1,
      "lastError": null,
      "createdAt": "2026-10-04T14:17:00.000Z"
    }
  ]
}

Nota: No consume cuota. Si el estado es FAILED, el lastError dice qué respondió tu servidor; si es SUCCESS con 200, el evento se entregó.

POST/tracking/subscriptions

Suscribir a cambios de tracking

Suscribe la cuenta a los cambios de estado de un envío. Registra el envío en el sistema de tracking en background y notifica vía webhook cuando cambie de estado.

ParámetroDescripción
orderNumber*Número de guía (8 a 12 dígitos, patrón ^[0-9]+$).
orderCode*Código de seguridad (4 caracteres).
{
  "orderNumber": "66479331",
  "orderCode": "3KTH"
}
Respuesta (ejemplo)
{
  "success": true,
  "message": "Suscripción creada.",
  "subscription": {
    "id": "5f4e3d2c-1b0a-9988-7766-554433221100",
    "orderNumber": "66479331",
    "orderCode": "3KTH",
    "lastStatus": null,
    "lastMirrorStatus": null,
    "active": true,
    "createdAt": "2026-09-08T12:00:00.000Z"
  }
}
GET/tracking/subscriptions

Listar suscripciones

Lista las suscripciones de tracking de la cuenta.

curl -X GET "https://api.shalom-api.lat/tracking/subscriptions" \
  -H "x-api-key: TU_API_KEY"
Respuesta (ejemplo)
{
  "success": true,
  "total": 1,
  "data": [
    {
      "id": "5f4e3d2c-1b0a-9988-7766-554433221100",
      "orderNumber": "66479331",
      "orderCode": "3KTH",
      "lastStatus": "IN_TRANSIT",
      "active": true,
      "createdAt": "2026-09-08T12:00:00.000Z"
    }
  ]
}
DELETE/tracking/subscriptions

Cancelar suscripción

Cancela la suscripción de la cuenta a un envío.

ParámetroDescripción
orderNumber*Número de guía (8 a 12 dígitos, querystring).
orderCode*Código de seguridad (4 caracteres, querystring).
curl -X DELETE "https://api.shalom-api.lat/tracking/subscriptions?orderNumber=66479331&orderCode=3KTH" \
  -H "x-api-key: TU_API_KEY"
Respuesta (ejemplo)
{
  "success": true,
  "message": "Suscripción eliminada."
}

Qué resuelve un webhook

La alternativa es preguntar cada pocos segundos por cada guía. Un webhook invierte eso: registras tu URL una vez, suscribes las guías que te interesan y recibes un POST cuando algo cambia de verdad.

Es la diferencia entre enterarte de una entrega en el momento y enterarte la próxima vez que alguien consulte.

Qué estados recibes

Cada evento tracking.status_changed trae el estado tal cual lo informa Shalom en status (por ejemplo "Registrado", "En origen", "En tránsito", "En destino", "Demora de envíos" o "Entregado") y su equivalente normalizado en statusCode (UNKNOWN, REGISTERED, EN_ORIGIN, IN_TRANSIT, AT_DESTINATION, OUT_FOR_DELIVERY, DELIVERED). El estado anterior viaja en previousStatus y previousStatusCode.

statusCode es el que conviene usar para decidir flujos: status es el texto del espejo y puede cambiar de redacción si Shalom la ajusta. El payload suma statusAt (fecha del hito en ISO UTC), delayed y delayAt (si Shalom reporta demora) y mirrorMessage, que repite el texto del espejo por compatibilidad.

Una guía recién creada avisa hasta tres veces antes de moverse: Registrado (REGISTERED) → En origen (EN_ORIGIN) → En tránsito (IN_TRANSIT). Mientras se mueve se consulta cada 30 minutos; sin cambios, cada 2 horas, y esperando recojo en destino, cada 3 horas hasta que la entregan. Entre las 22:00 y las 06:00 (hora de Lima) no se consulta: un cambio de la noche se avisa desde las 06:00. Una guía con 20 días sin movimiento, o devuelta o anulada, deja de vigilarse; vuelve a suscribirla para reactivarla. Más detalle en el tema Optimizaciones del tracking.

Estados que informa Shalom

El espejo de Shalom publica estos textos (campo statuses.message); la API los replica tal cual y agrega el código normalizado. Es la lista completa de estados que puede recibir tu integración.

Registrado → statusCode REGISTERED: la guía existe en el sistema pero todavía no fue recepcionada en la agencia de origen.

En origen → statusCode EN_ORIGIN: recepcionada en la agencia de origen (Shalom la muestra como "Tu envío ha sido recepcionado").

En tránsito → statusCode IN_TRANSIT: despachada hacia la agencia destino.

En destino → statusCode AT_DESTINATION: llegó a la agencia destino y está lista para recojo.

Demora de envíos → el statusCode no cambia: es un aviso (delayed en true, con delayAt) y el hito real sigue siendo el último alcanzado.

Entregado → statusCode DELIVERED: entregada al destinatario.

Demora de envíos es el único caso donde status y el hito no coinciden: Shalom mantiene ese título incluso después de entregar la guía, así que la entrega se informa igual con statusCode DELIVERED (y delayed en true). Si Shalom no encuentra la orden, status llega en null y statusCode mantiene el último hito conocido.

Verifica siempre la firma

PUT /webhooks devuelve un secreto con el que se firma cada envío. Comprueba esa firma antes de procesar nada: sin eso, cualquiera que conozca tu URL puede inyectarte eventos falsos.

Si el secreto se filtró, vuelve a llamar a PUT /webhooks con rotateSecret en true y actualiza tu verificación.

Suscribir guías una por una

POST /tracking/subscriptions se hace por guía, con su orderNumber y su orderCode. Si tu tienda registra muchos envíos, suscribe justo después de crear cada guía, en el mismo flujo.

Responde rápido y de forma idempotente

Contesta con un 2xx en cuanto recibas y procesa el evento después. Si tu endpoint tarda o falla, el sistema reintenta, así que guarda un identificador del evento para no aplicar dos veces el mismo cambio de estado.

Cuándo seguir usando polling

Si solo necesitas el estado cuando el cliente abre la pantalla de seguimiento, una consulta puntual por API es más simple que montar un endpoint público. El webhook tiene sentido cuando algo tiene que pasar sin que nadie esté mirando.

Errores de esta sección

400URL de webhook inválida o guía mal formada.
401Falta autenticación de usuario.

Preguntas frecuentes

¿Cómo compruebo que el POST viene de Shalom API y no de un tercero?

Verificando la firma HMAC con el secreto que devuelve PUT /webhooks. Es el paso que impide que alguien inyecte eventos falsos en tu sistema.

¿Necesito HTTPS para recibir webhooks?

La URL debe ser válida y se recomienda HTTPS, porque por ahí viajan datos de tus envíos.

¿Puedo cambiar la URL del webhook?

Sí, volviendo a llamar a PUT /webhooks con la nueva url.

¿Me avisan cuando la guía llega a la agencia destino?

Sí: recibes AT_DESTINATION (status "En destino") en cuanto el espejo registra la llegada a la agencia destino, con la fecha del hito en statusAt. Antes ya te avisamos con REGISTERED ("Registrado") y EN_ORIGIN ("En origen") cuando recepcionan la guía, y si el envío es a domicilio después verás OUT_FOR_DELIVERY y DELIVERED al entregarse.

¿Qué significa status y qué statusCode en el evento?

status es el texto literal del espejo de Shalom (por ejemplo "Demora de envíos") y statusCode es su equivalente normalizado (REGISTERED, EN_ORIGIN, IN_TRANSIT, AT_DESTINATION, OUT_FOR_DELIVERY, DELIVERED). Usa statusCode para decidir flujos y status para mostrarle al cliente lo mismo que ve en Shalom. Si Shalom reporta demora, delayed llega en true sin cambiar el statusCode.

¿Cómo dejo de recibir eventos de una guía?

Con DELETE /tracking/subscriptions, enviando su orderNumber y su orderCode.

¿Qué pasa si mi servidor está caído cuando llega un evento?

El sistema reintenta. Por eso conviene responder rápido y procesar de forma idempotente, para que un reintento no duplique el efecto.

Continúa con

¿Aún no tienes API key?

Escríbenos por WhatsApp y la recibes de inmediato para probar todos estos ejemplos.

Solicitar API key