# Realtime

Channels, tickets, presence and live logs.

> Section: Realtime

## Create a channel

A channel belongs to exactly one project. A channel with the same name in another project is a different channel.

```bash
veltic realtime channels create PROJECT_ID orders "Order status"
```

## Test in two terminals

Start the listener first, then publish from a second terminal.

```bash
veltic realtime listen PROJECT_ID orders
veltic realtime publish PROJECT_ID orders created '{"id":1}'
```

## Connect a browser client

Request a short-lived ticket from the dashboard and connect directly to the realtime endpoint with it. The dashboard cannot terminate the WebSocket itself, because serverless functions cannot hold a persistent connection. Grant only the publish or subscribe permissions the client needs.

```typescript
const ticket = await fetch('/api/realtime/ticket', {
  method: 'POST',
  body: JSON.stringify({ channels: ['orders'], mode: 'subscribe' })
}).then(response => response.json());

const socket = new WebSocket(`${ticket.endpoint}?ticket=${ticket.token}`);
```

## Live logs

logs:app:<name> and logs:function:<name> are a reserved namespace. Nobody creates them: the ticket grants them through a prefix after checking app.read or function.read and that the resource exists, and it grants subscribe only, so no client can forge a log line. Payloads are raw excerpts batched every 250 milliseconds; anything over 32 KB is dropped and flagged as truncated.

## Realtime is not an archive

Messages reach whoever is connected at the time. Store anything that matters in PostgreSQL and resynchronize state after a reconnect.
