This page has two complete, runnable builds. Each combines a channel type, an auth endpoint, and a server publisher into a real feature. Both use stock pusher-js and the stock Pusher server libraries. Only the host changes. Everything below drops straight into an existing Pusher codebase.

Live presence list

Build a “who’s online” roster on a presence-* channel. An auth endpoint signs the subscription. A client tracks members that join and leave in real time.

Server-pushed notifications

Your backend triggers events. The browser binds and renders them. The feature continues to work across reconnects because channel state is restored on resubscribe.
Every snippet assumes that you created an app in the Realtime Console. You need its key, secret, and app ID. The key is public (it ships in the browser bundle). The secret is server-only.

The one-line switch

To run on ClutchCall, change only the host. Keep your key, your channel names, your event names, and your handlers.
To use the QUIC transport instead of WebSocket, swap pusher-js for the WebTransport/QUIC-capable fork. The fork speaks the identical Pusher protocol over an HTTP/3 connection (/app/<key>). The recipes below are unchanged. See SDK & API for which client to install.

Recipe 1 — Live presence list

Presence channels (presence-*) are private channels that also carry a member roster. On subscribe, you get the current members and every subsequent join and leave. You can render “who’s online” with no polling. Presence channels are authorized, so you need a small auth endpoint. ClutchCall checks its HMAC exactly like Pusher does. Sign the subscription with the stock server library’s authorizeChannel.
1

Add the auth endpoint

When the browser subscribes to a private-* or presence-* channel, pusher-js POSTs the socket_id and channel_name to your channelAuthorization.endpoint. Return the signed payload. For presence, attach the member’s user_id and public user_info. Other clients see these fields in the roster. Put only display-safe fields here.
The auth endpoint is your trust boundary. Never take the user_id from the browser. Derive it from your own authenticated session. A caller of this endpoint can appear in the roster as any identity that the endpoint returns.
2

Subscribe and render the roster

On the client, subscribe to a presence-* channel and read members. The pusher:subscription_succeeded event gives you the initial roster. pusher:member_added / pusher:member_removed keep the roster live.
3

React to presence from your backend (optional)

Register the Presence webhook group in the console to receive member_added / member_removed server-side. This is useful for “mark user offline” logic without an open socket. See console → webhooks for the delivery format and for how to check the X-Pusher-Signature HMAC.
A member’s presence is derived from their live connection. ClutchCall sends member_removed when a client’s last tab closes, or when the network drops for long enough. The roster corrects itself without a client-side heartbeat. Fan-out spans shards and edge nodes automatically. You never run or name a message broker.

Recipe 2 — Server-pushed notifications

This is the classic pattern. Your backend does work (an order ships, a job finishes). You want the result to appear instantly in the user’s browser. Publish from the server with trigger(). Bind on the client. Use a private per-user channel (private-notifications-<userId>). Then only the authorized user receives their notifications. Reuse the same auth endpoint from Recipe 1.
1

Publish from the server

Call trigger(channel, event, data) anywhere in your backend. That single call fans the event out to every connected subscriber of that channel across the mesh.
The REST body’s data is a string, exactly as in the Pusher HTTP API. JSON-encode your payload before you put it in the field. The server libraries do this for you. The server libraries also do the authenticated publish (they sign the request with your app secret). See console → publish a test event to try it from the browser first.
2

Bind on the client

Subscribe to the user’s private channel and bind the event. To show a toast, increment a badge, or play a sound, write a handler.
3

Survive reconnects

Connections drop. Laptops sleep. Phones switch from WiFi to cellular. You do not re-subscribe by hand. When the socket comes back, pusher-js replays your subscriptions and runs your auth endpoint again automatically. Where possible, ClutchCall carries the connection across a network change without a full reconnect. Bind the connection lifecycle to drive UI. Backfill any events that were possibly published while you were offline. The channel is live-only, so durable state comes from your own API.
Treat realtime as the fast path, not the system of record. On reconnect, a short GET …?since=<cursor> closes the gap for the rare window where the socket was down while your server published. The pattern is the same one that you use with hosted Pusher.
Notification fan-out uses the same trigger() → subscriber path as presence. The path spans shards and edge nodes. You publish once. The mesh delivers to every online subscriber of the channel.

Honest gaps

Shipped and used above: public / private-* / presence-* channels, HMAC subscription auth, client-* events, server trigger(), the REST publish API, and the channel-existence + presence webhook groups.Still rolling out: some webhook and batch-delivery features (for example, batched event webhooks and larger multi-channel publishes) are in preview. They can lag the hosted Pusher feature set. If a build depends on one of them, check it in the Realtime Console for your app before you ship.

Details

The channel model, transports (WebSocket and QUIC), and how fan-out works.

SDK & API

The client, server-publish, and auth surfaces, and which pusher-js to use.

Cookbook

Shorter copy-paste snippets: subscribe, private auth, client events, webhooks.

Console

Create apps and keys, publish test events, see live stats, and configure webhooks.