Realtime
Publish messages, subscribe to channels, and track presence with Lepsto Realtime.
Lepsto Realtime delivers messages from your backend to subscribed browser tabs. It can also track who is connected through presence and retain messages so clients can recover after a disconnection.
Your application chooses the channels and permissions. Realtime holds the connections, delivers each publish to current subscribers within the request, and provides a browser client that reconnects when the network drops.
When to reach for it
Use Realtime for updates that need to reach an open page: chat messages, collaborative edits, order status, job progress or dashboard changes. Presence adds a roster of connected users. History lets clients replay retained messages after reconnecting.
Live delivery needs an audience. If no client is watching, you do not need to publish a live update.
The four ideas
The examples below use a chat application. Replace names such as chat:room-1 with your application’s channels.
- A channel is a named message stream. Publishing or subscribing creates its use; there is no separate creation step. Names contain 3–128 characters from
a-z,A-Z,0-9,.,_,-and:, with at least one colon. - A namespace is the segment before the first colon:
chatin bothchat:room-1andchat:room-2. Its policy applies to all those channels. Names contain 1–64 characters from the same set except:. - A capability pairs a channel with allowed operations:
subscribereceives messages,publishsends from a connected client,presenceenters and reads the roster, andhistoryreplays earlier messages. A token’s capabilities define all access for its connection. - A grant assigns a subject operations on a channel pattern until you revoke it.
Register the namespace before issuing tokens or using its channels. Unregistered namespaces allow no capabilities, so a subscription to
chat:room-1cannot succeed untilchatexists.
What a namespace decides
Set a namespace’s policy once to control every channel within it:
Setting | Values | Default | What it decides |
|---|---|---|---|
visibility | public, authorized | authorized | public gives every authenticated identity subscribe on namespace:* without a grant |
presence | boolean | false | Whether a channel keeps a roster |
clientEvents | boolean | false | Whether connected clients may publish directly |
history | none, last-message, window | none | What is retained and replayable |
historyWindowSeconds | 1 … 2592000 | — | Retention window; required when history is window |
encryptionRequired | boolean | false | Whether payloads must be end-to-end encrypted |
identifiedOnly | boolean | false | Whether anonymous callers get any capability at all |
subscribeProxyUrl | HTTPS URL or null | null | A callback of yours consulted per channel while a token is minted |
archive | off, { days: N } | off | Durable retention of archived history entries, up to 3650 days |
In Realtime → Namespaces, select Create namespace to set these options. To edit an existing namespace, select its pencil icon; its name stays locked. Agents use realtime_namespace_create and realtime_namespace_update. REST operations are in the Realtime API reference. Namespace management is not available on the public HTTP routes.
How policy narrows a capability
Namespace policy limits capabilities from both grants and backend token requests:
presencesurvives only if the namespace haspresenceenabled.publishsurvives only if the namespace hasclientEventsenabled.historysurvives only if the namespace’shistoryis notnone.subscribeis not gated by these flags. Who may subscribe is decided by the caller side: a grant, or the channel your backend names when it mints.
Unsupported operations are removed during issuance. For example, requesting ['subscribe', 'presence'] when presence is disabled produces ['subscribe']. If no capabilities remain, issuance fails with 422.
Two checks run before operation filtering. identifiedOnly excludes anonymous callers entirely. If you set subscribeProxyUrl, Realtime calls it once per concrete channel during token issuance; a channel receives no capability unless your callback allows it.
Grants
A grant records the following permission until it is revoked:
Field | Meaning |
|---|---|
subject | The identity the grant applies to, or * for every identity in the product |
pattern | A channel pattern such as chat:* |
ops | The operations granted on every channel the pattern matches |
A * in a pattern matches one segment only, and both names must have the same number of segments. For example, chat:* matches chat:room-1 but not chat:room-1:typing; chat:*:* matches the latter. The namespace must be literal, so *:room-1 is invalid. Patterns can have at most eight segments.
Platform identities and your product’s end users obtain access differently:
Caller | Needs a grant | How its capabilities are decided |
|---|---|---|
A platform identity | Yes | Grants are resolved when a token is minted for that identity, together with the public visibility rule |
One of your own end users | No | Your backend states which concrete channels and operations the token should carry, and namespace policy narrows that declaration. No wildcards |
In Realtime → Grants, use Create grant to set the subject, pattern and operations. You can filter the list by subject and revoke any row. Agents use realtime_grant_create, realtime_grant_list and realtime_grant_revoke.
What you build against
The @lepsto/sdk package has two Realtime imports. Choose the HTTP client for the credential your backend holds; browsers use the socket client with a delegated token.
Surface | Credential | Use it for |
|---|---|---|
@lepsto/sdk/realtime HTTP client | Product public key and product ID, kept on your backend | tokens.issue, messages.publish, history.get, presence.get and presence.stats |
Browser socket, also in @lepsto/sdk/realtime | Delegated token from your backend | Connecting, subscribing, presence and reconnecting |
Server SDK, @lepsto/sdk/realtime/server | Server credential and explicit base URL | Namespace policy, grants, webhooks, administrative presence writes and server-mode tokens, plus publish, history and presence reads; server-only |
Product public key on your backend | The five public operations without the SDK, at https://public.lepsto.com/{productId}/realtime, using Authorization: Bearer |
Publishing, history reads and both presence reads are available through either SDK subpath. A backend already using the management client can keep using that client for these operations.
The workspace provides Realtime → Namespaces, Grants and Webhooks for management, plus per-channel History, Archive and Presence inspectors. Status reports service, delivery, signing-key and connection health. Product public keys are managed separately in Product → Settings → Public Access.
Next steps
- Send your first realtime message: one path from nothing to a message arriving in a browser tab.
- Authenticate your backend and your users: the product public key you hold and the short-lived token each user gets.
- Call the public HTTP routes: the five routes, their request and response bodies, and the limits on them.
- Show who is on a channel: turn on the roster and read it.
- Replay what a client missed: retain messages and recover after a reconnect.
- Look up a limit or an error: every quota, status code and close code in one place.