The Event Creator screen triggers a single event on the selected app and shows the raw result inline. It is the console equivalent of pusher.trigger(). This page explains what the button actually does, how to read the response card, and how to turn the form into a signed REST request that your own server can send. The screen needs three things before it will publish: a signed-in session, an org, and a selected app. Without a session it prompts you to sign in at the portal; without an app it sends you to Apps & keys.

What the console publish does differently from a signed REST call

The console does not sign a REST request. It calls the control-plane procedure realtime.publish (an org-scoped procedure) with { orgId, appId, channel, event, data }. The control-plane API then RPUSHes the publish body onto the engine’s generic BFF-to-engine ring (clutchcall:realtime:ring) — the same bus the presence and assist bridges ride. Two consequences follow, and they are the reason console results can differ from your server’s results:
  • No per-deployment HTTP configuration is involved. The publisher is always reachable from the console, because it writes to the ring rather than to an engine HTTP endpoint.
  • The control-plane API is an authorized publisher. private-* and presence-* channels are legitimate targets from this screen, and the form never blocks those prefixes. Channel authorization that a browser subscriber would have to pass does not apply to the publish side here.
Your own server, by contrast, posts to the engine’s Pusher-compatible REST plane with an HMAC signature. See Turning the form into a signed REST request.

Reading the three response states

The API response card renders one of three outcomes, driven by the ok and wired fields of the procedure result. Before you press Send event, the card shows an empty state: “No response yet.” A fourth outcome is not part of the card at all — see Telling a transport failure from a rejected publish.

Queued delivery and what it guarantees

queued is a success state, not a failure. The ok: true means the control-plane API wrote your publish body onto the BFF-to-engine ring. The wired: false means it could not observe an engine heartbeat at that moment. The engine picks the entry up when it reconnects and drains the ring. What the state tells you:
  • The body was accepted. You do not need to retry the form to get the event onto the ring; retrying enqueues a second copy.
  • Delivery is deferred, not cancelled.
What the state does not tell you:
  • It does not confirm delivery. Fan-out to channel subscribers happens engine-side after the ring is drained. Nothing in this response reflects whether any subscriber received the event.
  • It does not carry a hold time or a delivery deadline. The response has no expiry field, and the console does not display one. Treat “delivers when the engine reconnects” as the whole of the contract.
  • It is not a replay mechanism. The ring is a handoff to the engine, not subscriber-facing history. Whether a client that connects in the interim sees the event depends entirely on when the engine drains the ring relative to that client’s subscription — the console cannot tell you which came first.
If you need to confirm the event actually reached clients, observe it on a subscriber rather than inferring it from this card.

Telling a transport failure from a rejected publish

The screen surfaces three distinct classes of failure in three distinct places. They mean different things: The distinction that matters: a mutation error means “we never got an answer,” while ok: false means “we got an answer and it was no.” Only the second one has an HTTP status and a response body to read.

Channel and event name validation

The form validates shape before it sends anything. Errors appear underneath the offending input once you have pressed Send event at least once. Channel
  • Required.
  • Maximum 164 characters.
  • Must match [A-Za-z0-9_\-=@,.;]+ — letters, digits, and _ - = @ , . ; only.
The character rule is the Pusher protocol channel-name rule. A stock pusher-js client refuses to subscribe to a name outside that set, so publishing to one is publishing into the void. The control-plane API enforces the same rule, so bypassing the form does not help. Channel prefixes are deliberately not restricted. private-orders (the default) and presence-* names are accepted because the control-plane API publishes as an authorized publisher. Event name
  • Required.
  • Maximum 200 characters.
Data Must parse as JSON. The field shows valid JSON or invalid live as you type, and Send event is disabled while the payload is invalid. The parsed object — not the raw text — is what goes to the procedure.

Turning the form into a signed REST request

The Equivalent cURL card mirrors your current form values as a request against the engine’s external Pusher-compatible REST plane. This is the shape your own server SDK sends; it is not the path the console itself takes.
Points to carry across when you write this by hand:
  • The endpoint is POST /apps/{app_id}/events on the engine host, with the app id from the pill at the top of the screen.
  • data is a JSON-encoded string, not a nested object. The console re-serializes whatever you typed in the Data textarea into a string for this snippet. Sending an object instead of a string is the most common cause of a rejected publish.
  • channels is an array, even for a single channel.
  • Authentication is query-string HMAC, not a bearer header: auth_key, auth_timestamp, auth_version=1.0, body_md5, and auth_signature. The signature is HMAC-SHA256 of the sign-string with your app secret, and body_md5 is the MD5 of the exact request body you send — recompute both if you edit the payload.
Because this path authenticates with the app secret rather than an org session, its authorization outcome can differ from the console’s. A publish that succeeds from the Event Creator can still be rejected here if the key or signature is wrong; that arrives as a non-2xx status, the REST-plane equivalent of the Publish failed state above.