The Event Creator screen publishes through the ClutchCall control plane, which signs nothing you have to think about. The Equivalent cURL card on that screen shows the other path: a direct, signed POST to the engine’s HTTP plane, which is what your own server code does. That request carries five query parameters — auth_key, auth_timestamp, auth_version, body_md5 and auth_signature — and the engine rejects it if the signature does not match. This page documents how to build that request by hand, and what the queued result on the API response card means.

The publish endpoint and its query parameters

<ws-host> and <app_id> are filled in for you in the cURL card — the app id is also shown in the pill next to the page title. Content-Type is application/json. Only auth_signature is excluded from the material that gets signed; every other parameter above is part of it.

Request body and encoding the data field

The body is a JSON object with three fields:
  • name — the event name. This is the name subscribers bind to.
  • channels — an array of channel names. The Event Creator publishes to one channel at a time, so the card emits a single-element array.
  • data — a JSON-encoded string, not a nested object. The Data textarea in the console holds a JSON object; the card serialises that object and puts the resulting string in data. Client-side, the payload is parsed back out of that string.
If you build the request in your own code, the equivalent of what the card does is JSON.stringify(payload) for the data field, then JSON.stringify again for the whole envelope.

Computing body_md5

body_md5 is the lowercase hex MD5 digest of the serialised request body — the same bytes you pass to -d. Compute it after you have finished building the body; any whitespace or key-order change invalidates it.
Because the digest covers the body, you cannot reuse a signature across two publishes even if the channel and event are identical.

Building the sign-string and the auth_signature HMAC

The sign-string is three lines joined with a single \n (no trailing newline):
Line by line:
  1. The HTTP method, uppercase: POST.
  2. The request path only — no scheme, no host, no query string.
  3. The query parameters, excluding auth_signature, sorted by parameter name and joined with &. Use the raw values here, not URL-encoded ones.
Sorted by name, the four parameters always come out in the order shown above: auth_key, auth_timestamp, auth_version, body_md5. If you add any other query parameter, it has to be folded into the same sorted list. auth_signature is then the lowercase hex HMAC-SHA256 of that sign-string, keyed with your app secret:
Send the request with that URL and the exact body string you hashed:
The app secret only ever lives on your server. It is the key to the HMAC and is never transmitted.

Channel and event name rules

The console validates the same shapes the control plane enforces, so a name that the Event Creator rejects will not work over REST either:
  • Channel name — required, at most 164 characters, and may contain only letters, digits and _ - = @ , . ;. This is the realtime protocol’s channel grammar: a stock client refuses to subscribe to anything outside it, so publishing to such a name publishes into the void.
  • Event name — required, at most 200 characters.
Channel prefixes are not restricted on the publish side. private- and presence- channels are legitimate publish targets, because a signed REST caller (or the console’s control plane) is an authorized publisher. The prefix governs who may subscribe, not who may publish.

Response codes and error bodies

A successful publish returns a 2xx and the console shows the green ok pill with the event and channel name. When the engine rejects the publish, the control plane surfaces the engine’s HTTP status and its response body unchanged. On the API response card that appears as a warning pill carrying the status code, the line Publish failed (HTTP <status>), and the raw response body rendered as JSON underneath. Read that body — it is the engine’s own error, not a control-plane wrapper, so it is the same text your server SDK would see from a direct signed call. Two failure modes never reach the engine at all:
  • Invalid JSON in the Data field. The console parses the textarea before sending and reports Invalid JSON: <message> inline. The Data field’s valid JSON / invalid indicator tracks this as you type.
  • Shape validation. An empty or malformed channel or event name is reported under the field and the request is not sent.

Accepted-but-queued delivery semantics

Publishes issued from the console do not go over the signed HTTP plane. The control plane pushes the publish body onto the engine’s generic ring buffer — clutchcall:realtime:ring, the same bus the presence and assist bridges ride. That is why console publishing needs no per-deployment HTTP configuration: the publisher is always reachable, even when the engine is not. The consequence is a third outcome besides success and failure. The response carries a wired flag: queued is an acceptance, not an error: the card reads “Queued — engine offline; will deliver when the engine reconnects.” The event sits on the ring and is delivered when an engine comes back and drains it. Subscribers that are connected at that later moment receive it then; the publish is not replayed to clients that were subscribed at the original publish time and have since gone away. Treat queued as a signal to check engine health before you interpret a silent client as a publishing bug. If you see queued for a publish that you expected to be live, the event is not lost — the engine link is down.

Publishing from the console instead of signing

For one-off tests, the Event Creator is the shorter path: it publishes through the control plane with your org credentials, so there is no auth_key, body_md5 or HMAC to build, and private- / presence- channels work without extra setup. Use the signed REST endpoint when the publisher is your own backend, and reach for the Equivalent cURL card to get a copy-paste starting point that already mirrors the channel, event and payload you typed into the form.
  • Authentication — where app keys and secrets sit relative to client tokens
  • Telemetry — the metric and trace streams that cover publishes