REST API
The Realtime area publishes 28 REST endpoints. Paths are relative to https://api.lessly.com; see Authentication for the required header.
GET/realtime/archive
Read a channel's durably archived history from Postgres (survives the Redis hot window). Offset-paginated: pass the returned next_offset as after_offset for the next page.
MCP tool: realtime_archive_get
Parameters
| Name | In | Type | Required | Description |
|---|
| channel | query | string | • | Channel whose archived history to read |
| after_offset | query | string | — | Return entries strictly after this offset (from a previous page) |
| limit | query | integer | — | — |
Response
| Field | Type | Always | Description |
|---|
| channel | string | • | — |
| entries | array | • | — |
| next_offset | string | • | Pass as after_offset to fetch the next page; null = no more entries |
POST/realtime/archive/exports
Start an async NDJSON export of a channel's archived history to the product bucket. Returns an export id; poll realtime_archive_export_status until done.
MCP tool: realtime_archive_export
Parameters
| Name | In | Type | Required | Description |
|---|
| channel | body | string | • | Channel whose archive to export |
| from_ts | body | integer | — | Only entries with ts >= from_ts (epoch ms) |
| to_ts | body | integer | — | Only entries with ts <= to_ts (epoch ms) |
Response
| Field | Type | Always | Description |
|---|
| status | string | • | — |
| export_id | string | • | — |
GET/realtime/archive/exports/:export_id
Check an archive export: status, and the NDJSON blob reference once done
MCP tool: realtime_archive_export_status
Parameters
| Name | In | Type | Required | Description |
|---|
| export_id | path | string | • | Export id returned by realtime_archive_export |
Response
| Field | Type | Always | Description |
|---|
| ref | object | • | Blob reference of the NDJSON export once status is "done" |
| error | string | • | — |
| status | string | • | — |
| export_id | string | • | — |
| entry_count | integer | • | — |
GET/realtime/grants
List realtime channel grants for this product, optionally filtered by subject
MCP tool: realtime_grant_list
Parameters
| Name | In | Type | Required | Description |
|---|
| subject | query | string | — | Filter grants by subject |
Response
| Field | Type | Always | Description |
|---|
| grants | array | • | — |
POST/realtime/grants
Grant a subject (identity id or "*" for all identities) operations on channels matching a pattern; "*" in a pattern matches exactly one segment
MCP tool: realtime_grant_create
Parameters
| Name | In | Type | Required | Description |
|---|
| subject | body | string | • | Identity id the grant applies to, or "*" for every identity in the product |
| pattern | body | string | • | Channel pattern, e.g. "chat:*" ("*" matches exactly one segment) |
| ops | body | array | • | Operations granted on matching channels |
Response
| Field | Type | Always | Description |
|---|
| id | string | • | — |
| ops | array | • | — |
| pattern | string | • | — |
| subject | string | • | — |
| createdAt | string | • | — |
DELETE/realtime/grants/:id
Revoke a realtime channel grant by id
MCP tool: realtime_grant_revoke
Parameters
| Name | In | Type | Required | Description |
|---|
| id | path | string | • | Grant id to revoke |
Response
| Field | Type | Always | Description |
|---|
| revoked | boolean | • | — |
POST/realtime/messages
Publish a JSON message to a realtime channel of the current product
MCP tool: realtime_messages_publish
Parameters
| Name | In | Type | Required | Description |
|---|
| channel | body | string | • | Channel to publish the message to |
| data | body | string | • | JSON payload delivered to channel subscribers |
Response
| Field | Type | Always | Description |
|---|
| epoch | string | — | Stream epoch of the stored message (present when history is on) |
| offset | string | — | Stream offset of the stored message (present when history is on) |
| channel | string | • | Channel the message was published to |
| published | boolean | • | Publish acknowledged by the fan-out backend |
GET/realtime/messages/history
Read message history of a realtime channel: either a cursor (offset + epoch, replays strictly after the offset; recovered:false on epoch mismatch or aged-out entries) or a window (last_n / last_ms). Conceptually requires the `history` capability; in Phase 1 this surface is Identity-authenticated management access.
MCP tool: realtime_history_get
Parameters
| Name | In | Type | Required | Description |
|---|
| channel | query | string | • | Channel to read history from |
| offset | query | string | — | Cursor: resume strictly after this offset (requires epoch) |
| epoch | query | string | — | Cursor: stream epoch the offset belongs to |
| last_n | query | integer | — | Window: return the last N entries |
| last_ms | query | integer | — | Window: return entries newer than now minus this many milliseconds |
Response
| Field | Type | Always | Description |
|---|
| epoch | string | • | Current stream epoch, or null when the channel has no history yet |
| channel | string | • | Channel the history was read from |
| entries | array | • | Entries in stream order |
| recovered | boolean | • | false when the cursor epoch mismatches or entries aged out — client must resync |
GET/realtime/namespaces
List all realtime namespaces registered for this product
MCP tool: realtime_namespace_list
Parameters
No parameters.
Response
| Field | Type | Always | Description |
|---|
| namespaces | array | • | — |
POST/realtime/namespaces
Register a realtime namespace (the part of a channel name before the first colon) with its policy: visibility, presence, client events, history, encryption, identified-only
MCP tool: realtime_namespace_create
Parameters
| Name | In | Type | Required | Description |
|---|
| name | body | string | • | Namespace name (the part of a channel name before the first colon) |
| visibility | body | string | — | public: any authenticated identity may subscribe without a grant |
| presence | body | boolean | — | Whether presence is enabled on channels in this namespace |
| clientEvents | body | boolean | — | Whether clients may publish events directly |
| history | body | string | — | History retention policy for channels in this namespace |
| historyWindowSeconds | body | integer | — | Retention window in seconds; required when history is "window" |
| encryptionRequired | body | boolean | — | Whether payloads must be end-to-end encrypted |
| identifiedOnly | body | boolean | — | Whether only identified (non-anonymous) identities get capabilities |
| subscribeProxyUrl | body | string | — | If set, token mint consults this URL per requested channel (fail-closed); null disables |
| archive | body | string | — | History archive policy: off, or durably retain archived entries for N days (requires history != "none") |
Response
| Field | Type | Always | Description |
|---|
| id | string | • | — |
| name | string | • | — |
| archive | string | • | History archive policy |
| history | string | • | — |
| presence | boolean | • | — |
| createdAt | string | • | — |
| updatedAt | string | • | — |
| visibility | string | • | — |
| clientEvents | boolean | • | — |
| identifiedOnly | boolean | • | — |
| subscribeProxyUrl | string | • | — |
| encryptionRequired | boolean | • | — |
| historyWindowSeconds | integer | • | — |
| subscribeProxySecret | string | — | Full proxy signing secret — returned ONLY when subscribeProxyUrl is set/changed |
| subscribeProxySecretPrefix | string | • | Visible prefix of the proxy signing secret; null when no proxy url is set |
DELETE/realtime/namespaces/:name
Delete a realtime namespace by name (grants on it stop resolving)
MCP tool: realtime_namespace_delete
Parameters
| Name | In | Type | Required | Description |
|---|
| name | path | string | • | Namespace name |
Response
| Field | Type | Always | Description |
|---|
| deleted | boolean | • | — |
GET/realtime/namespaces/:name
Get a realtime namespace and its policy by name
MCP tool: realtime_namespace_get
Parameters
| Name | In | Type | Required | Description |
|---|
| name | path | string | • | Namespace name |
Response
| Field | Type | Always | Description |
|---|
| id | string | • | — |
| name | string | • | — |
| archive | string | • | History archive policy |
| history | string | • | — |
| presence | boolean | • | — |
| createdAt | string | • | — |
| updatedAt | string | • | — |
| visibility | string | • | — |
| clientEvents | boolean | • | — |
| identifiedOnly | boolean | • | — |
| subscribeProxyUrl | string | • | — |
| encryptionRequired | boolean | • | — |
| historyWindowSeconds | integer | • | — |
| subscribeProxySecret | string | — | Full proxy signing secret — returned ONLY when subscribeProxyUrl is set/changed |
| subscribeProxySecretPrefix | string | • | Visible prefix of the proxy signing secret; null when no proxy url is set |
PATCH/realtime/namespaces/:name
Update the policy of a realtime namespace
MCP tool: realtime_namespace_update
Parameters
| Name | In | Type | Required | Description |
|---|
| name | path | string | • | Namespace name to update |
| visibility | body | string | — | public: any authenticated identity may subscribe without a grant |
| presence | body | boolean | — | Whether presence is enabled on channels in this namespace |
| clientEvents | body | boolean | — | Whether clients may publish events directly |
| history | body | string | — | History retention policy for channels in this namespace |
| historyWindowSeconds | body | integer | — | Retention window in seconds; required when history is "window" |
| encryptionRequired | body | boolean | — | Whether payloads must be end-to-end encrypted |
| identifiedOnly | body | boolean | — | Whether only identified (non-anonymous) identities get capabilities |
| subscribeProxyUrl | body | string | — | If set, token mint consults this URL per requested channel (fail-closed); null disables |
| archive | body | string | — | History archive policy: off, or durably retain archived entries for N days (requires history != "none") |
Response
| Field | Type | Always | Description |
|---|
| id | string | • | — |
| name | string | • | — |
| archive | string | • | History archive policy |
| history | string | • | — |
| presence | boolean | • | — |
| createdAt | string | • | — |
| updatedAt | string | • | — |
| visibility | string | • | — |
| clientEvents | boolean | • | — |
| identifiedOnly | boolean | • | — |
| subscribeProxyUrl | string | • | — |
| encryptionRequired | boolean | • | — |
| historyWindowSeconds | integer | • | — |
| subscribeProxySecret | string | — | Full proxy signing secret — returned ONLY when subscribeProxyUrl is set/changed |
| subscribeProxySecretPrefix | string | • | Visible prefix of the proxy signing secret; null when no proxy url is set |
GET/realtime/presence
Get the current presence roster for a channel. Roster is deduplicated by identity (connections counts live sockets); a per-connection view is deferred — the store is identity-keyed.
MCP tool: realtime_presence_get
Parameters
| Name | In | Type | Required | Description |
|---|
| channel | query | string | • | Channel name, "namespace:rest" |
Response
| Field | Type | Always | Description |
|---|
| channel | string | • | Channel name |
| members | array | • | Current roster, deduplicated by identity |
POST/realtime/presence/enter
Enter presence on a realtime channel; upserts the caller (or member_id) into the roster
MCP tool: realtime_presence_enter
Parameters
| Name | In | Type | Required | Description |
|---|
| channel | body | string | • | Channel name, "namespace:rest" |
| info | body | string | — | Arbitrary JSON metadata for the member (<=10KB serialized) |
| ttl_seconds | body | integer | — | Presence entry TTL in seconds (1-3600) |
| member_id | body | string | — | Act for a synthetic member id instead of the caller identity (backend integrations) |
Response
| Field | Type | Always | Description |
|---|
| member | object | • | The entered/updated member |
| channel | string | • | Channel name |
POST/realtime/presence/leave
Leave presence on a realtime channel, removing the caller (or member_id) from the roster
MCP tool: realtime_presence_leave
Parameters
| Name | In | Type | Required | Description |
|---|
| channel | body | string | • | Channel name, "namespace:rest" |
| member_id | body | string | — | Act for a synthetic member id instead of the caller identity (backend integrations) |
Response
| Field | Type | Always | Description |
|---|
| channel | string | • | Channel name |
| removed | boolean | • | Whether the member was removed |
GET/realtime/presence/stats
Get the presence member count for a channel
MCP tool: realtime_presence_stats
Parameters
| Name | In | Type | Required | Description |
|---|
| channel | query | string | • | Channel name, "namespace:rest" |
Response
| Field | Type | Always | Description |
|---|
| channel | string | • | Channel name |
| members | integer | • | Number of distinct identities present |
POST/realtime/presence/update
Update a presence member's info and/or refresh its TTL
MCP tool: realtime_presence_update
Parameters
| Name | In | Type | Required | Description |
|---|
| channel | body | string | • | Channel name, "namespace:rest" |
| info | body | string | — | Arbitrary JSON metadata for the member (<=10KB serialized) |
| ttl_seconds | body | integer | — | Presence entry TTL in seconds (1-3600) |
| member_id | body | string | — | Act for a synthetic member id instead of the caller identity (backend integrations) |
Response
| Field | Type | Always | Description |
|---|
| member | object | • | The entered/updated member |
| channel | string | • | Channel name |
GET/realtime/public-access/status
Check whether this product has a public key configured — an onboarding hint for the portal, never an authorization decision
MCP tool: realtime_public_access_status
Parameters
No parameters.
Response
| Field | Type | Always | Description |
|---|
| exists | boolean | • | Whether this product has created a public key yet (an onboarding hint, not a gate) |
GET/realtime/status
Get realtime service status: Redis fan-out connectivity, token signing key presence, gateway URL
MCP tool: realtime_status_get
Parameters
No parameters.
Response
| Field | Type | Always | Description |
|---|
| redis | string | • | Redis fan-out connectivity |
| service | string | • | API liveness marker |
| gatewayUrl | string | • | WebSocket URL of the realtime gateway |
| signingKeyConfigured | boolean | • | Whether the token signing key is present |
POST/realtime/tokens
Mint a short-lived capability token (JWT) carrying the capabilities the identity has via namespace policy and grants (optionally filtered to the given channels), plus the gateway WebSocket URL to connect to
MCP tool: realtime_tokens_create
Parameters
| Name | In | Type | Required | Description |
|---|
| channels | body | array | — | Concrete channels to filter the resolved capabilities to; omit to receive all capabilities the identity has |
Response
| Field | Type | Always | Description |
|---|
| token | string | • | Signed EdDSA capability JWT (60s TTL) |
| gatewayUrl | string | • | WebSocket URL of the realtime gateway to connect to |
GET/realtime/webhooks
List all client webhooks registered for this product (secret metadata only)
MCP tool: realtime_webhook_list
Parameters
No parameters.
Response
| Field | Type | Always | Description |
|---|
| webhooks | array | • | — |
POST/realtime/webhooks
Register a client webhook: lifecycle notifications (channel occupied/vacated, presence member added/removed) are POSTed to the URL signed with HMAC-SHA256. Returns the full signing secret ONCE.
MCP tool: realtime_webhook_create
Parameters
| Name | In | Type | Required | Description |
|---|
| url | body | string | • | Endpoint that receives signed lifecycle POSTs (https in production) |
| events | body | array | • | Lifecycle event types this webhook receives |
| description | body | string | — | Free-form note |
Response
| Field | Type | Always | Description |
|---|
| secret | string | • | Full signing secret — returned only once, at creation. Store it now. |
| webhook | object | • | — |
DELETE/realtime/webhooks/:webhookId
Delete a client webhook (its secrets and delivery log go with it)
MCP tool: realtime_webhook_delete
Parameters
| Name | In | Type | Required | Description |
|---|
| webhookId | path | string | • | Webhook id |
Response
| Field | Type | Always | Description |
|---|
| deleted | boolean | • | — |
GET/realtime/webhooks/:webhookId
Get a client webhook by id (secret metadata only, never the secret)
MCP tool: realtime_webhook_get
Parameters
| Name | In | Type | Required | Description |
|---|
| webhookId | path | string | • | Webhook id |
Response
| Field | Type | Always | Description |
|---|
| id | string | • | — |
| url | string | • | — |
| active | boolean | • | — |
| events | array | • | — |
| secrets | array | • | Secret metadata only — never the secret itself |
| createdAt | string | • | — |
| updatedAt | string | • | — |
| description | string | • | — |
PATCH/realtime/webhooks/:webhookId
Update a client webhook: url, event filter, description, active flag
MCP tool: realtime_webhook_update
Parameters
| Name | In | Type | Required | Description |
|---|
| url | body | string | — | Endpoint that receives signed lifecycle POSTs (https in production) |
| events | body | array | — | Lifecycle event types this webhook receives |
| description | body | string | — | Free-form note |
| active | body | boolean | — | Inactive webhooks receive no deliveries |
| webhookId | path | string | • | Webhook id to update |
Response
| Field | Type | Always | Description |
|---|
| id | string | • | — |
| url | string | • | — |
| active | boolean | • | — |
| events | array | • | — |
| secrets | array | • | Secret metadata only — never the secret itself |
| createdAt | string | • | — |
| updatedAt | string | • | — |
| description | string | • | — |
GET/realtime/webhooks/:webhookId/deliveries
List recent delivery attempts of a webhook (status, attempts, response code)
MCP tool: realtime_webhook_deliveries_list
Parameters
| Name | In | Type | Required | Description |
|---|
| webhookId | path | string | • | Webhook id |
| limit | query | integer | — | Max deliveries to return (newest first) |
Response
| Field | Type | Always | Description |
|---|
| deliveries | array | • | — |
POST/realtime/webhooks/:webhookId/secret/rotate
Rotate the webhook signing secret with an overlap window: the new secret signs immediately (returned ONCE), the previous one keeps verifying until its grace expiry
MCP tool: realtime_webhook_secret_rotate
Parameters
| Name | In | Type | Required | Description |
|---|
| webhookId | path | string | • | Webhook id |
Response
| Field | Type | Always | Description |
|---|
| prefix | string | • | Visible prefix of the new secret (X-Realtime-Key) |
| secret | string | • | New full signing secret — returned only once. Store it now. |
| previousExpiresAt | string | • | When the rotated-out secret stops verifying (grace window) |
Was this page helpful?Thanks for your feedback!