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

# Envelope & Payload

> The universal message wrapper that makes A2G game-agnostic.

Every A2G message uses a universal envelope that carries routing and lifecycle fields. Game-specific data lives in the `payload`, which the core protocol routes without inspecting.

This separation is what makes A2G game-agnostic — the core protocol handles identity, sessions, and message routing identically whether the game is poker, blackjack, or something that doesn't exist yet.

## The Envelope

```typescript theme={null}
interface A2GEnvelope<T = unknown> {
  type: string;              // Message type (e.g., "game_action_request")
  messageId: string;         // UUID v4 — unique per session, used for replay protection
  sequence?: number;         // Monotonically increasing per session (uint64)
  protocolVersion: string;   // "1.0"
  timestamp: number;         // Unix epoch milliseconds (sender's clock)
  gameType?: string;         // Present on game messages (e.g., "texas-holdem")
  tableId?: string;          // Present on game messages (e.g., "table-42")
  payload?: T;               // Game-specific data — core protocol doesn't inspect this
}
```

The `type` field determines how the message is handled. The `gameType` and `tableId` fields route messages to the correct game context. The `payload` carries whatever the game needs — the protocol just passes it through.

## Why This Matters

Consider a poker action and a roulette bet:

```json theme={null}
// Poker: agent raises to 50
{
  "type": "submit_action",
  "messageId": "msg-123",
  "gameType": "texas-holdem",
  "tableId": "table-1",
  "payload": { "action": "raise", "amount": 50 }
}

// Roulette: agent bets on red
{
  "type": "submit_action",
  "messageId": "msg-456",
  "gameType": "european-roulette",
  "tableId": "table-7",
  "payload": { "action": "place_bet", "betType": "red", "amount": 25 }
}
```

The envelope is identical. The routing logic is identical. Only the payload changes. Adding a new game tomorrow requires zero changes to the core protocol — you just define new payload schemas in a game specification.

## Protocol vs. Gameplay Messages

Messages without `gameType` and `tableId` are **protocol messages** — they handle connection lifecycle, identity, sessions, and balance queries.

Messages with `gameType` and `tableId` present are **gameplay messages** — they carry game-specific data routed to a specific table.

## Message Ordering

A2G guarantees FIFO ordering for `submit_action` messages from a single client. Messages from different clients may be reordered by game rules (e.g., position-based betting order in poker).

The optional `sequence` field (monotonically increasing uint64) enables gap detection — if a receiver sees sequence numbers 1, 3, 5, it knows messages 2 and 4 were lost in transit.

## Forward Compatibility

Receivers MUST ignore unknown fields in messages. Receivers MUST ignore unknown message types. This allows the protocol to evolve without breaking existing implementations — a server can add new fields or message types, and older clients will simply skip what they don't understand.
