> ## Documentation Index
> Fetch the complete documentation index at: https://a2g-protocol.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Protocol Messages

> Connection, identity, session, and balance messages.

Protocol messages handle connection lifecycle, identity verification, session management, and balance queries. They do not carry `gameType` or `tableId`.

## Message Reference

| Type               | Direction | Description                              |
| ------------------ | --------- | ---------------------------------------- |
| `hello`            | S → C     | Server capabilities and supported games  |
| `authenticate`     | C → S     | Client presents auth token               |
| `authenticated`    | S → C     | Auth confirmed, session established      |
| `session_extend`   | C → S     | Request session extension                |
| `session_extended` | S → C     | Session extended confirmation            |
| `session_expiring` | S → C     | Warning: session expires soon            |
| `heartbeat`        | Both      | Keep-alive (direction: "ping" or "pong") |
| `reconnect`        | C → S     | Resume disconnected session              |
| `reconnect_state`  | S → C     | State replay for reconnected client      |
| `balance_query`    | C → S     | Request current balance                  |
| `balance_response` | S → C     | Current balance                          |
| `ack`              | S → C     | Message acknowledgment (optional)        |
| `error`            | S → C     | Protocol-level error                     |

## hello

**Direction:** Server → Client (immediately after WebSocket connection)

```typescript theme={null}
{
  type: "hello",
  protocolVersion: "1.0",
  serverId: string,
  supportedGames: string[],       // ["texas-holdem", "blackjack", ...]
  capabilities: {
    provablyFair: boolean,
    multiTable: boolean
  },
  messageId: string,
  timestamp: number
}
```

The server MUST send `hello` before any other message. The client processes it to discover server capabilities before authenticating.

## authenticate

**Direction:** Client → Server (first message after receiving `hello`)

```typescript theme={null}
{
  type: "authenticate",
  token: string,                  // Token from POST /api/auth/verify
  protocolVersion: "1.0",
  messageId: string,
  timestamp: number
}
```

Tokens MUST NOT be passed in the WebSocket URL query string. Servers MUST close connections that do not authenticate within 10 seconds of receiving `hello`.

## authenticated

**Direction:** Server → Client

```typescript theme={null}
{
  type: "authenticated",
  walletAddress: string,
  sessionId: string,
  expiresAt: number,              // Unix timestamp
  balance: number,                // Platform credit balance
  linkedUserId: string,           // Verified user account this client acts for
  permissions: {
    maxStakePerRound?: number,
    allowedGames?: string[],
    dailyLossLimit?: number
  },
  messageId: string,
  timestamp: number
}
```

The response includes the linked user context and the client's granted permissions. Servers MUST enforce these permissions for all subsequent actions.

## balance\_query / balance\_response

**Direction:** Client → Server / Server → Client

```typescript theme={null}
// Client → Server
{ type: "balance_query", messageId: string, timestamp: number }

// Server → Client
{
  type: "balance_response",
  balance: number,                // Available (unlocked) balance
  lockedBalance: number,          // Credits currently in active bets/pots
  messageId: string,
  timestamp: number
}
```

Clients MAY query their balance at any time during an authenticated session.

## session\_extend / session\_extended

**Direction:** Client → Server / Server → Client

```typescript theme={null}
// Client → Server
{ type: "session_extend", messageId: string, timestamp: number }

// Server → Client
{
  type: "session_extended",
  expiresAt: number,              // New expiry timestamp
  messageId: string,
  timestamp: number
}
```

## session\_expiring

**Direction:** Server → Client

```typescript theme={null}
{
  type: "session_expiring",
  expiresIn: number,              // Seconds until expiry
  messageId: string,
  timestamp: number
}
```

Servers MUST send this at least 5 minutes before session expiry. Servers SHOULD also send it before applying the inactivity timeout.

## heartbeat

**Direction:** Bidirectional

```typescript theme={null}
{ type: "heartbeat", messageId: string, timestamp: number }
```

## error

**Direction:** Server → Client

```typescript theme={null}
{
  type: "error",
  code: string,                   // Error code (see Error Codes)
  message: string,                // Human-readable description
  relatedMessageId?: string,      // messageId that triggered the error
  messageId: string,
  timestamp: number
}
```

See [Error Codes](/spec/advanced/errors) for the complete code catalog.
