Real-Time Notifications
This page covers how to add a live in-app notification feed to your frontend — the WebSocket connection, the notification bell / history, and token refresh.
How it works
When your backend fires an event with a Push channel template, Orqestra publishes the rendered content to a Centrifugo WebSocket channel. Your frontend subscribes to that channel and receives the notification in real time.
No polling. No Firebase account. No WebSocket server to manage.
sequenceDiagram
participant B as Your Backend
participant O as Orqestra API
participant C as Centrifugo
participant F as User's Browser
F->>O: POST /api/v1/auth/realtime-token
O-->>F: { token, channels[] }
F->>C: WebSocket connect + subscribe
B->>O: POST /api/v1/events/trigger (Push template)
O->>C: Publish to user channel
C-->>F: Publication { title, body, eventType }
Step 1 — Request a real-time token
Your backend (or your frontend calling through your backend) requests a Centrifugo connection token:
curl -X POST https://your-orqestra-host/api/v1/auth/realtime-token \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_TENANT_API_KEY" \
-d '{ "userId": "uuid-of-the-logged-in-user" }'
Response:
{
"token": "eyJhbGciOiJIUzI1NiIs...",
"channels": [
"global_system#uuid-of-the-logged-in-user",
"your_custom_channel#uuid-of-the-logged-in-user"
]
}
Pass this token and channel list to your frontend. Do not expose your x-api-key in the browser.
Step 2 — Connect to the WebSocket
Install the Centrifugo JavaScript client:
npm install centrifuge
import { Centrifuge } from 'centrifuge';
const centrifuge = new Centrifuge(
'wss://your-orqestra-host/connection/websocket',
{ token: tokenResponse.token }
);
tokenResponse.channels.forEach((channel) => {
const sub = centrifuge.newSubscription(channel);
sub.on('publication', (ctx) => {
// ctx.data contains: { title, body, category, eventType }
console.log('New notification:', ctx.data.title);
addToNotificationFeed(ctx.data);
});
sub.subscribe();
});
centrifuge.connect();
:::tip Token refresh Realtime tokens expire after 2 hours. Request a fresh token on user login and set up a periodic refresh in your frontend to prevent disconnection. :::
Step 3 — Show the notification
The ctx.data object contains:
| Field | Description |
|---|---|
title | Short heading, rendered from template |
body | Main content, rendered from template |
category | Event type (e.g. order.confirmed) |
eventType | Same as category |
Use this to drive a toast notification, an in-app notification badge, or a notification feed panel.
Notification history (bell icon)
To show a notification history feed, fetch the user's past in-app notifications:
curl https://your-orqestra-host/api/v1/notifications/{tenantId}/{userId} \
-H "x-api-key: YOUR_TENANT_API_KEY"
Response:
{
"success": true,
"data": [
{
"id": "notif-uuid-1",
"type": "order.confirmed",
"title": "Order Confirmed",
"body": "Your order ORD-2026-1234 has been confirmed.",
"status": "UNREAD",
"created_at": "2026-04-22T12:00:00Z"
}
]
}
Mark a notification as read
curl -X PUT \
https://your-orqestra-host/api/v1/notifications/{tenantId}/{userId}/{notificationId}/read \
-H "x-api-key: YOUR_TENANT_API_KEY"
Creating a Push template
In Admin UI → Templates, create a template with channel = Push:
- Event type: match the event you'll fire (e.g.
order.confirmed) - Content body: plain text with Handlebars variables:
{{title}} — {{message}} - Target WS channel: the Centrifugo channel name to publish to (leave blank for the default user-personal channel)
Activate the template and fire the event from your backend. The notification appears in your frontend WebSocket subscription within milliseconds.