Developer APIs
Every API surface the platform exposes, what it is, and how much it promises.
This is the index a contributor, self-hoster or module author reads. The Action API has its own tree next door, because the person writing an action script is not the person reading this page.
Only the Module API is formally versioned, at
1.48.0(MODULE_API_VERSION, enforced) — declared inpackages/shared/src/types/module.tsand checked against each module's supported range at load time. A guard in that package fails the build if this line and the constant disagree, because they have before: the index a module author is pointed at once sat at 1.5.0 while the constant had reached 1.27.0, twenty-two minor versions of extension points behind. Every other surface here is unversioned: documented, stable in practice, and free to change between releases. The Character Sheet, Monster and Content APIs are not separate versions — they ship as part of the Module API.
The APIs
| API | What it is | Versioned | Contract |
|---|---|---|---|
| Action API | The action-script sandbox: an AsyncFunction over token code with a fixed set of globals injected — token, roll, applyDamage, requestRoll, prompt and the rest. Documented for its users at Action API. |
No | action-api.md |
| Module API | The Open-Core extension system. A declarative registry (artwork, dice, settings, system and sheet-section extensions), auto-mounted server routers, and module-contributed fixtures, AI schemas and host allowlists. | Yes — 1.48.0, enforced |
module-api.md |
| System API | Game systems: metadata plus campaign-inherited trait tables over REST, and the code-level SystemModule interface that carries a system's logic. |
No | system-api.md |
| Character Sheet API | The platform↔system sheet contract: a module supplies the sheet schema and the projection, validation and automation behind it. | Via the Module API | character-sheet-api.md |
| Character Sheet Renderer | How a module ships the sheet itself (v0.105.0): registerCharacterSheetRenderer, SheetRendererProps / SheetApi, the @purple-cat/sheet-kit, the host's modes and field registry — and the inventory of system-specific code still in apps/web. |
Via the Module API | character-sheet-renderer.md |
| Monster API | A deliberately thin generation surface — listTemplates and generateCharacter. A monster is a projected Character; there is no parallel path for one. |
Via the Module API | monster-api.md |
| Content API | Module-owned content providers, module-hosted routes, the module data store, the host allowlist, and AI parse schemas. | Via the Module API | content-api.md |
| REST / HTTP API | 58 route modules under /api. Clerk auth, CRUD and RPC verbs, soft-delete, and sub-entity routes for granular writes. |
No | rest-api.md |
| AI / GenAI API | /api/ai — LLM endpoints across four providers selected by x-ai-* headers, image generation, sheet parsing, monster and encounter generation, map generation and VBL detection. |
No | ai-api.md |
| Realtime / Socket API | Socket.IO. An actor on every socket (the provider's token in the handshake, v0.95.0), campaign rooms joined through the permission resolver, broadcasts for entity CRUD, presence, initiative, dice, and roll-request relay. | No | realtime-api.md |
| Permissions & the Gatekeeper | Roles and grants on every first-class entity, one resolver (effectivePermissions), one component every private read passes through, and the inventory that puts every GET in exactly one of four sets. Superuser Mode. |
No | read-routes-and-the-gatekeeper.md |
| Time Machine — the commit path | Every write to a campaign, map or character is a commit (a content-addressed snapshot with a parent pointer, on a timeline); versioned(...) as one line on a route; restore as a forked timeline; tags; the guard that puts every write router in one of two sets. |
No | time-machine-commit-path.md |
| Dice / RNG API | The shared deterministic dice contract in packages/shared, consumed by actions, the server and the dice-roller module extension — so a roll means the same thing in all three. |
No | dice-api.md |
Surfaces documented inside another API
These are real contracts, but they belong to one of the APIs above rather than standing alone.
| Surface | Belongs to |
|---|---|
| Auth — Clerk bearer tokens and impersonation | REST API |
| Storage and image upload — presigned URLs and the image proxy | REST API |
| Campaign functions and campaign actions — server-persisted action-code extensions | Action API |
The expression sandbox — renderFunction and bar valueFunction |
Action API, as a sibling execution surface |
System fixtures — SystemFixture and seeding |
System API and Module API |
| Map generation and VBL detection pipelines | AI API |
| Library — the asset store, tag query and classification | REST API, and module-facing through the PlatformAPI facade |
Client SDK — PurpleCatClient, wrapping REST and realtime |
Its own package, over both |
Proposed and committed changes
Each of these targets one of the contracts above. None is a contract itself.
| Document | Targets | State |
|---|---|---|
| Action API 1.0 proposal | Action API | Proposed — adds versioning, typed dialogues and replay |
| Chat invocation document | Action API, presentation only | Shipped as v0.73.0, though the document still opens by saying nothing is built |
| REST API cleanup | REST API | Committed, partially shipped — tracked as API usage refactor |
| Script execution trust boundaries | Action API and the expression sandbox | Shipped for the passive surfaces; the action surface is an accepted boundary |
Reference
Design and data documents that are not API contracts, but that you need in order to read the contracts.
| Document | What it is |
|---|---|
| Data index | Every table in the schema, what it holds, and whether anything specifies it |
| System model | The three-layer System → Campaign → entity inheritance model the System API sits on |
| Module system design | The module system's philosophy, hosting and deployment tiers |
| Module author guide | Everything needed to write a module, end to end |
| Module template | The minimal scaffold for a new module |
| Fixtures | Example system fixture files, and the format they illustrate |
| AI architecture | Why the platform is in-browser first, and where external models fit |
| Character import architecture | How an external character sheet becomes one of ours |
| Library image classification | Which model tags uploaded assets, and what it costs per image |
| Segmentation deployment | Where SAM 2 runs — browser, hosted API, or the operator's GPU — and what each costs; the material behind D5 |
| The service worker | What the installed app's worker caches and what it never touches (the API), how updates reach a client, and the kill-switch runbook |
Two things worth knowing before you build on any of this
POST /api/library/query is a contract, not an internal route. The map
generator picks assets through it — tags in, Jaccard-scored matches out — so its
response shape is owed to a consumer that ships separately from the platform.
v0.66.0 rewrote everything around it and deliberately left that shape untouched;
the scoring even stays in JavaScript rather than moving into SQL, because two
database dialects disagreeing in the last bit of a float would reorder ties for a
caller that cannot see why.
The PlatformAPI facade is an interface, not an implementation. It describes
the imperative platform operations a module would call. It is proposed, and the
type exists; nothing behind it does yet.
Related
- Module Development — the practical guide to writing one, as opposed to the contract it implements.
- Self-hosting — running the platform yourself, which is when the REST and realtime surfaces stop being internal to somebody else.