Live stream
Push new feed items to your client over Server-Sent Events.
GET /v1/notifications/stream holds a connection open and pushes each new
feed item to you the moment it lands — no polling. It speaks standard
Server-Sent Events,
so EventSource in a browser or any SSE client library works out of the box.
The stream carries the notifications feed only — the same human-readable items you'd see in the bell. For structured platform events (training progress, deployment status, goal alerts as data), use Realtime (WebSockets) instead.
Connect
curl -N disables buffering so events print as they arrive:
curl -N "$API_BASE/v1/notifications/stream" \
-H "Authorization: Bearer $TOKEN"Browsers' EventSource API can't set headers, so the endpoint also accepts
the token as a query parameter — either form authenticates the same way:
curl -N "$API_BASE/v1/notifications/stream?access_token=$TOKEN"A bad or missing token returns 401 with {"status": "Unauthorized"}.
What comes over the wire
The stream greets you immediately, then emits one notification event per
new feed item:
event: hello
data: {"user_id": "usr_4E92…"}
event: notification
data: {"type": "notification", "notification_id": "ntf_7C0A91B4E2D64F58A31006", "user_id": "usr_4E92…", "event_code": "training.completed", "category": "modeling", "severity": "success", "title": "Training complete", "body": "Daily sales forecaster finished in 4m 12s.", "link": "/workspaces/8b1f3c2a-…/trainings/5d9e02f7-…", "metadata": {"training_id": "5d9e02f7-…", "duration_s": 252}, "created_at": "2026-07-15T09:41:07+00:00", "read_at": null}
:keepalive| Event | Payload | Meaning |
|---|---|---|
hello | {"user_id": "…"} | Connection established and authenticated. Sent once, immediately. |
notification | One JSON feed item | Same fields as the feed, plus "type": "notification". |
notifications_unavailable | {} | Live delivery is temporarily unavailable; the stream closes right after. Fall back to polling the feed. |
A :keepalive comment line is sent every 25 seconds so proxies don't drop
the idle connection; SSE clients ignore comment lines automatically.
Reconnecting
Connections drop — networks blip, proxies recycle. Treat it as routine:
- Reconnect with backoff.
EventSourcereconnects automatically; with other clients, retry with a short exponential backoff. - Events that fired while you were offline are not replayed on the
stream. On reconnect, fetch the gap from the feed with the
sinceparameter, using thecreated_atof the last item you saw:
curl "$API_BASE/v1/notifications/?since=2026-07-15T09:41:07Z" \
-H "Authorization: Bearer $TOKEN"from predictai import PredictAI
client = PredictAI(token="pa_live_…")
data = client.notifications.get_notifications(params={"since": "2026-07-15T09:41:07Z"})
import { PredictAI } from "@predictai/sdk";
const client = new PredictAI({ token: "pa_live_…" });
const data = await client.notifications.getNotifications({ params: { since: "2026-07-15T09:41:07Z" } });
The feed is the source of truth; the stream is a "refresh now" signal. A client that treats every stream event as a hint to re-query never misses anything.

