Server Sent Events Streaming
Server-Sent Events (SSE) is a lightweight way to receive a continuous stream of real-time data from the Timebase Historian over a standard HTTP connection
Overview
Server-Sent Events (SSE) is a lightweight way to receive a continuous stream of real-time data from the Timebase Historian over a standard HTTP connection. SSE is simpler than the WebSocket (SignalR) API: the client opens one HTTP request and the Historian pushes events as data arrives. There is no bidirectional messaging — SSE is one-way, from the Historian to your client.
SSE is well suited for web dashboards, monitoring displays, and third-party integrations that only need to receive data, not send commands.
Two SSE endpoints are available:
- Data stream — streams live TVQ (Timestamp-Value-Quality) data points as tags are updated
- Tag stream — streams tag metadata changes (tag created, updated, or deleted)
How to use SSE
Endpoints
| Endpoint | What it streams |
|---|---|
GET /api/datasets/{dataset}/data/stream |
Live TVQ data points for the subscribed tags |
GET /api/datasets/{dataset}/tags/stream |
Tag metadata changes — created, updated, or deleted |
Replace {dataset} with the name of the dataset you want to subscribe to.
Subscribing with the pattern parameter
Use the pattern query parameter to specify which tags to subscribe to. You can provide multiple patterns in a single request:
GET /api/datasets/MyDataset/data/stream?pattern=Area1.TT.001.PV&pattern=Area2.#
Each pattern can be an exact tag name or a wildcard expression. Multiple patterns in one request are combined — if a tag matches any pattern, its data is included.
Wildcard patterns
| Wildcard | Meaning | Example | Matches |
|---|---|---|---|
+ |
Exactly one segment between delimiters (. or /) |
Area1.+.PV |
Area1.TT001.PV, Area1.PT002.PV — but not Area1.TT001.Sub.PV |
# |
All remaining segments (must be last) | Area1.TT.# |
Area1.TT.001.PV, Area1.TT.002.SP, Area1.TT.003 |
# alone |
All tags in the dataset | # |
Every tag — use with caution on large datasets |
Delimiters supported in tag names: . and /.
Initial values on connect
When you open a data stream connection, the Historian immediately sends the last known TVQ for every tag that matches your pattern(s), before streaming any new data. This ensures your display shows current values instantly rather than waiting for the next update.
Message format
SSE messages use standard event: and data: fields.
Data event (new TVQ value)
event: data
data: {"n":"Area1.TT.001.PV","t":"2026-04-29T10:30:00.000Z","v":56.78,"q":192}
| Field | Description |
|---|---|
n |
Tag name |
t |
Timestamp (UTC, ISO 8601) |
v |
Value |
q |
Quality code — 192 = Good, 28 = Good (local override), 64 = Uncertain, 0 = Bad |
Tag metadata event (tag created/updated/deleted)
event: tag
data: {"n":"Area1.TT.001.PV","tp":"Updated","t":{...},"dt":"2026-04-29T10:30:00.000Z"}
| Field | Description |
|---|---|
n |
Tag name |
tp |
Change type: Created, Updated, or Deleted |
t |
Full tag metadata object (name, description, format, UOM, fields) |
dt |
Timestamp of the change (UTC, ISO 8601) |
Connecting from a browser
const source = new EventSource(
'/api/datasets/MyDataset/data/stream?pattern=Area1.TT.#'
);
source.addEventListener('data', (event) => {
const tvq = JSON.parse(event.data);
console.log(tvq.n, tvq.v, tvq.t);
});
// To disconnect:
source.close();
Connecting from the command line (curl)
curl -N "http://localhost:4511/api/datasets/MyDataset/data/stream?pattern=Area1.TT.#"
Authentication
SSE endpoints require authentication when the Historian has Pulse authentication enabled. Pass a Bearer token in the Authorization header:
Authorization: Bearer <your-access-token>
Note: The browser EventSource API does not support custom headers. For authenticated browser SSE, use the Fetch API with an AbortController instead, or pass the token as a query parameter if your deployment supports it.
Disconnecting
Close the HTTP connection to unsubscribe. The Historian cleans up all resources automatically when the connection closes. There is no separate unsubscribe call.
SSE vs WebSocket (SignalR)
| SSE | WebSocket (SignalR) | |
|---|---|---|
| Direction | Server → Client only | Bidirectional |
| Protocol | Standard HTTP | WebSocket upgrade |
| Reconnection | Automatic (browser EventSource) | Manual or via SignalR client |
| Wildcard subscriptions | Yes | Yes |
| Best for | Dashboards, monitoring displays, simple integrations | Applications that also need to send commands or manage subscriptions dynamically |
Troubleshooting
| Symptom | Likely cause | What to do |
|---|---|---|
| Connection opens but no events are received | No tags match the provided pattern, or no new data has arrived for the matching tags | Confirm the pattern matches at least one tag name. Test with # to subscribe to all tags and confirm events flow. Check that the Collector is actively writing data to the dataset |
| HTTP 400 error — "invalid pattern" | The wildcard pattern contains invalid characters or # is not at the end |
Review the wildcard syntax. # must always be the last character in a pattern. + matches exactly one segment and cannot span multiple levels |
| HTTP 401 Unauthorized | Authentication is enabled and no Bearer token was provided, or the token has expired | Obtain a valid access token from Pulse and include it in the Authorization: Bearer header. See the Pulse documentation for how to obtain a token |
The EventSource API keeps reconnecting repeatedly |
The Historian is returning errors on connect (e.g. 401 or 400), and the browser auto-reconnects on any non-200 response | Open the browser developer console, check the Network tab for the SSE request, and read the HTTP status and response body to identify the error. Fix the pattern or authentication before the browser reconnects again |
| Data events stop arriving mid-session without closing the connection | The data source stopped sending data, or the Collector went offline | The SSE connection remains open even if no data arrives. Check the Collector status and the Historian's Dataset.Writes system tag to confirm data is still being received |