Motify Developers Sandbox · api.motify.illari.ai

El canal en tiempo real (MQTT)

Motify tiene dos rieles: HTTP manda, MQTT avisa. Todo lo que cambia en vivo — ofertas, estados de carrera, GPS del conductor, estados de verificación — llega por push sobre MQTT (AWS IoT Core, WebSocket con TLS). Esta guía cubre cómo conectarte, con qué credencial, qué puedes ver según tu rol, y cómo manejar el ciclo de vida de la conexión — incluida la renovación de sesión.

Conexión

El broker exige pasar por el custom authorizer en cada conexión — no existen conexiones anónimas. La credencial viaja en la URL del WebSocket:

wss://a3p5h9845pzkuc-ats.iot.us-east-1.amazonaws.com/mqtt
    ?x-amz-customauthorizer-name=motify-auth
    &token=<credencial>

// mqtt.js (web) — en Flutter (mqtt_client) el esquema es idéntico
const client = mqtt.connect(url, {
  clientId: "pax-<userId>",   // OBLIGATORIO: la policy solo permite TU clientId
  reconnectPeriod: 0,           // maneja la reconexión tú (ver ciclo de vida)
});
El clientId no es decorativo: la policy emitida por el authorizer solo autoriza el clientId de tu clase (pax-{userId}, drv-{userId}, stf-{id} con sufijo opcional para varias pestañas, vfy-{sessionId}). Conectar con otro id = rechazo. Y si dos clientes usan el MISMO clientId, el broker patea al primero — por eso cada sesión/pestaña debe tener el suyo.

Credenciales — quién se conecta con qué

ClaseCredencial (token)clientIdCuándo
Sesión de verificaciónverify.<sessionId> (el secreto de la sesión ES la credencial)vfy-{sessionId}Pre-autenticación: esperar el estado del flujo de identidad por push
PasajeroJWT Motify (en dev: dev-token dev.passenger.{id})pax-{userId}Toda la sesión de la app
ConductorJWT Motify (dev: dev.driver.{id})drv-{userId}Mientras está en turno
Staff (console)JWT Motify (dev: dev.staff.{id})stf-{id} o stf-{id}-*Monitoreo del backoffice
Estado en dev: el authorizer del sandbox valida dev-tokens y credenciales verify.*; el cambio a validación del JWT Motify (mismo JWKS que HTTP) es un swap del validador ya previsto — las policies y este contrato no cambian.

Permisos por clase (lo que el broker te deja hacer)

ClasePublicaEscucha
Verificaciónnadamotify/verify/{sessionId} (solo el suyo)
Pasajeronada (solo observa)motify/pax/{userId}/inbox · motify/ride/+/loc · motify/ride/+/events
Conductormotify/drv/{userId}/geo (posición gruesa) · motify/ride/+/loc (GPS en viaje)motify/drv/{userId}/inbox · motify/ride/+/events
Staffnada (solo observa)motify/drv/+/geo · motify/drv/+/inbox · motify/ride/+/loc · motify/ride/+/events
Los comodines de ride/+ son una limitación aceptada del MVP (documentada en el ADR-0002) con plan comprometido: cuando el refresh de policy consulte la carrera activa, se acotará al rideId exacto. La identidad del PUBLICADOR nunca depende del payload: la posición gruesa se escribe con clientId() del broker — un conductor no puede publicar por otro.

Ciclo de vida de la conexión (y la renovación de sesión)

flowchart LR A[Conectar
credencial vigente] --> B[Suscribirse a tus topics] B --> C[Recibir push] C -->|cada 15 min| D{Authorizer re-evalúa
la MISMA credencial} D -->|vigente| C D -->|vencida| E[Broker desconecta] E --> F[Renovar credencial
passkey login → JWT nuevo] F --> G[Reconectar con backoff + jitter] G --> H[Resuscribir + reconciliar por HTTP
GET /rides/active · GET /rides/id] H --> C
ReglaDetalle
Vida máxima24 h por conexión; la policy se re-evalúa cada 15 min con la credencial presentada al conectar — un JWT de 1 h vencerá y el broker te desconectará: es lo esperado.
RenovaciónAl desconectar: renueva el JWT (login con passkey, en silencio) y reconecta. La desconexión es un evento NORMAL del ciclo, no un error.
BackoffReintentos con backoff exponencial + jitter (1s → 2s → 4s… tope 30s). Nunca reconectes en loop apretado.
ReconciliaciónQoS 0, sin retained, sin sesión persistente: lo que pasó mientras estabas desconectado NO se re-entrega por MQTT. Al reconectar, reconstruye el estado por HTTP (GET /rides/active, GET /rides/{id}) y sigue en vivo desde ahí.
Un clientId por sesiónDos conexiones con el mismo clientId se patean mutuamente (kick-loop). Cada instancia/pestaña usa el suyo.

Laboratorio: conéctate y escucha

1Conexión como pasajero de prueba wss://…/mqtt · authorizer motify-auth
desconectado

Conecta con la identidad de prueba dev.passenger.labmqtt (clientId pax-labmqtt) y se suscribe a su inbox y a motify/ride/+/events. "Emitir evento de prueba" llama a POST /v1/dev/push (herramienta SOLO del sandbox, apagada en producción): el servidor publica un eco a tu inbox y lo ves llegar por el broker — el círculo completo "HTTP manda, MQTT avisa". También verás actividad real si creas una carrera desde la referencia de rides o corre el simulador.

// los mensajes del broker aparecerán aquí
Contrato formal AsyncAPI (schemas de payloads por topic): pendiente — esta guía es la referencia operativa del canal mientras tanto.