Skip to main content

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:

FieldDescription
titleShort heading, rendered from template
bodyMain content, rendered from template
categoryEvent type (e.g. order.confirmed)
eventTypeSame 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.