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

# Channels & Events

> Pusher channel naming, the contract event contract and the private-channel authorization endpoint.

## Channel contract

Channel names are built by helpers in `pusher.client.ts` — the single source of
truth shared between the publisher and the authorizer.

| Helper                        | Channel                         | Visibility | Auth required |
| ----------------------------- | ------------------------------- | ---------- | ------------- |
| `contractChannel(contractId)` | `private-contract-{contractId}` | Private    | Yes           |
| `accountChannel(accountId)`   | `private-account-{accountId}`   | Private    | Yes           |
| `totemChannel(codeRaspberry)` | `totem-{codeRaspberry}`         | Public     | No            |

<Note>
  Private channels (`private-` prefix) require a signed authorization token
  before a client may subscribe. The totem channel is public on purpose so
  touch UIs and NOC dashboards subscribe without a handshake.
</Note>

## Event contract

The contract-domain events are enumerated in `ContractPusherEvent`:

| Event                          | Emitted when                                      |
| ------------------------------ | ------------------------------------------------- |
| `contract.status_changed`      | Contract stage transition.                        |
| `contract.signature_requested` | Contract sent to the signer.                      |
| `contract.signed`              | Signature completed / contract activated.         |
| `contract.cancelled`           | Contract cancelled by an admin.                   |
| `contract.rejected`            | Signature rejected by a signer (internal signer). |
| `contract.pdf_generated`       | Reserved — no publisher wired yet.                |

## Private-channel authorizer

`POST /api/v3/realtime/pusher/auth`

<Steps>
  <Step title="Authorize">
    Requires the `pusher:auth` permission.
  </Step>

  <Step title="Validate body">
    `socket_id` and `channel_name` are both required (`400` otherwise).
  </Step>

  <Step title="Enforce namespace">
    The channel must match `^private-(contract|account)-[0-9a-f-]{36}$`;
    anything else is rejected with `403`.
  </Step>

  <Step title="Sign">
    Returns the Pusher auth payload from
    `authorizeChannel(socket_id, channel_name)`. When Pusher is not configured
    the endpoint returns `403`.
  </Step>
</Steps>

<Warning>
  The namespace regex is the security boundary: a caller holding `pusher:auth`
  can only subscribe to contract/account channels. Ownership scoping (which
  contract a user may watch) is enforced by the calling app's own session layer
  before it reaches this endpoint.
</Warning>

### Example request

```json theme={null}
{
  "channel_name": "private-contract-2f1c4e9a-3b7d-4a2e-9c88-0f1a2b3c4d5e",
  "socket_id": "123456.7890"
}
```

### Example response

```json theme={null}
{
  "auth": "<app_key>:<hmac_signature>"
}
```
