Skip to main content

Broadcast

Send messages to all clients in a channel — perfect for chat, notifications, and collaborative features.

Send a Message

const channel = client.realtime.channel('chat-room');

channel.send('message', {
text: 'Hello everyone!',
sender: 'Jane',
});

Listen for Messages

// Listen for a specific event type
channel.on('message', (payload, meta) => {
console.log(`${meta.userId}: ${payload.text}`);
});

// Listen for all messages
channel.onMessage((event, payload, meta) => {
console.log(`[${event}]`, payload);
});

Self-Receive Behavior

By default, broadcast messages are not sent back to the sender (excludeSelf defaults to true). To receive your own messages, explicitly set excludeSelf: false:

// Default: you do NOT receive your own messages
channel.send('message', { text: 'Hello' });

// Opt-in: receive your own messages
channel.send('message', { text: 'Hello' }, { excludeSelf: false });

WebSocket Message Format

Under the hood, the SDK sends a broadcast message with an optional excludeSelf field:

{
"type": "broadcast",
"event": "cursor-move",
"payload": { "x": 100, "y": 200 },
"excludeSelf": true
}
FieldTypeDefaultDescription
eventstringCustom event name
payloadobjectJSON data to broadcast
excludeSelfbooleantrueWhen true, the sender does not receive their own broadcast. Set to false to include the sender in broadcast recipients.

Broadcast Event Format

When a broadcast message is received, the server delivers it as a broadcast_event:

{
"type": "broadcast_event",
"event": "message",
"payload": { "text": "Hello everyone!", "sender": "Jane" },
"senderId": "conn_abc123",
"userId": "user_456"
}
FieldDescription
eventThe custom event name passed to send()
payloadThe JSON data passed to send()
senderIdUnique connection ID of the sender
userIdAuthenticated user ID of the sender

Channel Security

Broadcast channels use realtime.namespaces rules in edgebase.config.ts. Two rules are available:

  • subscribe — Who can join the channel and receive messages
  • publish — Who can send messages to the channel
realtime: {
namespaces: {
'broadcast:chat-*': {
access: {
subscribe(auth) { return auth !== null },
publish(auth) { return auth !== null },
},
},
'broadcast:public-*': {
access: {
subscribe() { return true }, // Anyone can listen
publish(auth) { return auth !== null }, // Only authenticated can send
},
},
},
}

Channels with no matching rule default to authenticated users only (deny by default, regardless of release mode). See Access Rules for the full security model.

Server-Side Broadcast

Admin SDKs can broadcast messages via the REST API, bypassing channel rules (Service Key = admin authority). That applies across all Admin SDKs.

import { createAdminClient } from '@edgebase/admin';

const admin = createAdminClient('https://my-app.edgebase.dev', {
serviceKey: process.env.EDGEBASE_SERVICE_KEY,
});

await admin.broadcast('chat-room', 'message', {
text: 'System announcement',
sender: 'system',
});

REST Endpoint

POST /api/realtime/broadcast

Headers:

  • X-EdgeBase-Service-Key: <your-service-key> (required)
  • Content-Type: application/json

Body:

{
"channel": "chat-room",
"event": "message",
"payload": { "text": "System announcement" }
}

Responses:

StatusDescription
200{ "ok": true }
400Invalid JSON or missing channel/event
401Invalid Service Key
403Service Key required

App Functions Integration

Inside App Functions, use context.admin.broadcast():

export default async function onPostCreate(doc, context) {
await context.admin.broadcast('updates', 'new-post', {
id: doc.id,
title: doc.data.title,
});
}
Broadcast vs Room

Broadcast is fire-and-forget pub/sub messaging — there's no server-side state. If you need server-authoritative state management (game logic, collaborative editing, etc.), use Room instead.