QuavernQuavsit

Section 06 sur 12

Streams

Deux endpoints poussent les mises à jour en server-sent events (SSE) au lieu d'être interrogés en boucle : les passages à un arrêt et les véhicules d'une ligne. Les streams demandent un plan avec le droit streams (tous les plans payants, Pay as you go compris) ; en Free ils répondent 402 plan_required.

Endpoints#

RouteParamètresIntervalle
GET /stops/{stop_id}/departures/streaminterval, horizon, limit, line, direction15–120 s, 20 par défaut
GET /lines/{line_id}/vehicles/streaminterval10–120 s, 10 par défaut

La réponse est en text/event-stream avec Cache-Control: no-cache. Demandez-la avec un client qui garde la connexion ouverte :

sh
curl -N "https://api.quavern.net/v1/stops/tbm:stop:3824/departures/stream?interval=20&limit=5" \
  -H "Authorization: Bearer qv_p_…"

Événements#

Chaque événement est event: <nom> suivi d'une ligne data: en JSON, puis d'une ligne vide.

ÉvénementQuandContenu
metaen premier, une fois{"plan", "interval", "max_duration"}
departurestoutes les interval secondes{"data": [Departure…], "meta": {…}}, identique à la réponse REST
vehiclestoutes les interval secondes{"data": [Vehicle…], "meta": {…}}
errorune fois, puis le stream se ferme{"code", "reason", "message"}

Une ligne de commentaire : ping est envoyée toutes les 15 secondes pour empêcher les intermédiaires de couper une connexion inactive ; les clients SSE l'ignorent. Le serveur ferme le stream après max_duration (600 s) ; reconnectez-vous pour continuer.

text
event: meta
data: {"plan":"pro","interval":20,"max_duration":600}

event: departures
data: {"data":[{"stop_id":"tbm:stop:3824","line_code":"B","headsign":"Berges de la Garonne","expected_at":"2026-09-07T14:13:20+02:00","realtime":true,"status":"delayed"}],"meta":{"generated_at":"2026-09-07T12:11:03Z","units":1,"freshness":"realtime"}}

: ping

Unités#

Chaque événement departures ou vehicles coûte 1 unité, débitée à l'envoi ; meta, les pings et error ne coûtent rien. Un stream à l'intervalle par défaut des passages coûte donc 3 unités par minute. Si le budget mensuel s'épuise en cours de stream, le serveur envoie error avec le reason quota_exhausted puis ferme.

Concurrence#

Chaque clé peut tenir un nombre borné de streams simultanés, fixé par le plan : 2 en Pay as you go et Starter, 3 en Pro, 8 en Max, 16 en Enterprise. En ouvrir un de plus renvoie 429 stream_limit_reached. Le service a aussi un plafond global ; quand il est atteint, la même erreur est renvoyée même sous votre propre limite, traitez-la donc comme une condition de réessai (attendez 5 à 30 secondes).

Notes pour le client#

L'API navigateur EventSource ne peut pas envoyer d'en-tête Authorization, et les clés ne doivent de toute façon jamais atteindre un navigateur : consommez les streams depuis un processus serveur et relayez à vos clients si besoin. Avec fetch, lisez response.body en flux et découpez sur les lignes vides. Reconnectez-vous à la fermeture avec un court délai aléatoire, et préférez interroger l'endpoint REST si vous avez besoin de moins d'une mise à jour toutes les 20 secondes.