Docs

Chat messages

Send, edit, and delete messages, and load chat message history.

Messages are the core of a room. Each one has a stable id its sender assigns, so edits and deletes reference it, your UI can render optimistically, and resends never duplicate.

Send

const message = await room.messages.send({ text: 'hello' });
console.log(message.id);

send returns the message immediately with its id filled in, so you can render it without waiting for the round trip. Besides text, a message can carry metadata (structured data your app reads, like an attachment reference) and headers (the same idea, kept separate so UI concerns and app concerns don’t fight over one object).

Subscribe

const off = room.messages.subscribe((event) => {
  switch (event.type) {
    case 'created': add(event.message); break;
    case 'updated': replace(event.message); break;
    case 'deleted': replace(event.message); break;
  }
});

Every event carries the message’s full current state, so handling an update or delete is always “replace what you have”, never patch arithmetic. Events arrive in order even when the network delivers frames out of order, because the client reconciles by version: a stale edit never overwrites a newer one, and duplicates are dropped.

Edit and delete

await room.messages.update(message.id, { text: 'hello (fixed the typo)' });
await room.messages.delete(message.id);

update replaces the message body. Fields you omit are cleared, so pass metadata again if the edit should keep it. delete leaves a tombstone: the message keeps its id and sender but its text becomes empty and deleted becomes true, which is what lets a UI show “message deleted” in place.

The message object

Field Type Meaning
id string Stable id, assigned by the sender
clientId string Who sent it
roomName string The room it belongs to
text string The body, empty once deleted
metadata, headers object App data carried with the message
createdAt Date When it was sent
updatedAt Date When it was last edited, equals createdAt until then
deleted boolean True once deleted

Chat message history

const page = await room.messages.history({ limit: 50 });

for (const message of page.messages) {
  render(message);  // Oldest first, edits and deletes already applied
}

if (page.hasMore) {
  const older = await room.messages.history({ limit: 50, cursor: page.nextCursor });
}

History returns messages in their current state, not as a raw event log. A message that was edited comes back with its edited text, and a deleted one comes back as its tombstone, so rendering the backlog is the same code as rendering live events. Page backward by passing nextCursor until hasMore is false.

How far back history reaches is the room channel’s retention: chat: channels store messages at your plan’s ceiling by default, adjustable per prefix with a channel rule.

Capabilities

Sending, editing, and deleting need publish on the room’s channel, receiving needs subscribe, and history needs history. See Authentication and capabilities.