# Channels

Channels are named streams. A client opens one WebSocket connection to Vask, then subscribes that connection to one or more channels.

Use the same channel names and SDK calls you would use with Pusher Channels. Connect to `wss://wss.vask.dev/app/{app_key}` and use your Vask `app_key` as the SDK key.

## Channel types

| Type            | Prefix                     | Auth required | Tracks members | Notes                                                            |
| --------------- | -------------------------- | ------------- | -------------- | ---------------------------------------------------------------- |
| Public          | none                       | No            | No             | Any connected client with the `app_key` can subscribe.           |
| Private         | `private-`                 | Yes           | No             | Your app signs each subscription.                                |
| Presence        | `presence-`                | Yes           | Yes            | Like private channels, plus member roster and join/leave events. |
| Cache           | `cache-`                   | No            | No             | Replays the last server-triggered event to new subscribers.      |
| Private cache   | `private-cache-`           | Yes           | No             | Private channel behavior plus cache replay.                      |
| Presence cache  | `presence-cache-`          | Yes           | Yes            | Presence channel behavior plus cache replay.                     |
| Encrypted       | `private-encrypted-`       | Yes           | No             | Private channel behavior plus SDK-managed encryption.            |
| Encrypted cache | `private-encrypted-cache-` | Yes           | No             | Encrypted channel behavior plus cache replay.                    |

## Public channels

Public channels do not call your auth endpoint. Use them only for data that can be read by anyone who knows the channel name.

```js
const pusher = new Pusher('app_key', {
    wsHost: 'wss.vask.dev',
    wsPort: 443,
    forceTLS: true,
    enabledTransports: ['ws', 'wss'],
});

const channel = pusher.subscribe('public-feed');
channel.bind('message.created', (event) => {
    console.log(event);
});
```

## Private channels

Private channels require a server-side authorization response. The SDK posts `socket_id` and `channel_name` to your auth endpoint, then sends the returned `auth` value in the `pusher:subscribe` frame.

```js
const channel = pusher.subscribe('private-dashboard.42');

channel.bind('metric.updated', (event) => {
    console.log(event);
});
```

Your auth endpoint decides whether the current user can subscribe.

```json
{
    "auth": "app_key:hmac_signature"
}
```

## Presence channels

Presence channels use the same authorization flow as private channels, but the response also includes JSON-encoded `channel_data`.

```json
{
    "auth": "app_key:hmac_signature",
    "channel_data": "{\"user_id\":\"user-123\",\"user_info\":{\"name\":\"Ada\"}}"
}
```

The `user_id` is the identity Vask uses for the roster. If the same user has several tabs open, they count as one presence member.

```js
const room = pusher.subscribe('presence-room.42');

room.bind('pusher:subscription_succeeded', (members) => {
    console.log(members);
});

room.bind('pusher:member_added', (member) => {
    console.log(member.id);
});

room.bind('pusher:member_removed', (member) => {
    console.log(member.id);
});
```

## Naming rules

Channel names should be stable ASCII strings. Keep names short and application scoped.

```text
public-feed
private-user.123
presence-document.456
cache-market-data.BTCUSD
private-encrypted-chat.789
```

Do not put secrets in channel names. Private and presence channels enforce access through the auth signature, not through obscurity.

## Related docs

- [Authentication and signatures](/docs/authentication)
- [Cache channels](/docs/cache-channels)
- [Encrypted channels](/docs/encrypted-channels)
- [HTTP API reference](/docs/http-api)
