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

# Versions and branches

> Snapshot, branch, check out, and diff a world's graph — a git-style version tree of full snapshots.

Every world keeps a **version tree**: a branching history of full graph
snapshots, plus a **HEAD** pointer that tracks the working graph. Snapshot a
version before a risky change, branch to explore an alternative, check out an
older snapshot to roll back, and diff any two versions to see exactly what moved.

<Note>
  Reading versions needs a publishable (`pk_`) or secret (`sk_`) key with
  `worlds:read`. Snapshotting and checking out need a secret key with
  `worlds:write`.
</Note>

## How the tree works

* A **version** is a full snapshot of a world's graph at a point in time, plus
  metadata: `id`, `parentVersionId`, `source`, `title`, and `createdAt`.
* **HEAD** is the version your working graph currently descends from.
* Snapshotting onto the **current HEAD** advances HEAD — a linear "save".
  Snapshotting off an **older** parent forks a **branch** and leaves HEAD alone.
* `source` records how a version was made: `save`, `branch`, `manual`, `ai`
  (an agent edit), or `import`.

## Snapshot a version

Capture the world's current graph as a new version. Omit `parentVersionId` to
snapshot onto the current HEAD.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST 'https://api.alakazam.gg/v1/worlds/WORLD_ID/versions' \
    -H 'Authorization: Bearer sk_live_…' \
    -H 'Content-Type: application/json' \
    -d '{ "title": "before the vault rewrite", "source": "save" }'
  ```

  ```javascript JavaScript theme={null}
  const { versionId, version } = await fetch(
    "https://api.alakazam.gg/v1/worlds/WORLD_ID/versions",
    {
      method: "POST",
      headers: {
        Authorization: "Bearer sk_live_…",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ title: "before the vault rewrite", source: "save" }),
    },
  ).then((r) => r.json());
  console.log("snapshot", versionId, "parent", version.parentVersionId);
  ```

  ```python Python theme={null}
  import requests

  body = requests.post(
      "https://api.alakazam.gg/v1/worlds/WORLD_ID/versions",
      headers={
          "Authorization": "Bearer sk_live_…",
          "Content-Type": "application/json",
      },
      json={"title": "before the vault rewrite", "source": "save"},
  ).json()
  print("snapshot", body["versionId"], "parent", body["version"]["parentVersionId"])
  ```
</CodeGroup>

## List the tree

`GET /v1/worlds/{id}/versions` returns every node oldest-first; rebuild the tree
from each node's `parentVersionId`.

<CodeGroup>
  ```bash cURL theme={null}
  curl 'https://api.alakazam.gg/v1/worlds/WORLD_ID/versions' \
    -H 'Authorization: Bearer pk_live_…'
  ```

  ```javascript JavaScript theme={null}
  const { versions } = await fetch(
    "https://api.alakazam.gg/v1/worlds/WORLD_ID/versions",
    { headers: { Authorization: "Bearer pk_live_…" } },
  ).then((r) => r.json());
  for (const v of versions) console.log(v.id, "←", v.parentVersionId, v.source, v.title);
  ```

  ```python Python theme={null}
  import requests

  versions = requests.get(
      "https://api.alakazam.gg/v1/worlds/WORLD_ID/versions",
      headers={"Authorization": "Bearer pk_live_…"},
  ).json()["versions"]
  for v in versions:
      print(v["id"], "←", v["parentVersionId"], v["source"], v["title"])
  ```
</CodeGroup>

Fetch one snapshot in full — graph and all — with
`GET /v1/worlds/{id}/versions/{versionId}`; it returns the version metadata plus
the complete `snapshot` world.

## Check out a version

Checking out sets the working graph to a version's snapshot **and** moves HEAD
onto it, atomically. A later snapshot then branches off the checked-out version.
The response carries the restored `world` and the new `rev` (also the `ETag`).
Like every world write, checkout honors `If-Match` / `expectedRev` and returns
`409` if a concurrent edit advanced the rev, so a checkout never silently
clobbers an in-flight edit.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST 'https://api.alakazam.gg/v1/worlds/WORLD_ID/checkout' \
    -H 'Authorization: Bearer sk_live_…' \
    -H 'Content-Type: application/json' \
    -d '{ "versionId": "VERSION_ID" }'
  ```

  ```javascript JavaScript theme={null}
  const res = await fetch(
    "https://api.alakazam.gg/v1/worlds/WORLD_ID/checkout",
    {
      method: "POST",
      headers: {
        Authorization: "Bearer sk_live_…",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ versionId: "VERSION_ID" }),
    },
  );
  const { world, rev } = await res.json();
  console.log("restored", world.name, "rev", rev);
  ```

  ```python Python theme={null}
  import requests

  res = requests.post(
      "https://api.alakazam.gg/v1/worlds/WORLD_ID/checkout",
      headers={
          "Authorization": "Bearer sk_live_…",
          "Content-Type": "application/json",
      },
      json={"versionId": "VERSION_ID"},
  )
  body = res.json()
  print("restored", body["world"]["name"], "rev", body["rev"])
  ```
</CodeGroup>

## Diff two versions

`GET /v1/worlds/{id}/versions/{a}/diff/{b}` returns a pure structural diff
between version `a` (base) and version `b` (target). States are keyed by their
record key, events by their unique `name`; `changed` means present in both but not
byte-identical.

<CodeGroup>
  ```bash cURL theme={null}
  curl 'https://api.alakazam.gg/v1/worlds/WORLD_ID/versions/BASE_ID/diff/TARGET_ID' \
    -H 'Authorization: Bearer pk_live_…'
  ```

  ```javascript JavaScript theme={null}
  const diff = await fetch(
    "https://api.alakazam.gg/v1/worlds/WORLD_ID/versions/BASE_ID/diff/TARGET_ID",
    { headers: { Authorization: "Bearer pk_live_…" } },
  ).then((r) => r.json());
  console.log("states +", diff.states.added, "events ~", diff.events.changed);
  ```

  ```python Python theme={null}
  import requests

  diff = requests.get(
      "https://api.alakazam.gg/v1/worlds/WORLD_ID/versions/BASE_ID/diff/TARGET_ID",
      headers={"Authorization": "Bearer pk_live_…"},
  ).json()
  print("states +", diff["states"]["added"], "events ~", diff["events"]["changed"])
  ```
</CodeGroup>

The diff is shaped like this:

```json theme={null}
{
  "a": "BASE_ID",
  "b": "TARGET_ID",
  "states": { "added": ["vault"], "removed": [], "changed": ["cellar"] },
  "events": { "added": ["Turn the brass key"], "removed": [], "changed": [] }
}
```

## Status codes

| Status | Meaning                                                                       |
| ------ | ----------------------------------------------------------------------------- |
| `200`  | OK. Snapshot/checkout/diff/list/get succeeded.                                |
| `400`  | A required field is missing (e.g. `versionId` on checkout).                   |
| `404`  | The world or a referenced version doesn't exist, or isn't yours.              |
| `409`  | The rev you asserted is stale — a concurrent edit moved it; reload and retry. |
