Skip to content

Developers · GraphQL

WebSocket Mutations

Last updated 1 November 2026

The channel_send_message mutation: push a JSON message to every browser in a channel room.

One mutation sends messages over WebSockets: channel_send_message. It pushes a JSON payload to every browser subscribed to a channel and room. Use it to show a result that finishes after the page has loaded. Examples are a slow API reply from a background job, the progress of an import, or a new order on a dashboard.

channel_send_message

channel_send_message(
  channel_name: String!
  room_id: String!
  payload: JSONPayload!
): String
ArgumentTypeMeaning
channel_nameString!The channel, as the subscribing browsers name it
room_idString!The room within the channel. Everyone in the room gets the message
payloadJSONPayload!The message: any JSON value, passed through unchanged

It returns the string dispatched. It does not run the channel's receive partial.

Example: send a reply to a room

app/graphql/ask/send_reply.graphql

mutation send_reply($room: String!, $reply: JSONPayload!) {
  channel_send_message(channel_name: "replies", room_id: $room, payload: $reply)
}
{% liquid
  assign reply = {}
  assign reply['text'] = 'Done'
  graphql sent = 'ask/send_reply', room: room, reply: reply
%}

A hash passed as payload arrives in the browser as a JSON object. This works from a background job, which has no browser of its own: the room is how the job finds the page.

Note

This page shows a mutation, so it was not run on the docs instance. The example is the measured one in the Insites Logic Engine websockets reference.

Before a browser can receive it

  • The channel needs app/views/partials/channels/<channel>/subscribed.liquid. It must output true to admit a subscriber. With no partial, everyone is refused.
  • The browser connects to /websocket with the page's authenticity_token in the URL. Without the token the connection is closed.
  • A page that only listens can use Server-Sent Events at /anycable-events instead. The same message reaches both.

Common mistakes

  • Putting private data in a shared room. Anyone holding a room id can subscribe, so the room is the boundary. Sign room ids with a secret constant.
  • Checking context.session in the subscribed partial. It is null there.
  • Expecting a reply over Server-Sent Events to carry an envelope. The payload arrives bare.