The toast endpoints power realtime in-app notifications. The flow is:Documentation Index
Fetch the complete documentation index at: https://docs.manticscore.com/llms.txt
Use this file to discover all available pages before exploring further.
- Exchange a Clerk session for a short-lived WebSocket token.
- Open a WebSocket to the realtime gateway with that token.
- Subscribe to one or more topics (always within your own user namespace).
- (Optional) Register an APNS token so undelivered toasts fall back to a push notification.
Bootstrap a WebSocket token
Mint a short-lived WebSocket token bound to a (user, device) pair. Clients call this with their Clerk session, then open a WebSocket to the URL returned in the response. Rate limit: 30 requests per minute.Optional. Informational mirror of the Clerk JWT — the
Authorization header is the source of truth and is verified by the auth middleware. Provided so callers can document the binding explicitly; the body field is not re-verified.Stable per-device identifier. Optional — when omitted, the server synthesizes a deterministic id of the form
clerk:<user_id> that is stable across reconnects. Pass an explicit value when two devices on the same Clerk account need to differentiate themselves (separate APNS tokens, distinct presence rows).iOS bundle identifier of the calling app.
Topics to pre-subscribe at connect. Topics outside the user’s own namespace are silently dropped — only
user:<user_id>:* and arbitrary non-user:* topics are allowed. When the array is empty, the server inserts user:<user_id> so first-connect subscriptions work without any client-side topic plumbing.200 response
Short-lived WebSocket token (15-minute TTL). Treat as a credential.
Pre-formatted WebSocket URL with the token embedded as a query parameter.
ISO 8601 timestamp when the token expires. Re-bootstrap before this to maintain a continuous connection.
The subset of
default_topics that passed the namespace check.Register a device for APNS fallback
Register (or refresh) an iOS device for APNS fallback delivery. Toasts dispatched while no foreground WebSocket is connected are forwarded to APNS instead of dropped. Rate limit: 30 requests per minute.Stable per-device identifier; must match the one used in
toast-bootstrap. If the bootstrap call omitted device_id, pass the synthesized clerk:<user_id> value here.iOS bundle identifier.
200 response
Publish a toast from an external service
External publishers (separate services or scripts) call this endpoint to deliver a toast to a user. Internal services should callservices.toasts.publish_toast() directly instead — no HTTP round-trip, no shared secret.
Rate limit: 120 requests per minute.
TOAST_PUBLISH_SECRET_KEY:
Recipient Clerk user id.
Topic to publish on. Subscribers receive only the topics they have explicitly subscribed to.
Optional. The server drops a toast if another with the same
dedupe_key was delivered to this user recently.Optional. The client collapses toasts that share a
collapse_key, replacing the previous one in place.Optional. Server-side TTL after which the toast is dropped if not delivered.
When
true, the server falls back to APNS if the user has no foreground WebSocket connection.202 response
401 invalid_publish_key if the bearer is wrong, and 503 toast_publish_disabled if the secret is unset server-side.
List recent toasts for the current user
Replay surface for the authenticated user. Useful for a notification-center UI. Rate limit: 60 requests per minute.Page size, range 1–200.
200 response
WebSocket realtime gateway
Open a multiplexed WebSocket to receive toasts in realtime.POST /v1/sessions/toast-bootstrap and expires after 15 minutes. Connections with an expired or unknown token receive an error frame and a close with code 4001. Connections without a token are closed with code 4002.
Server frames
On successful connect, the server immediately sends:Client messages
The client may send the following JSON messages:- subscribe
- unsubscribe
- client_state
- ping
error frame of code topic_not_allowed.Close codes
| Code | Meaning |
|---|---|
4001 | Token expired or rejected after upgrade. |
4002 | Missing token at connect. |
The realtime gateway is multi-worker safe. The publisher uses a Redis pub/sub channel keyed on the user, so any worker holding a foreground connection delivers the toast — APNS fallback is only used when no worker has a connection.
Silent control envelopes
The same WebSocket also carries silent control messages with envelope{"type": "control", "control": {"kind": "...", "params": {...}, "ts": "..."}}. These are dispatched by the server when state the client cares about changes — for example:
usage.changed— fired when an entitlement transitions (RC webhook event, Apple server-to-server notification, or admin credit grant). The client refetchesGET /v1/usage.flags.changed— broadcast to all clients when CMS feature flags update.
onControl handler so they do not surface as toast overlays.