> ## 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.

# Message Envelope

> Universal message wrapper — fields, ordering, and forward compatibility.

Every A2G message conforms to a universal envelope. Game-specific data lives in the `payload` field, which the core protocol routes without inspecting.

## Schema

```typescript theme={null}
interface A2GEnvelope<T = unknown> {
  type: string;              // Message type identifier
  messageId: string;         // UUID v4, unique per message
  sequence?: number;         // Monotonically increasing per session (uint64)
  protocolVersion: string;   // "1.0"
  timestamp: number;         // Unix milliseconds (sender's clock)
  gameType?: string;         // Present on gameplay messages
  tableId?: string;          // Present on gameplay messages
  payload?: T;               // Game-specific data (optional for protocol messages)
}
```

## Field Semantics

**`type`** — Identifies the message kind. MUST be one of the types defined in the specification. Unknown types MUST be ignored by receivers (forward compatibility).

**`messageId`** — UUID v4 string, unique per message within a session. Servers MUST reject duplicate `messageId` values within the same session (replay protection). Clients SHOULD generate messageIds using a cryptographically secure random source.

**`sequence`** — OPTIONAL. An unsigned 64-bit integer, monotonically increasing per sender within a session. Servers MUST increment `sequence` by 1 with each message sent to a given client. Clients SHOULD include `sequence` on messages sent to the server. Receivers MAY use sequence numbers to detect message gaps. When absent, receivers MUST NOT assume message loss.

**`protocolVersion`** — Semantic version string. REQUIRED in `hello` and the client's first `authenticate` message. OPTIONAL in subsequent messages; when absent, assumes the version negotiated during `hello`. This reduces per-message overhead for high-frequency gameplay.

**`timestamp`** — Unix milliseconds at message creation. Used for ordering and debugging, not for consensus. Clock skew between participants is expected.

**`timeoutSeconds`** — Present on `game_action_request` and `betting_window_open`. The number of seconds the client has to respond. Timeouts are enforced server-side using the server's clock. If the client does not respond in time, the server applies the default timeout action defined in the game specification.

**`gameType`** — Identifies the game (e.g., `"texas-holdem"`, `"blackjack"`, `"european-roulette"`). REQUIRED on all gameplay messages. MUST be omitted on protocol messages.

**`tableId`** — Identifies the table/room. REQUIRED on all gameplay messages. MUST be omitted on protocol messages.

**`payload`** — Game-specific data. The core protocol routes messages by envelope fields without inspecting the payload. Payload schemas are defined per game in game specifications.

## Gameplay Envelope

Messages with `gameType` and `tableId` present are gameplay messages:

```typescript theme={null}
interface GameplayEnvelope<T = unknown> extends A2GEnvelope<T> {
  gameType: string;   // Required
  tableId: string;    // Required
}
```

## Message Ordering

Servers MUST process `submit_action` messages from a single client in FIFO order (first received, first processed). This ensures deterministic gameplay and prevents race conditions.

Clients operating in multi-threaded environments MUST serialize their `submit_action` messages — send one at a time, not in parallel. Messages from different clients MAY be reordered by the server according to game rules (e.g., seat position in poker).

## Forward Compatibility

Receivers MUST ignore unknown fields in the envelope and payload. Receivers MUST ignore unknown message types. This allows minor version increments to add new fields and message types without breaking existing implementations.
