openapi: 3.0.3
info:
  title: ARC‑AGI‑3 REST API
  version: 1.0.0
  description: |
    Programmatic interface for running agents against ARC‑AGI‑3 games, opening/closing score‑cards and driving game state with actions.
    All requests **require** an `X‑API‑Key` header issued from the ARC‑AGI‑3 web console.

    **Important: Session Affinity via Cookies**  
    Games are stateful and require session affinity. The server sets cookies (especially `AWSALB*` cookies) in responses that **must be included in all subsequent requests** for the same game session. These cookies route requests to the correct backend instance maintaining your game state. Most HTTP clients handle cookies automatically, but ensure your client preserves and sends cookies received from RESET and ACTION responses.

servers:
  - url: https://three.arcprize.org

components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key

  schemas:
    Game:
      type: object
      description: |
        Human-readable name/identifier pair for an ARC-AGI-3 game.  
        Used when listing available titles or embedding game metadata in other payloads.
      properties:
        game_id:
          type: string
          example: ls20-016295f7601e
          description: Stable, globally unique ID combining slug and version/hash.
        title:
          type: string
          nullable: true
          example: LS20
          description: Display title shown in UIs and scorecards.
        default_fps:
          type: integer
          nullable: true
          description: Default playback frame rate for the game.
        tags:
          type: array
          nullable: true
          items:
            type: string
          description: Public labels associated with the game.
        date_downloaded:
          type: string
          format: date-time
          nullable: true
          description: Timestamp associated with the available game metadata.
        class_name:
          type: string
          nullable: true
          description: Python game class name derived from the game ID when omitted in metadata.
      required: [game_id]

    OpenScorecardRequest:
      type: object
      description: |
        Optional metadata sent when opening a scorecard.  
        Every field is optional; omit any you don't need.  
        Use this to attach provenance links, free-form tags, or an
        "opaque" JSON blob describing the run (e.g. model settings,
        hyper-parameters, experiment notes). The opaque payload must not
        exceed 16 KB once serialized.
      properties:
        source_url:
          type: string
          format: uri
          description: Link to code, notebook, or write-up associated with the run.
        tags:
          type: array
          description: Arbitrary labels for later filtering and aggregation.
          items:
            type: string
        opaque:
          description: |
            Any JSON-serializable value (≤ 16 KB). Stored verbatim; the service
            does not inspect or validate its structure.
        competition_mode:
          type: boolean
          description: Set to `true` to enable competition restrictions for this scorecard.

    OpenScorecardResponse:
      type: object
      description: |
        Response returned after a successful "open scorecard" request.
        Contains the server-generated identifier for this tracked run.
      properties:
        card_id:
          type: string
          description: Globally unique ID for the newly opened scorecard.
      required: [card_id]

    CloseScorecardRequest:
      type: object
      description: |
        Payload for closing a previously opened scorecard and finalising
        its aggregated results.
      properties:
        card_id:
          type: string
          description: |
            Identifier of the scorecard to close—use the `card_id`
            returned by **OpenScorecardResponse**.
      required: [card_id]

    ScorecardSummary:
      type: object
      description: |
        Aggregate results for an entire scorecard run.  
        Returned when closing a scorecard or when retrieving a scorecard (open or closed).
        Includes cumulative totals, optional metadata echoed from the open request
        (e.g. `source_url`, `tags`, `opaque`), user identity (`user_name`, `user_id`),
        timestamps (`open_at`, `last_update`, `published_at`), and a per-environment
        breakdown in `environments`. The `tags_scores` array provides per-tag aggregates
        for runs that were tagged.
      properties:
        card_id:
          type: string
          description: The scorecard ID returned by **OpenScorecardResponse**.
        score:
          type: number
          format: float
          description: Average of the best per-environment scores in this scorecard.
        source_url:
          type: string
          format: uri
          description: Link originally supplied in the **OpenScorecardRequest**.
        tags:
          type: array
          description: Arbitrary labels echoed back from the open request.
          items: { type: string }
        user_name:
          type: string
          description: Display name of the user who opened/ran this scorecard.
        user_id:
          type: string
          description: Stable identifier of the user (e.g. provider subject id).
        published_at:
          type: string
          format: date-time
          description: When the scorecard was closed/published (absent if still open).
        environments:
          type: array
          description: Per-environment breakdown; each entry is one game/environment with its runs.
          items:
            $ref: '#/components/schemas/EnvironmentSummary'
        opaque:
          description: |
            JSON value (≤ 16 KB) exactly as provided when the
            scorecard was opened. Absent if none was supplied.
        tags_scores:
          type: array
          description: Per-tag aggregate statistics for runs that were tagged.
          items:
            $ref: '#/components/schemas/TagScore'
        competition_mode:
          type: boolean
          nullable: true
          description: Whether competition restrictions apply to this scorecard.
        open_at:
          type: string
          format: date-time
          description: When the scorecard was opened.
        last_update:
          type: string
          format: date-time
          description: When the scorecard was last updated (e.g. last action or close).
        total_environments_completed:
          type: integer
          description: Number of environments with at least one run that reached WIN.
        total_environments:
          type: integer
          description: Total number of environments in this scorecard.
        total_levels_completed:
          type: integer
          description: Sum of the highest completed-level count for each environment.
        total_levels:
          type: integer
          description: Total number of levels across all environments.
        total_actions:
          type: integer
          description: Number of actions taken across all recorded runs.
      required:
        - card_id
        - score
        - environments
        - total_environments_completed
        - total_environments
        - total_levels_completed
        - total_levels
        - total_actions

    EnvironmentSummary:
      type: object
      description: |
        Statistics for one environment (game) inside a scorecard.  
        Contains aggregate counts and an array of `runs` (one per RESET/play).
      properties:
        id:
          type: string
          description: Environment/game identifier (e.g. `am92-80effacb`).
        runs:
          type: array
          description: One entry per run (RESET) in this environment.
          items:
            $ref: '#/components/schemas/RunSummary'
        score:
          type: number
          format: float
          description: Best run score for this environment.
        actions:
          type: integer
          description: Total actions taken in this environment across all runs.
        levels_completed:
          type: integer
          description: Highest completed-level count among this environment's runs.
        completed:
          type: boolean
          description: Whether at least one run in this environment reached WIN.
        level_count:
          type: integer
          description: Number of levels in this environment.
        resets:
          type: integer
          description: Number of RESETs (level or full) in this environment.
      required: [id, runs, score, actions, levels_completed, completed, level_count, resets]

    RunSummary:
      type: object
      description: |
        Statistics for a single run (one RESET → play until WIN/GAME_OVER or abandon)
        within an environment. Arrays `level_scores`, `level_actions`, and
        `level_baseline_actions` align by index (one entry per level).
      properties:
        id:
          type: string
          description: Environment id this run belongs to.
        guid:
          type: string
          description: Server-generated session id for this run.
        score:
          type: number
          format: float
          description: Score achieved in this run.
        levels_completed:
          type: integer
          description: Number of levels completed in this run.
        actions:
          type: integer
          description: Number of actions taken in this run.
        resets:
          type: integer
          description: Number of resets (level or full) in this run.
        state:
          type: string
          description: |
            Final state of the run:
            • **NOT_FINISHED** - run is active.  
            • **NOT_PLAYED**   - no game has been started.
            • **WIN**          - run ended in victory.  
            • **GAME_OVER**    - run ended in defeat.
          enum: [NOT_PLAYED, NOT_FINISHED, WIN, GAME_OVER]
        completed:
          type: boolean
          description: Whether the run reached the WIN state.
        level_scores:
          type: array
          description: Score achieved at each level (positional).
          items: { type: number, format: float }
        level_actions:
          type: array
          description: Actions taken at each level (positional).
          items: { type: integer }
        level_baseline_actions:
          type: array
          description: Baseline (e.g. par) actions per level, when defined (positional).
          items: { type: integer }
        number_of_levels:
          type: integer
          description: Number of levels in this environment (may be 0 if not applicable).
        number_of_environments:
          type: integer
          description: Number of environments (may be 0 if not applicable).
      required:
        - id
        - guid
        - score
        - levels_completed
        - actions
        - resets
        - state
        - completed

    TagScore:
      type: object
      description: Per-tag aggregate statistics for runs that were tagged (e.g. for filtering).
      properties:
        id:
          type: string
          description: Tag or run identifier.
        guid:
          type: string
          description: Session id associated with this tag entry.
        score:
          type: number
          format: float
          description: Aggregate score for this tag.
        levels_completed:
          type: integer
          description: Levels completed for this tag.
        actions:
          type: integer
          description: Total actions for this tag.
        resets:
          type: integer
          description: Resets for this tag.
        state:
          type: string
          enum: [NOT_PLAYED, NOT_FINISHED, WIN, GAME_OVER]
          description: Terminal state for this tag run, if applicable.
        completed:
          type: boolean
          description: Whether this tag aggregate reached the WIN state.
        number_of_levels:
          type: integer
          description: Number of levels.
        number_of_environments:
          type: integer
          description: Number of environments.
      required:
        - id
        - score
        - levels_completed
        - actions
        - number_of_levels
        - number_of_environments

      
    ResetCommand:
      type: object
      description: |
        Starts a new game session **or** resets an existing one, depending on
        whether a `guid` is supplied.

        • **No `guid` (null/empty)** → A brand-new game instance is created and
          the response will include its freshly minted `guid`.

        • **With `guid`** → The server issues a reset to that specific
          instance:
            - If at least one ACTION command has been executed in the **current
              level**, only that level is reset (typical "try again" behaviour).
            - If no ACTION commands have been executed since the last level
              transition, the entire game is reset to its initial state.

        Sending two RESET commands back-to-back therefore always yields a
        completely fresh game.

        All plays should be associated with an open scorecard via `card_id`
        so aggregated results can be tracked.
      properties:
        game_id:
          type: string
          description: Identifier of the game to start or reset (e.g. `ls20`).
        card_id:
          type: string
          description: |
            scorecard identifier returned by **OpenScorecardResponse**. Required
            to attribute this play to the correct scorecard.
        guid:
          type: string
          nullable: true
          description: |
            Server-generated game session ID.  
            • Omit or set to `null` to create a new game.  
            • Provide an existing value to reset that game as described above.
      required: [game_id, card_id]

    SimpleActionCommand:
      type: object
      description: |
        Issues a one-parameter action (ACTION1 - ACTION5 or ACTION7) to a running
        game instance identified by `guid`.

        **Important:** Include any cookies (especially `AWSALB*` cookies) received from previous RESET or ACTION responses to ensure session affinity.
      properties:
        game_id:
          type: string
          description: Game identifier this action targets.
        guid:
          type: string
          description: Server-generated session ID obtained from a RESET response.
        reasoning:
          description: |
            Optional, caller-defined JSON value (≤ 16 KB once serialized) capturing the
            agent's internal reasoning, model parameters, or any other
            metadata you'd like to store alongside the action.
      required: [game_id, guid]

    ComplexActionCommand:
      type: object
      description: |
        Payload for coordinate-based actions (e.g. `/api/cmd/ACTION6`).
        Supplies an `(x, y)` location on the 64 × 64 game grid along with
        the game/session identifiers so the engine can apply the action
        to the correct running instance.

        **Important:** Include any cookies (especially `AWSALB*` cookies) received from previous RESET or ACTION responses to ensure session affinity.
      properties:
        game_id:
          type: string
          description: Identifier of the game receiving this action.
        guid:
          type: string
          description: Server-generated session ID obtained from the RESET call.
        x:
          type: integer
          minimum: 0
          maximum: 63
          description: Horizontal coordinate on the game grid (0 = left, 63 = right).
        y:
          type: integer
          minimum: 0
          maximum: 63
          description: Vertical coordinate on the game grid (0 = top, 63 = bottom).
        reasoning:
          description: |
            Optional, caller-defined JSON value (≤ 16 KB once serialized) capturing the
            agent's internal reasoning, model parameters, or any other
            metadata you'd like to store alongside the action.
      required: [game_id, guid, x, y]

    FrameResponse:
      type: object
      description: |
        Snapshot returned after every RESET or ACTION command.  
        Includes the latest visual frame(s), cumulative progress, the
        current game state, and an echo of the triggering action.
      properties:
        game_id:
          type: string
          description: Game identifier for the running session.
        guid:
          type: string
          description: Server-generated session ID; use this for all subsequent commands.
        frame:
          type: array
          description: |
            One or more consecutive visual frames. Each frame is a 64 × 64
            grid of 4-bit colour indices (integers 0-15). Multiple frames
            may be returned if the environment advances internally (e.g.,
            animations) before settling.
          items:
            type: array
            items:
              type: array
              items:
                type: integer
                minimum: 0
                maximum: 15
        state:
          type: string
          description: |
            Current state of the session:
            
            • **NOT_FINISHED** - game in progress, not yet WIN or GAME_OVER.  
            • **NOT_PLAYED**   - no game has been started.
            • **WIN**          - session ended in victory.  
            • **GAME_OVER**    - session ended in defeat.
          enum: [NOT_PLAYED, NOT_FINISHED, WIN, GAME_OVER]
        levels_completed:
          type: integer
          description: Current cumulative number of levels completed for this run.
          minimum: 0
          maximum: 254
        win_levels:
          type: integer
          description: |
            Level threshold required to reach the **WIN** state. Mirrors
            the game's configured win condition so agents can adapt
            dynamically without hard-coding values.
          minimum: 0
          maximum: 254
        action_input:
          type: object
          description: Echo of the command that produced this frame.
          properties:
            id:
              type: integer
              minimum: 0
              maximum: 7
              description: Numeric `GameAction` ID that produced the frame (`0` is RESET).
            data:
              type: object
              description: Additional parameters originally sent with the action.
              additionalProperties: true
            reasoning:
              description: Optional caller-supplied reasoning value echoed with the action.
        full_reset:
          type: boolean
          description: Whether the RESET created a new game rather than resetting the current level.
        available_actions:
          type: array
          description: List of available actions for the current game.
          items:
            type: integer
            enum: [0, 1, 2, 3, 4, 5, 6, 7]
      required: [game_id, guid, frame, state, levels_completed, win_levels, action_input, available_actions]

tags:
  - name: Games
  - name: Scorecards
  - name: Commands

paths:

  /api/games:
    get:
      tags: [Games]
      summary: List available games
      description: |
        Retrieves metadata for every game currently exposed by the
        ARC-AGI-3 platform.  
        Use this discovery endpoint to obtain `game_id` values before
        opening a scorecard or issuing commands.
      operationId: listGames
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: Successful lookup; array of game descriptors.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Game'
              examples:
                sample:
                  summary: Two games
                  value:
                    - game_id: ls20-016295f7601e
                      title: LS20
                    - game_id: ft09-16726c5b26ff
                      title: FT09
        '401':
          description: Missing or invalid **X-API-Key** header.

  /api/games/{game_id}:
    get:
      tags: [Games]
      summary: Retrieve game metadata
      description: |
        Retrieves metadata for one game. You may pass either the complete
        versioned game ID or its stable ID prefix.
      operationId: getGame
      security:
        - ApiKeyAuth: []
      parameters:
        - name: game_id
          in: path
          required: true
          schema:
            type: string
          description: Complete game ID or stable ID prefix (for example, `ls20`).
      responses:
        '200':
          description: Game metadata.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Game'
        '404':
          description: No matching game was found.
        '401':
          description: Missing or invalid **X-API-Key** header.

  /api/healthcheck:
    get:
      summary: Check API health
      description: Returns a plain-text response when the API process is healthy.
      operationId: healthcheck
      responses:
        '200':
          description: API process is healthy.
          content:
            text/plain:
              schema:
                type: string
              example: okay

  /api/scorecard/open:
    post:
      tags: [Scorecards]
      summary: Open scorecard
      description: |
        Creates a new scorecard to aggregate statistics across one or more
        plays. The server returns a `card_id`, which must be included in all
        subsequent RESET commands and in the final **/scorecard/close** call.
        You may attach optional metadata (URL, tags, opaque JSON) that will
        be echoed back in summary responses.
      operationId: openScorecard
      security:
        - ApiKeyAuth: []
      requestBody:
        description: Optional metadata to associate with the new scorecard.
        required: false
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OpenScorecardRequest'
            examples:
              minimal:
                summary: Minimal request
                value: {}
              full:
                summary: With tags, link, and opaque blob
                value:
                  source_url: https://github.com/arcprize/docs
                  tags: [baseline, gpt-4o]
                  opaque:
                    model: gpt-4o
                    temperature: 0.25
      responses:
        '200':
          description: scorecard successfully created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OpenScorecardResponse'
              examples:
                success:
                  value:
                    card_id: 8bb3b1b8-4b46-4a29-a13b-ad7850a0f916
        '401':
          description: Missing or invalid **X-API-Key** header.

  /api/scorecard/close:
    post:
      tags: [Scorecards]
      summary: Close scorecard
      description: |
        Finalises a previously opened scorecard, locking its data and
        returning the aggregate results.  
        After a scorecard is closed, additional RESET or ACTION commands
        using its `card_id` are rejected.  
        You must supply the `card_id` obtained from **/scorecard/open**.
      operationId: closeScorecard
      security:
        - ApiKeyAuth: []
      requestBody:
        description: Identifier of the scorecard to close.
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CloseScorecardRequest'
            examples:
              example:
                value:
                  card_id: 8bb3b1b8-4b46-4a29-a13b-ad7850a0f916
      responses:
        '200':
          description: scorecard closed; final aggregate results returned.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ScorecardSummary'
              examples:
                success:
                  value:
                    card_id: 8ae52f21-b40c-457b-9f4e-65bd8381e67f
                    score: 100
                    source_url: https://sandbox.internal.arc-prize.com
                    tags: [human]
                    user_name: distracted_poincare
                    user_id: "102214435702678430912@google"
                    published_at: "2026-01-26T23:34:57.097896Z"
                    environments:
                      - id: am92-80effacb
                        runs:
                          - id: am92-80effacb
                            guid: 4a38a278-796b-4f42-a28b-a27a68dbf862
                            score: 100
                            levels_completed: 5
                            actions: 136
                            resets: 0
                            state: WIN
                            completed: true
                            level_scores: [100, 100, 100, 100, 100]
                            level_actions: [12, 34, 41, 26, 23]
                            level_baseline_actions: [20, 40, 50, 55, 60]
                            number_of_levels: 0
                            number_of_environments: 0
                        score: 100
                        actions: 136
                        levels_completed: 5
                        completed: true
                        level_count: 5
                        resets: 0
                    tags_scores:
                      - id: change9
                        guid: d3a0a4d8-536c-479d-b5a8-10bf1dc8aee3
                        score: 100
                        levels_completed: 5
                        actions: 136
                        resets: 0
                        state: NOT_FINISHED
                        completed: false
                        number_of_levels: 5
                        number_of_environments: 1
                      - id: example
                        guid: 66fe6b58-adf8-45b1-ac73-70ed486e22d0
                        score: 100
                        levels_completed: 5
                        actions: 136
                        resets: 0
                        state: NOT_FINISHED
                        completed: false
                        number_of_levels: 5
                        number_of_environments: 1
                    open_at: "2026-01-26T23:34:18.213873Z"
                    last_update: "2026-01-26T23:34:53.229182Z"
                    total_environments_completed: 1
                    total_environments: 1
                    total_levels_completed: 5
                    total_levels: 5
                    total_actions: 136
        '401':
          description: Missing or invalid **X-API-Key** header.
        '404':
          description: Supplied `card_id` does not correspond to an open scorecard.

  /api/scorecard/{card_id}:
    get:
      tags: [Scorecards]
      summary: Retrieve scorecard
      description: |
        Returns the current (or final) statistics for the specified
        scorecard.  
        This works for both open and already-closed scorecards, making it
        useful for polling progress or fetching archived results.
      operationId: getScorecard
      security:
        - ApiKeyAuth: []
      parameters:
        - name: card_id
          in: path
          required: true
          description: Identifier returned by **/scorecard/open**.
          schema:
            type: string
      responses:
        '200':
          description: scorecard found; summary returned.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ScorecardSummary'
              examples:
                example:
                  value:
                    card_id: 8ae52f21-b40c-457b-9f4e-65bd8381e67f
                    score: 100
                    source_url: https://sandbox.internal.arc-prize.com
                    tags: [human]
                    user_name: distracted_poincare
                    user_id: "102214435702678430912@google"
                    open_at: "2026-01-26T23:34:18.213873Z"
                    last_update: "2026-01-26T23:34:53.229182Z"
                    total_environments_completed: 1
                    total_environments: 1
                    total_levels_completed: 5
                    total_levels: 5
                    total_actions: 136
                    environments: []
                    tags_scores: []
        '401':
          description: Missing or invalid **X-API-Key** header.
        '404':
          description: No open or closed scorecard found with the supplied `card_id`.

  /api/scorecard/{card_id}/{game_id}:
    get:
      tags: [Scorecards]
      summary: Retrieve scorecard (one game)
      description: |
        Returns the scorecard statistics **limited to a single environment**.
        Only the entry matching `game_id` is present in `environments`; all
        top-level counters are recomputed for that environment alone.

        Useful for dashboards that present per-game progress without
        fetching the full scorecard payload.
      operationId: getScorecardForGame
      security:
        - ApiKeyAuth: []
      parameters:
        - name: card_id
          in: path
          required: true
          description: Identifier returned by **/scorecard/open**.
          schema:
            type: string
        - name: game_id
          in: path
          required: true
          description: Game identifier to filter by (e.g. `ls20-1d57d6daeb05`).
          schema:
            type: string
      responses:
        '200':
          description: scorecard found; statistics for the requested game.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ScorecardSummary'
              examples:
                example:
                  value:
                    card_id: 8ae52f21-b40c-457b-9f4e-65bd8381e67f
                    score: 100
                    source_url: https://sandbox.internal.arc-prize.com
                    tags: [human]
                    user_name: distracted_poincare
                    user_id: "102214435702678430912@google"
                    open_at: "2026-01-26T23:34:18.213873Z"
                    last_update: "2026-01-26T23:34:53.229182Z"
                    total_environments_completed: 1
                    total_environments: 1
                    total_levels_completed: 5
                    total_levels: 5
                    total_actions: 136
                    environments:
                      - id: ft09-1d57d6daeb05
                        runs:
                          - id: ft09-1d57d6daeb05
                            guid: 66fe6b58-adf8-45b1-ac73-70ed486e22d0
                            score: 3
                            levels_completed: 2
                            actions: 478
                            resets: 0
                            state: WIN
                            completed: true
                            level_scores: [1, 2]
                            level_actions: [171, 307]
                            level_baseline_actions: [200, 250]
                            number_of_levels: 5
                            number_of_environments: 1
                        score: 3
                        actions: 478
                        levels_completed: 2
                        completed: true
                        level_count: 5
                        resets: 0
                    tags_scores: []
        '401':
          description: Missing or invalid **X-API-Key** header.
        '404':
          description: |
            Either the supplied `card_id` does not exist, or the
            scorecard contains no entry for the specified `game_id`.

  /api/cmd/RESET:
    post:
      tags: [Commands]
      summary: Start or reset game instance
      description: |
        Creates a new game session **or** resets an existing one,
        depending on the presence of `guid` in the request body:

        • **Omit `guid` or set it to `null`** → start a brand-new game
          instance.  
        • **Provide an existing `guid`** → reset that session.  
          - If at least one ACTION command has been issued since the last
            level transition, only the **current level** is restarted.  
          - If no ACTIONs have been issued, the entire game resets.  
          Two consecutive RESETs therefore guarantee a completely fresh
          game.

        The call always returns the first (or refreshed) frame of the
        game state, along with updated score and win condition.

        **Note:** The response includes cookies (particularly `AWSALB*` cookies) that must be included in all subsequent ACTION commands for this session. These cookies ensure requests are routed to the same backend instance maintaining your game state.
      operationId: resetGame
      security:
        - ApiKeyAuth: []
      requestBody:
        description: Game identifier, scorecard ID, and (optionally) the session `guid`.
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ResetCommand'
            examples:
              newGame:
                summary: Start a new session
                value:
                  game_id: ls20-016295f7601e
                  card_id: 8bb3b1b8-4b46-4a29-a13b-ad7850a0f916
              levelReset:
                summary: Reset current level of an existing session
                value:
                  game_id: ls20-016295f7601e
                  card_id: 8bb3b1b8-4b46-4a29-a13b-ad7850a0f916
                  guid: 2fa5332c-2e55-4825-b5c5-df960d504470
      responses:
        '200':
          description: First frame after starting or resetting the session.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FrameResponse'
              examples:
                frame:
                  value:
                    game_id: ls20-016295f7601e
                    guid: 2fa5332c-2e55-4825-b5c5-df960d504470
                    frame:
                      - [[0,0,0,…],[…]] # truncated for brevity
                    state: NOT_FINISHED
                    levels_completed: 0
                    win_levels: 254
                    action_input:
                      id: 0
                      data: {}
                    available_actions: [1, 2, 3, 4]
        '400':
          description: |
            Bad request - possible causes:  
            • Unknown `game_id`  
            • Missing or unknown `card_id`  
            • `guid` does not correspond to an active session
        '401':
          description: Missing or invalid **X-API-Key** header.

  /api/cmd/ACTION1:
    post:
      tags: [Commands]
      summary: Execute simple action 1
      description: |
        Issues **ACTION 1** to the specified game session.  
        This is a single-parameter command (no X/Y coordinates): the exact
        in-game effect depends on the title—for example, it might
        represent "move up" or "select option A".

        The request must include:
        • `game_id` — which game to act on  
        • `guid` — the active session identifier returned from RESET  

        An optional `reasoning` JSON blob (≤ 16 KB) can be attached for
        audit or research purposes.

        A successful call returns the next visual frame(s) and updated
        score/state.
      operationId: action1
      security:
        - ApiKeyAuth: []
      requestBody:
        description: Game/session identifiers plus optional reasoning data.
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SimpleActionCommand'
            examples:
              action:
                value:
                  game_id: ls20-016295f7601e
                  guid: 2fa5332c-2e55-4825-b5c5-df960d504470
                  reasoning:
                    policy: "π_left"
      responses:
        '200':
          description: Frame returned after executing the action.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FrameResponse'
              examples:
                frame:
                  value:
                    game_id: ls20-016295f7601e
                    guid: 2fa5332c-2e55-4825-b5c5-df960d504470
                    frame:
                      - [[0,0,1,…],[…]]   # truncated
                    state: NOT_FINISHED
                    levels_completed: 3
                    win_levels: 254
                    action_input:
                      id: 1
                    available_actions: [1, 2, 3, 4]
        '400':
          description: |
            Bad request - possible causes:  
            • Unknown `game_id` or invalid format  
            • `guid` not found or does not belong to `game_id`  
            • `reasoning` field exceeds 16 KB or is malformed
        '401':
          description: Missing or invalid **X-API-Key** header.

  /api/cmd/ACTION2:
    post:
      tags: [Commands]
      summary: Execute simple action 2
      description: |
        Issues **ACTION 2** to the specified game session.  
        This is a single-parameter command (no X/Y coordinates): the exact
        in-game effect depends on the title—for example, it might
        represent "move down" or "select option B".

        The request must include:
        • `game_id` — which game to act on  
        • `guid` — the active session identifier returned from RESET  

        An optional `reasoning` JSON blob (≤ 16 KB) can be attached for
        audit or research purposes.

        A successful call returns the next visual frame(s) and updated
        score/state.
      operationId: action2
      security:
        - ApiKeyAuth: []
      requestBody:
        description: Game/session identifiers plus optional reasoning data.
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SimpleActionCommand'
            examples:
              action:
                value:
                  game_id: ls20-016295f7601e
                  guid: 2fa5332c-2e55-4825-b5c5-df960d504470
                  reasoning:
                    policy: "π_left"
      responses:
        '200':
          description: Frame returned after executing the action.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FrameResponse'
              examples:
                frame:
                  value:
                    game_id: ls20-016295f7601e
                    guid: 2fa5332c-2e55-4825-b5c5-df960d504470
                    frame:
                      - [[0,0,1,…],[…]]   # truncated
                    state: NOT_FINISHED
                    levels_completed: 3
                    win_levels: 254
                    action_input:
                      id: 2
                    available_actions: [1, 2, 3, 4]
        '400':
          description: |
            Bad request - possible causes:  
            • Unknown `game_id` or invalid format  
            • `guid` not found or does not belong to `game_id`  
            • `reasoning` field exceeds 16 KB or is malformed
        '401':
          description: Missing or invalid **X-API-Key** header.

  /api/cmd/ACTION3:
    post:
      tags: [Commands]
      summary: Execute simple action 3
      description: |
        Issues **ACTION 3** to the specified game session.  
        This is a single-parameter command (no X/Y coordinates): the exact
        in-game effect depends on the title—for example, it might
        represent "move left" or "select option C".

        The request must include:
        • `game_id` — which game to act on  
        • `guid` — the active session identifier returned from RESET  

        An optional `reasoning` JSON blob (≤ 16 KB) can be attached for
        audit or research purposes.

        A successful call returns the next visual frame(s) and updated
        score/state.
      operationId: action3
      security:
        - ApiKeyAuth: []
      requestBody:
        description: Game/session identifiers plus optional reasoning data.
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SimpleActionCommand'
            examples:
              action:
                value:
                  game_id: ls20-016295f7601e
                  guid: 2fa5332c-2e55-4825-b5c5-df960d504470
                  reasoning:
                    policy: "π_left"
      responses:
        '200':
          description: Frame returned after executing the action.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FrameResponse'
              examples:
                frame:
                  value:
                    game_id: ls20-016295f7601e
                    guid: 2fa5332c-2e55-4825-b5c5-df960d504470
                    frame:
                      - [[0,0,1,…],[…]]   # truncated
                    state: NOT_FINISHED
                    levels_completed: 3
                    win_levels: 254
                    action_input:
                      id: 3
                    available_actions: [1, 2, 3, 4]
        '400':
          description: |
            Bad request - possible causes:  
            • Unknown `game_id` or invalid format  
            • `guid` not found or does not belong to `game_id`  
            • `reasoning` field exceeds 16 KB or is malformed
        '401':
          description: Missing or invalid **X-API-Key** header.

  /api/cmd/ACTION4:
    post:
      tags: [Commands]
      summary: Execute simple action 4
      description: |
        Issues **ACTION 4** to the specified game session.  
        This is a single-parameter command (no X/Y coordinates): the exact
        in-game effect depends on the title—for example, it might
        represent "move right" or "select option D".

        The request must include:
        • `game_id` — which game to act on  
        • `guid` — the active session identifier returned from RESET  

        An optional `reasoning` JSON blob (≤ 16 KB) can be attached for
        audit or research purposes.

        A successful call returns the next visual frame(s) and updated
        score/state.
      operationId: action4
      security:
        - ApiKeyAuth: []
      requestBody:
        description: Game/session identifiers plus optional reasoning data.
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SimpleActionCommand'
            examples:
              action:
                value:
                  game_id: ls20-016295f7601e
                  guid: 2fa5332c-2e55-4825-b5c5-df960d504470
                  reasoning:
                    policy: "π_left"
      responses:
        '200':
          description: Frame returned after executing the action.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FrameResponse'
              examples:
                frame:
                  value:
                    game_id: ls20-016295f7601e
                    guid: 2fa5332c-2e55-4825-b5c5-df960d504470
                    frame:
                      - [[0,0,1,…],[…]]   # truncated
                    state: NOT_FINISHED
                    levels_completed: 3
                    win_levels: 254
                    action_input:
                      id: 4
                    available_actions: [1, 2, 3, 4]
        '400':
          description: |
            Bad request - possible causes:  
            • Unknown `game_id` or invalid format  
            • `guid` not found or does not belong to `game_id`  
            • `reasoning` field exceeds 16 KB or is malformed
        '401':
          description: Missing or invalid **X-API-Key** header.

  /api/cmd/ACTION5:
    post:
      tags: [Commands]
      summary: Execute simple action 5
      description: |
        Issues **ACTION 5** to the specified game session.  
        This is a single-parameter command (no X/Y coordinates): the exact
        in-game effect depends on the title—for example, it might
        represent "jump", "rotate", "fire" or "select option E".

        The request must include:
        • `game_id` — which game to act on  
        • `guid` — the active session identifier returned from RESET  

        An optional `reasoning` JSON blob (≤ 16 KB) can be attached for
        audit or research purposes.

        A successful call returns the next visual frame(s) and updated
        score/state.
      operationId: action5
      security:
        - ApiKeyAuth: []
      requestBody:
        description: Game/session identifiers plus optional reasoning data.
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SimpleActionCommand'
            examples:
              action:
                value:
                  game_id: ls20-016295f7601e
                  guid: 2fa5332c-2e55-4825-b5c5-df960d504470
                  reasoning:
                    policy: "π_left"
      responses:
        '200':
          description: Frame returned after executing the action.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FrameResponse'
              examples:
                frame:
                  value:
                    game_id: ls20-016295f7601e
                    guid: 2fa5332c-2e55-4825-b5c5-df960d504470
                    frame:
                      - [[0,0,1,…],[…]]   # truncated
                    state: NOT_FINISHED
                    levels_completed: 3
                    win_levels: 254
                    action_input:
                      id: 5
                    available_actions: [1, 2, 3, 4]
        '400':
          description: |
            Bad request - possible causes:  
            • Unknown `game_id` or invalid format  
            • `guid` not found or does not belong to `game_id`  
            • `reasoning` field exceeds 16 KB or is malformed
        '401':
          description: Missing or invalid **X-API-Key** header.

  /api/cmd/ACTION6:
    post:
      tags: [Commands]
      summary: Execute complex action (requires x,y)
      description: |
        Issues **ACTION 6**—a two-parameter command that supplies explicit
        X/Y coordinates—to an active game session.  Common use-cases
        include "click/tap at (x,y)", "place a tile", or "shoot a
        projectile," depending on the game's mechanics.

        Required fields  
        • `game_id` — the game to act in  
        • `guid`    — session identifier obtained from RESET  
        • `x`,`y`   — zero-based grid coordinates (0-63 inclusive)

        On success the server applies the action, advances game logic to
        the next stable frame, and returns that frame together with the
        updated score, state, and win condition.
      operationId: action6
      security:
        - ApiKeyAuth: []
      requestBody:
        description: Game/session identifiers plus the coordinate payload.
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ComplexActionCommand'
            examples:
              placeTile:
                summary: Place at (12, 34)
                value:
                  game_id: ls20-016295f7601e
                  guid: 2fa5332c-2e55-4825-b5c5-df960d504470
                  x: 12
                  y: 34
      responses:
        '200':
          description: Frame returned after executing the action.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FrameResponse'
              examples:
                frame:
                  value:
                    game_id: ls20-016295f7601e
                    guid: 2fa5332c-2e55-4825-b5c5-df960d504470
                    frame:
                      - [[…]]   # truncated for brevity
                    state: NOT_FINISHED
                    levels_completed: 17
                    win_levels: 254
                    action_input:
                      id: 6
                      data:
                        x: 12
                        y: 34
                    available_actions: [1, 2, 3, 4]
        '400':
          description: |
            Bad request - possible causes:  
            • Unknown `game_id`  
            • `guid` not found or does not belong to the supplied `game_id`  
            • `x` or `y` outside the 0-63 range
        '401':
          description: Missing or invalid **X-API-Key** header.

  /api/cmd/ACTION7:
    post:
      tags: [Commands]
      summary: Execute simple action 7
      description: |
        Issues **ACTION 7** to the specified game session.  
        This is a single-parameter command (no X/Y coordinates): 
        ACTION7 will always be an undo action for games that support it.

        The request must include:
        • `game_id` — which game to act on  
        • `guid` — the active session identifier returned from RESET  

        An optional `reasoning` JSON blob (≤ 16 KB) can be attached for
        audit or research purposes.

        A successful call returns the next visual frame(s) and updated
        score/state.
      operationId: action7
      security:
        - ApiKeyAuth: []
      requestBody:
        description: Game/session identifiers plus optional reasoning data.
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SimpleActionCommand'
            examples:
              action:
                value:
                  game_id: ls20-016295f7601e
                  guid: 2fa5332c-2e55-4825-b5c5-df960d504470
                  reasoning:
                    policy: "π_left"
      responses:
        '200':
          description: Frame returned after executing the action.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FrameResponse'
              examples:
                frame:
                  value:
                    game_id: ls20-016295f7601e
                    guid: 2fa5332c-2e55-4825-b5c5-df960d504470
                    frame:
                      - [[0,0,1,…],[…]]   # truncated
                    state: NOT_FINISHED
                    levels_completed: 3
                    win_levels: 254
                    action_input:
                      id: 7
                    available_actions: [1, 2, 3, 4, 7]
        '400':
          description: |
            Bad request - possible causes:  
            • Unknown `game_id` or invalid format  
            • `guid` not found or does not belong to `game_id`  
            • `reasoning` field exceeds 16 KB or is malformed
        '401':
          description: Missing or invalid **X-API-Key** header.
