Skip to main content
POST
Estado de orden de agregador
Este endpoint es entrante — tu agregador de delivery (Rappi, Uber, Didi, iFood, PedidosYa, Glovo…) le hace POST cada vez que avanza la orden de su lado: se asignó un repartidor, la orden fue retirada, está en ruta, fue entregada, y así. Fire autentica la solicitud, correlaciona la orden, refleja el último estado en orders.aggregator, y registra el evento en su log de eventos de agregador para observabilidad.
Este endpoint es asíncrono. Fire autentica, correlaciona la orden (guards de tenant + canal), deduplica y encola el evento — luego responde 202 Accepted con un webhookEventId (típicamente en menos de 100 ms). El espejo de la orden se actualiza un instante después en un worker en segundo plano (normalmente en ~2 segundos). Para verificar el resultado, consultá GET /v1/webhooks/events/{webhookEventId}. Los problemas corregibles por el cliente (payload inválido, orden no encontrada, tenant o canal equivocado, ids en conflicto) se rechazan síncronamente con 4xx antes del 202.
El estado es passthrough. Los agregadores no comparten un vocabulario de estados, así que Fire no impone un enum: status se guarda tal cual como el tipo de evento (courier_assigned, on_route, entregue, lo que use tu canal). El estado actual de la orden es el del occurredAt más reciente — no un orden de ciclo de vida fijo. No hay compuerta anti-regresión: un timestamp posterior gana, punto. Las etiquetas amigables y traducidas son un asunto de presentación que se resuelve desde el catálogo del canal, nunca se imponen aquí.
No hay un eventId emitido por Fire para ecoar. A diferencia del callback fiscal y los estados KDS — que ecoan un event.id que Fire emitió — un estado de agregador es un evento externo espontáneo. Fire no es la fuente de verdad acá, así que no hay chequeo de fuente de verdad sobre un eventId. En cambio, vos le decís a Fire a qué orden pertenece el estado, vía resolución de la orden abajo. La idempotencia se llavea por tu providerEventId (ver Idempotencia).

Resolución de la orden

Debés decirle a Fire a qué orden pertenece este estado. Hay dos caminos, y podés enviar uno o ambos — al menos uno es requerido: Ambos son vendor-scoped: la orden correlacionada debe pertenecer a la cuenta + vendor ligados a tu API key, y su canal debe coincidir con channelCode.
Si enviás ambos ids, deben apuntar a la misma orden. Fire correlaciona cada uno de forma independiente; si orderId y externalOrderId correlacionan a órdenes distintas, la solicitud se rechaza con 409 Conflict — Fire no va a adivinar a cuál te referías. Enviá uno, o enviá ambos apuntando a la misma orden.

Autenticación

Este endpoint requiere una API key vendor-scoped con el scope webhooks:aggregator (binding de cuenta + vendor). Fire valida que la orden correlacionada pertenezca a ese vendor. Las keys sin el scope, o sin binding de vendor, se rechazan con 403 Forbidden.
string
requerido
Tu API key vendor-scoped de Fire con scope webhooks:aggregator. Generá una desde Developers → Gestión de API para la cuenta/vendor cuyas órdenes reportará esta key.
string
Bearer <token> opcional — aceptado como alternativa legacy a x-api-key. Enviá uno u otro.

Cuerpo de la solicitud

string
requerido
El código de agregador/canal — debe ser igual al metadata.channel.code de la orden (channels.code, ej. RAPPI, UBER, o el id numérico de canal como 99). Si no coincide con el canal de la orden correlacionada, Fire responde 403.
string
requerido
El estado de entrega crudo, passthrough — guardado tal cual como el tipo de evento. Se acepta cualquier string no vacío (accepted, courier_assigned, picked_up, on_route, delivered, cancelled, o las etiquetas propias de tu canal). No se impone ningún enum.
string
requerido
El id propio de tu agregador para esta entrega — la llave de idempotencia (junto con channelCode). Fire mapea (channelCode, providerEventId) a un id de evento interno estable, así que reenviar el mismo par con el mismo status es un replay seguro. Usá el id de evento nativo si lo tenés; si no, un UUID.
string
requerido
Timestamp ISO 8601 UTC de cuándo cambió el estado del lado del agregador — no cuándo se envió. Esto es lo que ordena el recorrido: el estado con el occurredAt más reciente es el estado actual de la orden.
string
UUID de la orden en Fire. Requerido si externalOrderId está ausente. Ver Resolución de la orden.
string
El id de orden externo (XMART/agregador), comparado contra el metadata.order_id de la orden. Requerido si orderId está ausente. Ver Resolución de la orden.
object
Bolsa libre opcional de campos extra (nombre del repartidor, url de tracking, etc.). Se guarda tal cual, sin validar.

Ejemplos

Los reportes de la misma entrega comparten un channelCode y correlacionan a la misma orden; cada uno lleva su propio status, providerEventId y occurredAt:
courier_assigned (por orderId de Fire)
on_route (por id de orden externo)
delivered (ambos ids — deben apuntar a la misma orden)

Respuesta

En éxito el endpoint responde 202 Accepted — el evento fue autenticado, correlacionado, deduplicado y encolado. Un 202 no significa que el espejo de la orden ya se actualizó; eso ocurre de forma asíncrona. Usá el endpoint de estado para confirmar. El body trae dos ids distintos: eventId es el id interno estable de Fire para este par (channelCode, providerEventId), webhookEventId es el id de Fire para el registro encolado. Misma forma que el callback fiscal.
boolean
Siempre true cuando la solicitud fue aceptada y encolada.
boolean
true cuando este reporte de estado exacto ya se ingresó (misma orden, mismo (channelCode, providerEventId), mismo status) — se devuelve el registro existente y no se re-encola nada. false para un reporte nuevo (incluido un status distinto de la misma entrega — eso es un paso nuevo, no un duplicado).
string
El id interno estable de Fire derivado de (channelCode, providerEventId).
string
El id de Fire para el registro encolado. Pasalo a GET /v1/webhooks/events/{webhookEventId} para consultar el resultado. En un duplicado es el mismo id que se devolvió la primera vez.
string
Estado actual en la cola — queuedprocessingprocessed (y retry / failed / dead / ignored).
string
Timestamp ISO 8601 UTC de cuándo Fire recibió por primera vez este reporte. Estable entre reintentos.
string
Resumen legible.

Verificar el resultado

Como el procesamiento es asíncrono, el 202 solo confirma que el evento fue encolado. Para ver si el espejo de la orden se actualizó, consultá el endpoint de estado con el webhookEventId que devolvió el 202:
string
Ciclo de vida de la cola: queuedprocessingprocessed (listo) · failed / dead (se rindió tras reintentos) · retry (esperando el próximo intento) · ignored (manejado, sin acción — ej. un duplicado).
number
Intentos de procesamiento hasta ahora.
object | null
En éxito, el resultado del worker — ej. { "kind": "merged", "current": "delivered" }.
object | null
{ "message": "…" } cuando el último intento falló; null si no.
Se devuelve 404 para ids desconocidos — o ids de otro tenant — sin filtrar existencia. Autenticá con la misma key webhooks:aggregator que usaste para el evento.

Idempotencia y el recorrido

Fire deduplica por la orden más (channelCode, providerEventId) y el statusno por un eventId emitido por Fire. Esto es lo que hace funcionar el recorrido manteniendo limpios los reintentos:
Un status distinto nunca es un duplicado. Como los agregadores reportan legítimamente muchos estados para una entrega, dos reportes con el mismo (channelCode, providerEventId) pero un status distinto son dos pasos distintos — Fire guarda ambos. Mantené providerEventId único por reporte de estado para no reproducir un paso por accidente.

El espejo de la orden

Una vez procesado, el último estado se refleja en el bloque aggregator de la orden, con el recorrido completo guardado en history (ordenado por occurredAt). El status actual es la entrada con el occurredAt más reciente:
orders.aggregator
El estado crudo se guarda tal cual; cualquier etiqueta amigable y traducida se resuelve al momento de mostrar desde el catálogo de estados del canal — el valor guardado nunca cambia.

Relacionado

Inyectar orden

El endpoint de inyección que crea la orden que este estado referencia.

Estado de orden KDS

El webhook entrante hermano para el estado de cocina — mismo modelo async + cola, pero con eventId emitido por Fire y anti-regresión.

Callback fiscal

El webhook entrante fiscal — mismo envelope async + idempotencia.

Autenticación

Cómo funcionan las API keys, scopes y el binding de vendor.