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

# Run a Studio world

> Run a world you built in the web Studio through the API — copy its world ID and mint a session, no re-authoring required.

You don't have to author a world through the API to run it there. Any world you
built in the web [Studio](https://play.alakazam.gg) has a stable **world ID** (a
UUID) that your own app can play through the same session flow as an
API-generated world. Build it visually, copy the ID, and embed it in your
product.

<Note>
  **Ownership rule.** A world you make in the Studio is stored with no `app_id`
  and your account as its author. Your **secret key** can still mint a session
  for it — the API matches the world's author against your key's account owner.
  In short: your key runs the worlds **you authored**, even the ones that were
  never created through the API. It will never run another account's world.
</Note>

## Copy the world ID

Open the world in the Studio and use the **Developer / API** row in the share
panel to copy its ID. The ID is the world's identity everywhere in the API; the
slug is only a play handle. It looks like:

```text theme={null}
dc2c65e4-68d3-4210-a01e-7a54cc9ded2a
```

## Run it

Embedding is the same two steps as any world: mint a short-lived **session
token** on your server, then boot the world in the browser with the session
token (never your secret key).

<Steps>
  <Step title="Mint a session token (server)">
    Call `POST /v1/sessions/token` with your secret key and the Studio world's
    UUID as `worldId`. Bind it to the player and to the origin you'll embed on.

    <CodeGroup>
      ```bash cURL theme={null}
      curl -X POST 'https://api.alakazam.gg/v1/sessions/token' \
        -H 'Authorization: Bearer sk_live_…' \
        -H 'Content-Type: application/json' \
        -d '{
          "worldId": "dc2c65e4-68d3-4210-a01e-7a54cc9ded2a",
          "playerIdentity": "user-123",
          "origin": "https://yourgame.com"
        }'
      ```

      ```javascript JavaScript theme={null}
      const r = await fetch("https://api.alakazam.gg/v1/sessions/token", {
        method: "POST",
        headers: {
          Authorization: "Bearer sk_live_…",
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          worldId: "dc2c65e4-68d3-4210-a01e-7a54cc9ded2a", // copied from the Studio
          playerIdentity: user.id,
          origin: "https://yourgame.com",
        }),
      });
      const { token, slug } = await r.json(); // send `token` to the browser
      ```
    </CodeGroup>

    The response is the usual `{ token, expiresIn, worldId, slug, jti }`. If the
    world isn't one you authored (or the key's account doesn't own it), the mint
    fails closed with `404` — never a cross-account read.
  </Step>

  <Step title="Boot the world (browser)">
    Exchange the session token for a runtime connection with
    `POST /v1/sessions/connect`, or let the SDK do it for you. Pass the session
    token, never your secret key.

    <CodeGroup>
      ```bash cURL theme={null}
      curl -X POST 'https://api.alakazam.gg/v1/sessions/connect' \
        -H 'Content-Type: application/json' \
        -d '{ "token": "SESSION_TOKEN" }'
      ```

      ```javascript JavaScript theme={null}
      import { createEmbed } from "@alakazamworld/embed";

      createEmbed({
        container: "#game",
        slug,        // from the token response above
        token,       // the session token from your server
        onEnding: (e) => console.log("ending reached", e),
      });
      ```
    </CodeGroup>

    `/v1/sessions/connect` returns `{ worldId, reactorJwt, expiresIn, expiresAt, world }` —
    the same runtime payload an API-generated world returns, so nothing else in
    your integration changes.
  </Step>
</Steps>

## Notes

* **Identity is the UUID.** Always reference the world by its ID. The slug can
  change; the ID never does.
* **Author match only.** The bridge allows exactly one thing beyond app-scoped
  worlds: a world whose author is your key's account owner. Deleted worlds are
  excluded, and no other account's worlds are ever reachable.
* **Everything else is identical.** Quotas, concurrency, origin binding, and the
  [drift-refresh handoff](/sessions) all behave the same as for a world you
  created through [`POST /v1/worlds`](/quickstart).

## It works both ways

The bridge runs in the other direction too. A world you create with a **live**
secret key through [`POST /v1/worlds`](/quickstart) is attributed to your account,
so it shows up in your web [Studio](https://play.alakazam.gg) under **My
Creations** right alongside the worlds you built visually — same account, one
library. Open it there to view and play it. Editing and publishing follow the
Studio's normal rules: API-created worlds land **unlisted**, and — exactly like a
world you built by hand — saving changes or publishing requires your account to
have creator access, so if the Studio blocks a save or publish that's the creator
gate, not the bridge. Test-key creations stay out of the Studio list on purpose, so
your fixtures never clutter your real worlds.

## Next steps

<CardGroup cols={2}>
  <Card title="Embedding" icon="square-code" href="/embedding">
    Theming, events, token refresh, and cross-origin security.
  </Card>

  <Card title="Session handoff & continuity" icon="repeat" href="/sessions">
    Keep long streams clean with the drift-refresh double-buffer.
  </Card>
</CardGroup>
