Understand Convor connection tokens, channel-scoped subscription tokens, tenant channel names, refresh behavior, and protocol-only proxy routes.
Convor uses Centrifugo for realtime delivery. Realtime authentication is separate from normal REST authorization:
The official dashboard and widget implement this protocol. Prefer those clients unless you are building a reviewed first-party extension.
The dashboard uses its authenticated operator session to call:
GET /api/realtime/tokenThe response contains:
{
"token": "<connection-jwt>",
"url": "<configured-websocket-url>",
"expiresIn": 3600
}Connect to the returned url with the returned token. Do not hardcode a
WebSocket host from documentation or infer it from api.convor.io; the runtime
configuration is authoritative.
The operator connection token expires after one hour. Refresh it before expiry and reconnect using the replacement token.
The widget obtains a one-hour visitor token from
POST /api/auth/visitor-token. That token identifies the visitor and
organization and is used as the realtime connection token as well as the bearer
credential for visitor-scoped HTTP requests.
The official widget refreshes the visitor token shortly before expiry, reconnects with jitter after transient failures, and keeps the same anonymous visitor when a reusable visitor handle is available.
See Widget Bootstrap and Visitor Identity for the complete visitor trust flow.
Connection tokens do not grant every tenant channel. A client requests a channel-specific JWT from:
POST /api/realtime/subscribe-token{
"channelId": "org:<orgId>:conv:<conversationId>"
}The returned JWT is bound to the requesting principal and exactly one channel. Convor verifies the channel belongs to the authenticated organization before issuing it.
Supported tenant channel families include:
| Channel | Intended audience |
|---|---|
org:<orgId>:ops | Organization operators |
org:<orgId>:ops:conv:<conversationId> | Operators following one conversation |
org:<orgId>:triggers | Widget trigger configuration |
org:<orgId>:conv:<conversationId> | Conversation participants |
org:<orgId>:conv:<conversationId>:presence | Conversation presence |
org:<orgId>:visitor:<visitorId> | One visitor |
Visitors can subscribe only to their own visitor and conversation channels. Operator-only channels reject visitor principals. A channel whose organization prefix does not match the authenticated organization is rejected.
Channel names do not grant access
Knowing another conversation or visitor UUID does not authorize a subscription. Clients must obtain a server-issued token for every private channel.
A resilient client should:
Do not put connection or subscription JWTs in URLs, analytics events, logs, or persistent browser storage.
The server has authenticated realtime endpoints for publishing, presence, history, and subscription-token issuance. Their authorization rules are channel-specific and may return a safe empty fallback when Centrifugo presence or history is temporarily unavailable.
These routes support Convor's first-party clients and are not a replacement for the customer REST resources or outbound webhooks. For external automation, use the public API reference and outbound webhooks.
Routes under /api/centrifugo/*, including connect, disconnect, subscribe,
publish, and refresh callbacks, are Centrifugo-to-Convor infrastructure
callbacks. They validate lifecycle events and channel permissions for the
realtime server.
They are not public customer API endpoints, must not appear in the generated customer reference, and should never be called directly by a browser, integration, or organization API-key client. Configure Centrifugo to call them through the deployment's trusted proxy configuration; application clients use connection and subscription tokens instead.
Last updated: Aug 3, 2026
Was this page helpful?