Skip to main content
Every programmable world starts from a prompt. You can create one from a text premise, a seed image, or both. Every request goes to POST /v1/worlds with your secret key. The seed image anchors the world’s opening scene.

From a text premise

Describe the world and the API paints its opening frame.

From an image URL

Pass frame_url to open the world on an existing image. The URL must be fetchable by Alakazam’s servers with no cookies, authentication, or referer.
cURL
If a URL won’t fetch (hotlink protection, a login wall), upload the image inline with frame_b64 instead.

From a local image

Send the image inline as base64 with frame_b64 (a data URL or raw base64):
Python

Book → game: one chapter

Pass text (a chapter or a book excerpt) and the API turns it into a playable world through the book pipeline (it reads the passage, builds a story bible, and authors an act, all behind the same fail-closed kernel gate every world passes). One chapter is one world. text is mutually exclusive with premise/frame_b64/frame_url (send both and you get 400) and is capped at 40,000 characters.
Adapting a whole book, many chapters stitched into one story spine, with the same character carried across every chapter, is POST /v1/campaigns, in the Book → game (multi-chapter) section below. This single POST /v1/worlds path is the one-chapter tier.
A chapter is heavier than a one-line premise, so use async: true and poll GET /v1/jobs/:jobId until status is succeeded (then worldId is your world). The sync path works too, but a slow book pass can outlast an HTTP timeout.
On this single-chapter path, subject_ref is not accepted together with text (sending both returns 400). To carry the same character across a whole book, use POST /v1/campaigns below: it carries one character reference into every chapter for you.

Book → game (multi-chapter)

POST /v1/campaigns adapts a whole book into a campaign: one story spine and a linked chapter-world for every act. It runs the same book pipeline as the single-chapter path above, extended to segment the book, build a shared bible + spine, and author each chapter in order. Each chapter is an ordinary world: you run it exactly like any other, via /v1/sessions/token. Three things to know:
  • It’s always asynchronous. The response is 202 { jobId, campaignId } immediately; chapters author in the background. Poll GET /v1/jobs/{jobId} for progress (actsDone/actsTotal), and GET /v1/campaigns/{campaignId} for the chapter worldIds authored so far.
  • You’re billed one generation per chapter, reserved right before each chapter is authored: not a flat charge for the book. If a mid-book chapter hits your daily quota the campaign stops with the chapters so far intact (a partial campaign), and a retry never re-charges a chapter already authored.
  • The character is carried across every chapter. Pass subject_ref (a hosted image_url, or image_b64 which is hosted first) and that face, build, hair and clothing ride into every chapter’s seed. Omit it and the server paints one protagonist reference from the book’s bible and carries that. Either way the reference is stamped on each chapter world’s subjectRef, so you can keep adding scenes to any chapter with POST /v1/worlds/{id}/scenes.
text is capped at 200,000 characters. fidelity is faithful (default) or spirit; an optional target_acts (2–12) hints how many chapters to author (hard-capped at 12). A test key returns a deterministic mock campaign (a canned campaignId and one mock chapter) with no generation and no quota spend.

Retry safely

Set an Idempotency-Key so a network retry never creates, or charges for, a duplicate world:

Import a compiled world

Already have a compiled SMWorld (exported from another world, authored offline, or built by your own tooling)? Pass it as a world object to store it verbatim: no generation, no GPU. The graph is schema-validated (garbage is rejected) but not recompiled, and the call returns 201 with imported: true.
Import still reserves one generation of quota (an anti-spam bound, not a charge) and is size-limited: an oversized world returns 413 (default max 2 MB / 500 states / 2000 events), and an invalid one returns 422 with the failing errors. name/description in the body override whatever the blob carries.

Engagement: like a world

Bump a public world’s like counter with POST /v1/worlds/{id}/like. It uses the read scope, so a publishable (pk_) key can drive a like button straight from the browser. No body; returns 204. Only public/unlisted/featured worlds are likeable (liking a private one is a silent no-op). The likes and plays counters come back on every world read.

Generate asynchronously

By default POST /v1/worlds generates inline and returns the world. For long-running or high-volume work, set "async": true to queue a durable job and return immediately, then poll it. The job survives client disconnects and worker restarts.
Async is a live-key path. A test key ignores async and returns the sync mock immediately (no job, no polling, no webhook).
When status is succeeded, worldId points at your new world. A failed job is retried automatically. If it exhausts its attempts it’s marked failed and the reserved quota is refunded.