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

# Issue a match session

> Opens a single match context for an authenticated player. This is the
**start gate**: a session is only issued when

- the game is published,
- the `x-game-key` credential is valid for the requested environment and origin,
- the credential has the `session` scope, and
- the player is a real participant of the match.

The returned `token` is single-use, expires after 10 minutes, and is
consumed when the player submits a result. `boardHash` is a
`number`/`integer` match id.




## OpenAPI

````yaml /openapi/musterbox-public.yaml post /api/v1/game-sdk/{gameId}/sessions
openapi: 3.0.3
info:
  title: MusterBox Public API
  version: 1.0.0
  description: |
    The public surface of the MusterBox developer platform. Every path in this
    document is verified against the MusterBox backend source code. The client
    SDK (`MusterBoxSdk`) is the recommended way to drive these endpoints; these
    pages document the wire contract for teams that need to understand or
    debug the traffic the SDK produces.

    Environments are selected by the base URL. The control-plane base URL per
    environment is:

    | Environment  | Base URL                          |
    | ------------ | --------------------------------- |
    | `local`      | `http://localhost:8081`           |
    | `sandbox`    | `https://sandbox-api.musterbox.dev` |
    | `staging`    | `https://staging-api.musterbox.dev` |
    | `production` | `https://api.musterbox.com`       |

    All paths below include the `api/v1` backend prefix explicitly, matching
    how the SDK resolves URLs (`control plane base` + `/api/v1`).

    > **Security boundary**: authentication, game sessions and results are the
    > only integration surfaces. Purchase endpoints exist for the on-device
    > PIN-verification flow and should always be driven through the SDK's
    > `PurchaseClient` — never hand-rolled. Do not roll your own purchase flow.
servers:
  - url: https://api.musterbox.com
    description: Production (default)
  - url: https://sandbox-api.musterbox.dev
    description: Sandbox — pre-production validation
  - url: https://staging-api.musterbox.dev
    description: Staging — pre-release integration environment
  - url: http://localhost:8081
    description: Local development backend
security:
  - bearerAuth: []
tags:
  - name: Authentication
    description: Player login, session refresh, and logout via the backend auth API
  - name: Game SDK
    description: >-
      Match sessions and mutually-confirmed results for games hosted by
      MusterBox
  - name: Secure purchases
    description: SDK-mediated PIN sessions for secure player purchases
paths:
  /api/v1/game-sdk/{gameId}/sessions:
    post:
      tags:
        - Game SDK
      summary: Issue a match session
      description: >
        Opens a single match context for an authenticated player. This is the

        **start gate**: a session is only issued when


        - the game is published,

        - the `x-game-key` credential is valid for the requested environment and
        origin,

        - the credential has the `session` scope, and

        - the player is a real participant of the match.


        The returned `token` is single-use, expires after 10 minutes, and is

        consumed when the player submits a result. `boardHash` is a

        `number`/`integer` match id.
      operationId: createGameSession
      parameters:
        - name: gameId
          in: path
          required: true
          description: The identifier of the game (as registered in the MusterBox console).
          schema:
            type: string
          example: my-arena-game
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - environment
                - matchId
              properties:
                environment:
                  $ref: '#/components/schemas/Environment'
                matchId:
                  type: integer
                  description: The bracket Match this player belongs to.
                  example: 1042
      responses:
        '200':
          description: A fresh, single-use match session and its participant context.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GameSession'
        '401':
          description: Missing `x-game-key` header or invalid/unauthorized player token.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
        '403':
          description: >-
            Game is not published, credential scope is missing,
            credential/origin rejected, or the player is not a participant of
            this match.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
        '404':
          description: Game not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
      security:
        - bearerAuth: []
        - gameKey: []
components:
  schemas:
    Environment:
      type: string
      enum:
        - local
        - sandbox
        - staging
        - production
      description: Backend environment the credential was created for.
    GameSession:
      type: object
      properties:
        sessionId:
          type: string
          description: Backend id of the issued session.
        token:
          type: string
          description: Single-use session token for `/game-sdk/{gameId}/results`.
        expiresAt:
          type: string
          format: date-time
          description: Session expiry (10-minute TTL).
        context:
          $ref: '#/components/schemas/MatchParticipantContext'
      required:
        - sessionId
        - token
        - expiresAt
        - context
    ApiError:
      type: object
      description: >-
        NestJS error envelope ({ error: { code, message, status } }) or the
        plain { message } shape.
      properties:
        error:
          type: object
          properties:
            code:
              type: string
            message:
              type: string
            status:
              type: integer
        message:
          type: string
    MatchParticipantContext:
      type: object
      properties:
        tournamentId:
          type: string
          description: Bracket tournament the match belongs to.
          example: tor-8f21c3
        matchId:
          type: integer
        participantId:
          type: integer
          nullable: true
          description: The player's participant row, or null when not resolvable.
        slot:
          type: integer
          nullable: true
          enum:
            - 1
            - 2
          description: Opponent slot (1 or 2) of the user inside the match, or null.
      required:
        - tournamentId
        - matchId
        - participantId
        - slot
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: Player access token returned by login/refresh.
    gameKey:
      type: apiKey
      in: header
      name: x-game-key
      description: >-
        Long-lived game credential bound to allowed origins. Public by design in
        the browser; keep it out of mobile app code.

````