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

Schema

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