Realtime overview
Switera Realtime lets your SaaS frontend subscribe to live app, tenant, user, and role channels while your backend publishes messages through a trusted API key. The browser never receives runtime secrets. It receives short-lived Switera-issued tokens derived from the signed-in Connect user.
Use Realtime for live notifications, workspace updates, activity feeds, background-job progress, collaboration indicators, and customer-facing dashboards that should update without refresh.
Launch surface
| Area | Use it for | Launch state |
|---|---|---|
| Connection tokens | Let a signed-in Connect user open a websocket connection. | Available through /api/v1/connect/realtime/token. |
| Subscription tokens | Authorize one private app, tenant, user, or role channel. | Available through /api/v1/connect/realtime/subscriptions. |
| Publish API | Send trusted backend events to one channel. | Available through /api/v1/apps/{appId}/realtime/publish. |
| Runtime status | Verify token signing, public websocket URL, and runtime health. | Available in the app console and API. |
| Channel scopes | Keep live messages scoped to the intended audience. | Available for app, tenant, user, and role namespaces. |
Channel scopes
Channels are part of your application contract. Keep topic names stable once application code subscribes to them.
| Scope | Pattern | Typical audience |
|---|---|---|
| App | app:{appId}:{topic} | All connected users for one app. |
| Tenant | tenant:{appId}:{tenantId}:{topic} | Users who belong to one customer organization. |
| User | user:{appId}:{userId}:{topic} | One app user. |
| Role | role:{appId}:{tenantId}:{role}:{topic} | Members of one organization with a specific role. |
Good launch examples:
app:app_123:broadcast
tenant:app_123:tenant_456:updates
user:app_123:user_789:notifications
role:app_123:tenant_456:admin:updates
Runtime readiness
Open Services > Realtime or call the runtime endpoint before wiring frontend code.
GET /api/v1/apps/{appId}/realtime/runtime
Authorization: Bearer sf_secret_...
{
"status": "ready",
"summary": "Realtime runtime checks are passing.",
"websocket_url": "wss://switera.com/realtime/connection/websocket",
"namespaces": [
{
"name": "tenant",
"pattern": "tenant:{appId}:{tenantId}:{topic}",
"presence": true,
"history": "120s"
}
],
"checks": [
{
"key": "token_secret",
"status": "ready",
"summary": "Realtime token signing is configured."
}
]
}
Treat any setup_required or needs_attention status as a launch blocker for realtime features.
Issue a connection token
Your SaaS frontend calls the Connect route after the user is signed in. The request uses the existing browser session or Connect bearer token.
POST /api/v1/connect/realtime/token
Content-Type: application/json
{
"tenant_id": "tenant_456"
}
{
"token_type": "Bearer",
"expires_in": 900,
"app_id": "app_123",
"user_id": "user_789",
"tenant_id": "tenant_456",
"role": "admin",
"websocket_url": "wss://switera.com/realtime/connection/websocket",
"channels": [
"app:app_123:broadcast",
"user:app_123:user_789:notifications",
"tenant:app_123:tenant_456:updates",
"role:app_123:tenant_456:admin:updates"
]
}
Switera derives app_id, user_id, tenant_id, email, and role from trusted Auth and organization records. Do not send those values from browser code except the tenant the user is trying to enter.
Authorize a private channel
For private subscriptions, ask Switera for one subscription token per channel.
POST /api/v1/connect/realtime/subscriptions
Content-Type: application/json
{
"channel": "tenant:app_123:tenant_456:updates"
}
Switera checks that:
- app channels belong to the signed-in app,
- tenant channels belong to an organization where the user is an active member,
- user channels match the resolved app user,
- role channels match the user's active organization role.
Publish from a trusted backend
Publish from your backend, job runner, or automation using an app secret key.
POST /api/v1/apps/{appId}/realtime/publish
Authorization: Bearer sf_secret_...
Content-Type: application/json
{
"channel": "tenant:app_123:tenant_456:updates",
"data": {
"type": "invoice.paid",
"invoice_id": "inv_123"
},
"idempotency_key": "invoice-paid-inv_123"
}
{
"channel": "tenant:app_123:tenant_456:updates",
"published": true
}
Browser token example
const tokenResponse = await auth.issueRealtimeConnectionToken({
tenant_id: 'tenant_456'
});
const channel = 'tenant:app_123:tenant_456:updates';
const subscriptionToken = await auth.issueRealtimeSubscriptionToken({
channel
});
console.log(tokenResponse.websocket_url);
console.log(tokenResponse.token);
console.log(subscriptionToken.token);
Use the returned websocket_url and tokens with the realtime client layer in
your application. First-party Switera connection wrappers are tracked in the SDK
roadmap.
What not to do
- Do not put app secret keys in browser code.
- Do not publish directly to the internal realtime runtime.
- Do not use app-wide broadcast channels for tenant-specific data.
- Do not treat channel names as user input. Build them from trusted app, tenant, user, and role IDs.