> ## Documentation Index
> Fetch the complete documentation index at: https://voyant.travel/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Realtime

> Publish and subscribe to channels with presence and history, using server-side publishing and short-lived client tokens for browsers.

The `realtime` group is Voyant's pub/sub service. Your server publishes messages to channels, and clients subscribe over WebSocket. It supports message history, presence, and short-lived client tokens so browsers can connect without ever holding your API key.

```ts theme={null}
import { createVoyantCloudClient, RealtimeChannel } from "@voyant-travel/cloud-sdk";

const client = createVoyantCloudClient({ apiKey: process.env.VOYANT_API_KEY! });
```

## Publishing from the server

Publish single messages or batches from trusted server code:

```ts theme={null}
await client.realtime.publish("orders:eu", {
  event: "order.updated",
  data: { orderId: "ord_1" },
});

await client.realtime.publishBatch({ /* multiple messages */ });
```

Read recent history and presence:

```ts theme={null}
const history = await client.realtime.history("orders:eu");
const members = await client.realtime.presence.get("orders:eu");
```

## Subscribing from a client

Browsers should never carry the API key. Instead, mint a short-lived client token on the server, scoped to the capabilities that client needs, and hand it to the front end.

```ts theme={null}
// On the server
const { token } = await client.realtime.tokens.mint({
  clientId: "user_42",
  capabilities: { "orders:*": ["subscribe", "presence"] },
});
```

```ts theme={null}
// On the client, with the minted token
const channel = new RealtimeChannel({ channel: "orders:eu", token });

channel.on("message", (message) => {
  console.log(message.event, message.data);
});
```

`RealtimeChannel` is a standalone WebSocket subscriber with auto-reconnect and `sinceId` resume. It exposes `on`, `publish`, `enterPresence`, `updatePresence`, `leavePresence`, and `close`. The minted client token, not the API key, authenticates the connection.

## Scopes

| Methods                   | Scope                |
| ------------------------- | -------------------- |
| `publish`, `publishBatch` | `realtime:publish`   |
| `history`, `presence.get` | `realtime:subscribe` |
| `tokens.mint`             | `realtime:tokens`    |

Key types: `RealtimeMessageSummary`, `RealtimePresenceMember`, `RealtimeTokenSummary`, `PublishRealtimeMessageInput`, `PublishRealtimeBatchInput`, `MintRealtimeTokenInput`, `RealtimeCapability`, `RealtimeChannelOptions`.
