API reference
Local version 1. No real-token payments, blockchain deposits or withdrawals are enabled.
Game code uses the parent SDK bridge. The browser must not receive a creator key or call account routes with a copied cookie.
Public reads
| GET path | Result |
|---|---|
/api/v1/games | Active local listings, creator link when public, and TEST pool balance |
/api/v1/search?type=games&q= | Active first-party and community game search |
/api/v1/search?type=people&q=&cursor= | Up to 25 opted-in public profiles |
/api/v1/people/{handle} | Opted-in profile, published games and separately shared activity; otherwise 404 |
/api/v1/transparency | Unconfigured financial status |
/api/v1/transparency/snapshots | Empty, unconfigured snapshot list |
Profiles exclude emails and account IDs. Wallet addresses are opt-in; balances remain unavailable. Public profiles include their active published games; drafts and suspended listings are excluded. Public profile pages are not reserve proofs.
Player library
These routes use the signed-in Spawn account session, never a creator API key. Only Spawn's own UI calls them; game frames do not receive that session.
| Method | Path | Purpose |
|---|---|---|
| GET | /api/v1/account/library | Own favorites, recently opened games and sharing preferences |
| POST | /api/v1/account/library | Accepts only gameId and action: favorite, unfavorite or play |
| PUT | /api/v1/account/library-sharing | Sets boolean recent and favorites visibility flags |
The server derives the owner from the session and accepts only available catalog games. It retains at most 100 favorites and 24 additional recent-game records per account. Responses resolve currently available games; suspended or removed listings disappear.
Activity sharing is off by default. Public profile activity.recent and activity.favorites are null unless that category is shared; a private profile remains private regardless of these switches. Email, drafts, account balance and friends are not included. Recent activity records that a game was opened, not a completed run, verified score or reward entitlement.
Creator workspace
These routes require the owner's account session. Paths below start with /api/v1.
| Method | Path | Purpose |
|---|---|---|
| GET / PUT | /account/profile | Read or update own profile |
| GET | /account/balance | Own persistent TEST balance and recent entry/transfer history |
| GET / POST | /projects | List or create own projects |
| GET | /projects/{id} | Project, keys, releases and test pool |
| POST | /projects/{id}/keys | Issue scoped temporary publishing key |
| DELETE | /projects/{id}/keys/{keyId} | Revoke a key |
| POST | /projects/{id}/releases | Upload a browser artifact |
| POST | /projects/{id}/releases/{releaseId}/submit | Confirm an exact played preview |
| GET | /projects/{id}/players | Recent game participants with game-scoped ID, Spawn name and avatar URL |
| GET | /projects/{id}/submissions | Unverified submissions and review status |
| POST | /projects/{id}/submissions/review | Record creator review |
| GET | /projects/{id}/pool | TEST balance and recent transfers |
| POST | /projects/{id}/pool/transfers | Funded TEST top-up, reward or withdrawal |
Pool transfers require kind, amount, requestId, and a game-scoped playerId for rewards. Reuse the same request ID and exact payload after an uncertain response. There is no browser runtime reward authority.
Agent uploads
POST /api/v1/publish/{projectId}/releases accepts a publishing bearer key and:
{
"entry": "index.html",
"files": [{ "path": "index.html", "data": "BASE64_CONTENT" }]
}
An optional sourceCommit is a 40-character hexadecimal commit ID. Read status with GET /api/v1/publish/{projectId}/releases/{releaseId}. These keys cannot approve or publish a release.
Only allowlisted browser assets are accepted. Unsafe paths, hidden files, duplicates, empty entries and excessive sizes are rejected. Structural validation is not a playability or security certification.
Game and payment boundary
The Spawn parent creates /game-sessions, then brokers that launch's storage/{key}, scores and payment-intents operations. The server derives player/game/release authority from the authenticated launch, not game-supplied identity.
A game can request product entry; it cannot set its price. Only the trusted Spawn UI confirms or cancels /payment-intents/{id}. Confirmation binds the exact amount, player and active launch. Successful retries return the original receipt. All balances and receipts in this implementation are TEST-only.
Staff review routes under /admin require an explicitly assigned reviewer or administrator. Signup never creates an administrator automatically.
| Method | Path after /api/v1 | Access |
|---|---|---|
| GET | /admin/reviews | Reviewer or admin: submitted first listings |
| POST | /admin/reviews/{releaseId} | Reviewer or admin: decision, note, played; own first listings cannot be self-approved |
| GET | /admin/games | Admin: current listings and previously published builds |
| POST | /admin/games/{projectId} | Admin: action (suspend, resume, rollback), note, and releaseId for rollback |
| GET / POST | /admin/reviewers | Admin: list reviewers or grant review access to an exact handle |
| DELETE | /admin/reviewers/{handle} | Admin: revoke reviewer access; cannot remove administrator privileges |
Listing changes revoke existing game launches; resuming does not restore old capabilities. Rollback accepts only a previously published build of that project. All role and listing changes are recorded. A local operator command installs the owner-authorized first-party reference separately; it is not exposed to games, publishing keys or creators over HTTP.
Limits and errors
Ordinary writes accept at most 16,384 JSON bytes and reject unknown fields. Build uploads have a separate 35 MB encoded-request / 25 MB decoded-asset limit. Local authenticated traffic is limited to 120 requests per minute per account, with a separate public-read budget per client address; this is not deployed DDoS protection.
Errors use { "error": "message" }: 400 invalid input, 401 missing session, 403 forbidden origin or permission, 404 inaccessible record, 409 conflict, 413 quota and 429 rate limit. Handle failures explicitly; a failed read is not an empty record and a timed-out payment is not permission to charge again.
See SDK and game integration for storage quotas and credential rules. Public hosting, GitHub webhooks, broad server SDK access and real-money APIs remain unavailable.
Player profiles
Every account chooses a unique, case-insensitive Spawn name before using creator or game services. displayName matches that name; there is no numbered suffix. avatarUrl is optional and contains a platform-served image. Game identity never includes email. The private account page masks the connected email.
Signed-in accounts can update their own name, X username and visibility through /api/v1/account/profile. POST /api/v1/account/avatar accepts { "data": "base64 raster image" }, limited to 1 MB PNG, JPEG or WebP. Spawn validates and re-encodes the image; original uploads and metadata are not served. Names and images identify players in games even when their searchable profile is private. Images are public media: anyone with the image link can view them. Versioned links stop resolving when the image is replaced. X usernames are self-reported, not verified.
DELETE /api/v1/game-sessions/{id} revokes the signed-in player’s own launch. Spawn uses this when an embedded game navigates away; a pending entry cannot be confirmed after revocation. Previously completed receipts remain available without charging again.
Private operations
Platform operators use /developer. These routes require a signed-in owner or explicitly assigned platform developer; game creators and contributors cannot read them. All responses are uncached.
| Method | Route | Purpose |
|---|---|---|
| GET | /api/v1/operations | Bounded VPS metrics, service state, signups, console audit and TEST ledger totals |
| POST | /api/v1/operations/pause | Pause or resume game launches and checkout with {paused, reason} |
| POST | /api/v1/operations/developers | Owner only: grant/revoke console access with {handle, enabled} |
Contributors retain the separate game-review API. Console access never grants SSH access or permission to change real token balances. Monitoring refreshes every 15 seconds; samples older than 45 seconds are marked stale. Current reconciliation compares sandbox TEST balances with test grants. Real reserves remain unavailable until the token, custody contract and chain reader exist.
Reviewed multiplayer integration
GET /api/v1/multiplayer/status reports availability. Authenticated POST /api/v1/multiplayer/launches creates a private launch. POST /api/v1/multiplayer/launches/{id}/grant issues a short-lived signed admission; DELETE /api/v1/multiplayer/launches/{id} revokes further grant issuance. Requests cannot select an account or game identity. The opaque game frame receives admission only through its one-use document handshake and MessageChannel. The game receives a game-scoped player identifier and current Spawn name, never the account cookie or email. Signing keys stay on the account server. Existing game leases can last up to ten minutes after renewal is stopped.