GET de larga duración que recibe cada
evento en el momento, con replay garantizado si se corta la conexión.
Usa el stream para mantener un dashboard vivo (saldos, payins que acreditan,
payouts que liquidan, autorizaciones de tarjeta, alertas KYT para los admins).
Usa webhooks para todo lo que deba sobrevivir a que cierren el
navegador — los dos canales llevan los mismos eventos con el mismo payload
y el mismo event_id, así no escribes dos mapeos.
Abrir el stream
El endpoint pide la misma credencialAuthorization: Bearer que el resto de la
API, así que el EventSource nativo del navegador (que no puede mandar
headers) no sirve. Usa fetch leyendo el cuerpo como stream:
Respuesta
Reconectar sin huecos
Si se corta la conexión, reconecta mandando el último cursor procesado. El servidor replaya desde el log todo lo que te perdiste antes de volver al vivo, así una red inestable nunca pierde un evento.El replay tiene tope de 1.000 eventos. Si estuviste desconectado el tiempo
suficiente para perderte más, el stream emite un evento de control
replay_truncated y conviene reconciliar con ?snapshot=true o con
GET /v1/events/history en vez de asumir
continuidad.Snapshot inicial
Abrir con?snapshot=true envía primero el estado actual y después los
deltas. Elimina la carrera clásica de “leo los endpoints REST, después me
suscribo y pierdo lo que pasó en el medio”: el cursor se toma con la
suscripción ya abierta, así nada se cae por la rendija.
balances para una credencial de cuenta (los mismos campos de
GET /v1/balances) y, para un admin de organización,
los contadores de health operativa.
Filtrar por tipo de evento
?types= acota lo que recibes. Solo puede restringir lo que tu credencial
ya ve, jamás ampliarlo. Un tipo desconocido se rechaza con
400 invalid_event_type en vez de dejarte esperando eventos que no llegan.
Alcance: cuenta vs admin de organización
Una cuenta nunca ve los eventos de otra cuenta ni la superficie de compliance
org-wide. El stream jamás entrega un campo que esa misma credencial no pudiera
leer por REST.
Eventos de control
Además de tus eventos de negocio, el stream emite eventos de protocolo. No llevanid: (salvo snapshot), así que no mueven tu cursor de replay.
Cada 20 segundos llega un comentario
: ping para que ningún proxy corte una
conexión ociosa — ignora las líneas que empiezan con :.
Límites
Pasarse del límite de concurrencia devuelve
429 too_many_streams. Pasarse de
la cuota de aperturas devuelve 429 rate_limited — esa cuenta intentos, así
que un cliente que reconecta en bucle la quema aunque no tenga ningún stream
abierto. Respeta siempre el retry: (3 s) más backoff exponencial.
Historial consultable
El mismo log que alimenta el stream se lee por REST — útil para auditoría, para una vista de “qué me perdí” o cuando el replay quedó truncado.Errores
Lista completa en Errores.
Preguntas frecuentes
¿Reemplazo los webhooks por el stream?
¿Reemplazo los webhooks por el stream?
No. El stream vive mientras vive la pestaña; los webhooks llegan a tu
backend aunque nadie esté mirando. Usa el stream para la UI y los webhooks
para todo lo que dispare lógica de negocio (conciliación, contabilidad,
notificaciones).
¿Puede llegarme el mismo evento dos veces?
¿Puede llegarme el mismo evento dos veces?
Sí — tras una reconexión el replay puede reentregar el evento del borde, y
ambos canales (webhook y stream) comparten el mismo
event_id.
Deduplica por event_id y trata cada payload como estado absoluto.¿Por qué se cierra la conexión a los 30 minutos?
¿Por qué se cierra la conexión a los 30 minutos?
Por diseño. Un stream sin tope de vida esconde conexiones filtradas. El
servidor manda antes un evento de control
reconnect, y reconectar con
Last-Event-ID continúa exactamente donde ibas.¿Necesito una suscripción como con los webhooks?
¿Necesito una suscripción como con los webhooks?
No. El stream no se configura: entrega todo lo que tu credencial puede
ver. Las suscripciones de webhook solo controlan las entregas HTTP a tu
servidor.
No llega nada, ni siquiera el heartbeat.
No llega nada, ni siquiera el heartbeat.
Revisa que tu cliente HTTP no esté bufereando la respuesta (en
fetch, lee
res.body como stream en vez de esperar res.text()) y que ningún proxy
tuyo esté bufereando text/event-stream. CBPay ya desactiva el buffering
de su lado.¿Un admin de organización puede seguir una sola cuenta?
¿Un admin de organización puede seguir una sola cuenta?
Sí, con
?account_id=. El filtro solo opera dentro de tu propia
organización; cualquier otra cosa devuelve 404.