Skip to main content
This page covers the current version of Realtime. In Realtime (Legacy), a message is an opaque payload broadcast to the channel, and the only place logic can run is a single channel trigger.

What a message is

A message is the invocable handler inside a channel. It is the Realtime equivalent of an API endpoint, and it has the same parts: Because a message is a named handler rather than an untyped broadcast, the client sends “invoke send with this payload” rather than “push these bytes to everyone on the channel.”

Payload schema

Every message declares the payload it accepts, with types, exactly the way an API endpoint declares its inputs. Xano validates the incoming payload against that schema before any of your logic runs — a malformed payload is rejected at the boundary, not halfway through a function stack that has already written to your database. This is the single biggest practical difference from legacy Realtime, where the payload is whatever the client sent and validating it is your job inside the trigger.

In XanoScript

A message names both the server and the channel it belongs to, because a channel path is unique only within its server.
XanoScript
realtime_server, channel, input, stack, and response are required. deliver_to, description, history, middleware, and tags are optional.

The function stack

From the payload onward, a message is an ordinary Xano function stack. Everything you use in an API endpoint is available: database queries, custom functions, external API requests, conditionals, loops, and middleware. You also get the same authoring tools:
  • Canvas, stack, XanoScript, and split-screen editing
  • DB Preview, to see the effect of database steps while you build
  • Run & Debug, to execute a message handler without attaching a client
  • Drafts and publish, so a half-finished handler isn’t live
  • Branches, diffs, and version history

Delivery

deliver_to is chosen per message and decides who receives the result:
deliver_to = "sender" turns a websocket into a request/response channel. The client invokes a message, your stack does the work, and the result comes back over the same open connection — no second HTTP round trip, and no fan-out to clients that don’t care.
The guarantee for those deliveries — at_most_once or at_least_once — is a channel setting rather than a message one. See Delivery guarantees.

Rewriting a delivery per recipient

Delivery isn’t all-or-nothing. A channel’s deliver trigger runs once per recipient and can rewrite or drop that individual copy — so one publish becomes N personalized or redacted deliveries. See Realtime Triggers.

Requiring authentication

A message can require authentication independently of whether the channel allows anonymous clients to join. That means a channel can be open to read — anonymous clients join and receive broadcasts — while the messages that write to it are restricted to authenticated clients. Because it’s per message, one channel can mix them: a typing indicator open to everyone, and a send handler that isn’t. See Access Control.

Observability

Message executions appear in Request History under a Messages tab. Retention is set per object with the history clause, which accepts false, "inherit", a record count (0, 10, 100, 1000, 10000), or "all".

Next steps

Realtime Triggers

Run logic on connect, disconnect, join, leave, and deliver.

Publishing from Xano

Push to a channel from any query, function, or task.