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

# Convert a world into a shoot-for-score arcade

> One-call **Arcadeify**: runs the SAME canned kernel-agent ask the Studio's one-click Arcadeify button uses, turning the world into a shoot-for-score arcade derived from the world's own fiction (a progression, hostiles, a win condition). Same server-side kernel agent as `/edit`, same fail-closed gate: the agent authors the change and the result persists ONLY after passing the kernel grammar + doctrine suite. This is real LLM spend — reserved against your daily `edit` quota BEFORE the agent runs — a validation reject or agent error refunds it in full, while a committed edit, a no-change run, or a concurrency conflict meters the agent rounds actually burned and refunds only the unused slice. On success a version titled `arcadeify` (source `ai`) is snapshotted onto HEAD, so the conversion is one `POST …/checkout` away from rollback. **Guard:** a world that already has a `progression` is refused `409` unless you pass `force:true` (which rebuilds it). Pass an `Idempotency-Key` so a retry doesn't double-charge.




## OpenAPI

````yaml /alakazam-v1.yaml post /v1/worlds/{id}/arcadeify
openapi: 3.0.3
info:
  title: 'Alakazam: Programmable Worlds API'
  version: '1.0'
  description: >
    **Alakazam is the programmable worlds API.** Generate playable, AI-rendered
    worlds from a prompt or an image, program their logic, and embed them in
    your own products and games.


    A world is *programmable*: a live graph of states and events you generate,
    then read, edit, fork, drive, and react to through the API. Two surfaces: a
    **Creation API** (generate, read, manage, fork worlds) and a **Runtime/Embed
    API** (mint short-lived session tokens your end-users' browsers use to boot
    an embedded world).


    **Authentication.** Two schemes. Management endpoints (`/v1/apps*`) use your
    Supabase user session. Data endpoints use an **API key** issued per app:
    `pk_…` (publishable, browser-safe, read-only) and `sk_…` (secret,
    server-only — create/edit worlds and mint session tokens). Embedding a world
    in a browser uses a short-lived **session token** minted server-side with a
    secret key (not a publishable key directly). Never ship a secret key to a
    browser.


    **Test vs live.** Keys come in `test` and `live` modes — the prefix tells
    you which (`sk_test_…`/`pk_test_…` vs `sk_live_…`/`pk_live_…`). A **test**
    key runs against a sandbox: every generative endpoint returns a
    deterministic mock marked `"mock": true`, with no GPU or vendor spend; test
    worlds/characters are isolated from live data (forced `private`, never
    slugged or discoverable); and test usage is **never** billed. See the
    Testing guide.


    **Usage, quota & billing.** Every operation is counted against a per-app
    daily quota, reserved before any GPU spend. Exceeding it returns `402`. The
    quota is a free abuse guard, not a charge. Billing, when enabled, is
    **runtime-only**: you pay for `session_seconds` (live play time). Creating
    worlds and every other operation are free. Test-mode usage is never billed,
    even after billing is enabled. The API is in developer preview. See Pricing.


    **Building with an AI coding agent?** Install the skill (`npx skills add -g
    https://docs.alakazam.gg/skill.md`) and the MCP server (`npx
    @alakazamworld/mcp`) so your agent knows this API and can call it live. See
    the Agent quickstart.
servers:
  - url: https://api.alakazam.gg
    description: Production (placeholder, set to your conjure-service host)
security: []
tags:
  - name: Apps & Keys
    description: >-
      Create apps (tenants) and manage API keys. Authenticated with your user
      session.
  - name: Worlds
    description: >-
      Create, read, manage, and fork SMWorld games. Authenticated with an API
      key.
  - name: Graph editing
    description: >
      Read and program a world's graph of states (nodes), events (edges), and
      the entrance, using deterministic CRUD, a batch op vocabulary, a
      natural-language kernel-agent edit, and the kernel validate/lint gate.
      Every write is validated fail-closed before it persists. Authenticated
      with an API key.
  - name: Versions
    description: >
      Snapshot, branch, check out, and diff a world's graph. Versions form a
      branching tree of full snapshots; a HEAD pointer tracks the working graph.
      Authenticated with an API key.
  - name: Characters
    description: >
      Create, manage, and talk to characters: a SMWorld subtype that pairs a
      stance-graph with a "brain" (persona, lore, voice). CRUD is authenticated
      with an API key. The live talk turn (/say) and voice (/tts) are called
      from the browser with a short-lived session token.
  - name: Scenario Studio
    description: >
      Author variation/counterfactual plans over an episode or scenario, submit
      them as durable batches (N verified clips), poll them, and accept/reject
      each result. Nothing bills at submit — a clip is charged only when
      accepted; rejected and failed clips never touch the ledger. Authenticated
      with an API key.
  - name: Sessions
    description: Mint short-lived runtime tokens for embedding a world.
  - name: Usage
    description: Per-app usage and quota.
  - name: Webhooks
    description: >-
      Register HTTPS endpoints to receive signed server-side event
      notifications. Managed with your user session.
  - name: Simulation & Data
    description: >
      **Beta — self-hosted runner.** Drive a world headlessly as a training
      environment (gym) and stream the SNN-controller observation contract: two
      virtual proximity sensors, collision spikes, object labels, and an
      optional square RGB camera. The same schema is emitted offline by the
      dataset exporter (JSONL episodes + train-ready NPZ), so controllers
      trained on recorded data plug straight into the live loop.
paths:
  /v1/worlds/{id}/arcadeify:
    post:
      tags:
        - Graph editing
      summary: Convert a world into a shoot-for-score arcade
      description: >
        One-call **Arcadeify**: runs the SAME canned kernel-agent ask the
        Studio's one-click Arcadeify button uses, turning the world into a
        shoot-for-score arcade derived from the world's own fiction (a
        progression, hostiles, a win condition). Same server-side kernel agent
        as `/edit`, same fail-closed gate: the agent authors the change and the
        result persists ONLY after passing the kernel grammar + doctrine suite.
        This is real LLM spend — reserved against your daily `edit` quota BEFORE
        the agent runs — a validation reject or agent error refunds it in full,
        while a committed edit, a no-change run, or a concurrency conflict
        meters the agent rounds actually burned and refunds only the unused
        slice. On success a version titled `arcadeify` (source `ai`) is
        snapshotted onto HEAD, so the conversion is one `POST …/checkout` away
        from rollback. **Guard:** a world that already has a `progression` is
        refused `409` unless you pass `force:true` (which rebuilds it). Pass an
        `Idempotency-Key` so a retry doesn't double-charge.
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: If-Match
          in: header
          required: false
          schema:
            type: string
          description: The `rev` you last read. Mismatch returns 409.
        - name: Idempotency-Key
          in: header
          required: false
          schema:
            type: string
          description: >-
            A retried arcadeify with the same key returns the original result
            without a second LLM spend (its own route-scoped namespace).
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                force:
                  type: boolean
                  default: false
                  description: >-
                    Rebuild the arcade even when the world already has a
                    `progression`. Without it, an already-progression world is
                    refused `409`.
                expectedRev:
                  type: string
                  description: >-
                    Optional optimistic-concurrency token; alternative to the
                    `If-Match` header.
      responses:
        '200':
          description: >-
            Arcade conversion applied (or a no-op — see below). The new revision
            is the `ETag` header. `versionId` is the `arcadeify` snapshot, and
            is `null` when no version was written: a fail-soft post-persist
            snapshot failure, OR a no-change run (the agent asked a clarifying
            question / produced no ops — the original world is returned
            unchanged via `reply`).
          headers:
            ETag:
              schema:
                type: string
              description: >-
                The new revision token (header only — read it from `ETag`, not
                the body).
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/EditResult'
                  - type: object
                    properties:
                      versionId:
                        type: string
                        format: uuid
                        nullable: true
                        description: >-
                          The `arcadeify` version snapshot (source `ai`),
                          parent-chained to HEAD. Null on a no-change run or a
                          fail-soft post-persist snapshot failure.
        '400':
          description: Malformed JSON body
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '402':
          description: Daily edit quota exceeded
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: API key is missing the required scope for this operation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: World not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '409':
          description: >
            Two causes: (a) the world already has a `progression` and `force`
            was not `true` (detail: "world already has progression — pass
            force:true to rebuild it") — the guard fires BEFORE any quota is
            reserved (so it is free); or (b) an optimistic-concurrency conflict
            — the `rev` you asserted is stale (the agent already ran, so its
            burned rounds are metered and only the unused reservation is
            refunded). Reload and retry.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '422':
          description: >-
            The agent's world failed the kernel gate (not persisted; reservation
            refunded)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GraphValidationError'
        '429':
          description: Too many requests
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '502':
          description: Authoring agent failed (reservation refunded)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '503':
          description: Authoring or quota backend unavailable (fail-closed)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      security:
        - ApiKeyAuth: []
components:
  schemas:
    EditResult:
      type: object
      description: >
        The RESULT-ONLY response from a kernel-agent edit. It carries the
        validated `world`, advisory `diagnostics`, and the agent's
        natural-language `reply`, and none of the agent's internals: the system
        prompt, op grammar, lexicon, model id, and raw op trace are never
        exposed. When the agent needs clarification it returns its question in
        `reply` and leaves the world unchanged. (A TEST-mode response
        additionally carries a `mock: true` marker.)
      required:
        - world
        - diagnostics
        - reply
      properties:
        world:
          $ref: '#/components/schemas/SMWorld'
        diagnostics:
          type: array
          description: >-
            The full validateWorld set (advisory warning/info findings) for the
            persisted world.
          items:
            $ref: '#/components/schemas/KernelDiagnostic'
        reply:
          type: string
          description: >-
            The agent's natural-language summary of what it did, or a clarifying
            question when no change was made.
        mock:
          type: boolean
          description: Present and `true` only for TEST-mode keys. See Testing.
    Error:
      type: object
      properties:
        detail:
          type: string
          description: Human-readable error message.
        errors:
          type: array
          items:
            type: string
          description: Field-level validation errors (e.g. on 422 from POST /v1/worlds).
        schemaVersion:
          type: string
      required:
        - detail
    GraphValidationError:
      type: object
      description: >-
        A 422 from a graph write or validate: the world failed the kernel gate.
        Nothing was persisted.
      required:
        - detail
        - diagnostics
      properties:
        detail:
          type: string
        diagnostics:
          type: array
          items:
            $ref: '#/components/schemas/KernelDiagnostic'
        schemaVersion:
          type: string
          example: '1.0'
    SMWorld:
      type: object
      description: >
        A playable world's compiled graph — `id`, `name`, `entrance`, and the
        `scene` (states + events). This is the shape returned *inside* the
        `world` field of a World resource (see `World`) and by the graph-editing
        routes. Additional optional properties are allowed (forward-compatible);
        the `schemaVersion` on responses pins the contract version.
      additionalProperties: true
      required:
        - id
        - name
        - entrance
        - scene
      properties:
        id:
          type: string
        name:
          type: string
        description:
          type: string
        cover:
          type: string
        entrance:
          type: object
          required:
            - image
            - state
          properties:
            image:
              type: object
              required:
                - src
              properties:
                label:
                  type: string
                src:
                  type: string
                  description: Seed image for the boot.
            state:
              type: string
              description: Initial state id.
        scene:
          type: object
          required:
            - states
            - events
          properties:
            states:
              type: object
              additionalProperties: true
            events:
              type: array
              items:
                type: object
                additionalProperties: true
        subject:
          type: string
          description: >
            Prose subject lock — how the hand-authored worlds hold a character
            steady across states. Metadata (ignored by the runtime).
            `subjectRef.descriptor` defaults to this when painting new scenes.
        subjectRef:
          type: object
          description: >
            Canonical CHARACTER REFERENCE — the PIXEL counterpart of `subject`.
            Set at create time via the `subject_ref` request field (POST
            /v1/worlds), or attached/rotated later via the `set_subject_ref`
            graph op. `POST /v1/worlds/{id}/scenes` paints new scenes FROM this
            image so the character stays identical across scenes, levels and
            book chapters. Metadata (ignored by the runtime).
          properties:
            imageUrl:
              type: string
              description: 'Hosted URL of the character reference image (never a data: URI).'
            descriptor:
              type: string
              description: >-
                Optional prose descriptor; defaults to the world's `subject`
                when painting scenes.
    KernelDiagnostic:
      type: object
      description: >
        A single finding from the kernel grammar + doctrine lint suite.
        STRUCTURAL lints (e.g. `dangling-ref`, `transition-needs-to`,
        `kernel-cycle`, `slot-*`) are always fatal `error`s and block the write
        (422). Doctrine/budget lints (e.g. `negation`, `whiteout`,
        `lethal-override`, `budget`) are advisory and surface as
        `warning`/`info`.
      required:
        - lint
        - severity
        - path
        - message
      properties:
        lint:
          type: string
          description: The lint id (e.g. `dangling-ref`, `negation`, `budget`).
        severity:
          type: string
          enum:
            - error
            - warning
            - info
        path:
          type: string
          description: Human-readable location, e.g. `event[Step outside].movement.static`.
        message:
          type: string
          description: What is wrong and, where possible, how to fix it.
        loc:
          type: object
          description: Structured location for editor/narrator UIs.
          properties:
            field:
              type: string
            template:
              type: string
            slot:
              type: string
            fill:
              type: string
  securitySchemes:
    ApiKeyAuth:
      type: http
      scheme: bearer
      description: >-
        An app API key, e.g. `Authorization: Bearer sk_live_…`. Secret (`sk_`)
        for writes/sessions; publishable (`pk_`) is read-only (browser-safe).

````