Registry API
Base URL: https://creators.threetopia.com/api. JSON endpoints return { "message": "…" } on error, sometimes with a details array. Use the CLI unless you need a direct integration.
Authentication
Browser authentication uses a host-only, HttpOnly, Secure, SameSite=Lax cookie. Browser mutations require the same Origin. CLI authentication uses Authorization: Bearer TOKEN. Never put a token in a URL or package file.
| Method and path | Purpose |
|---|---|
GET /health |
Registry version and docs |
POST /auth/start |
Request code: {email}; browser same-origin |
POST /auth/verify |
Verify {challenge,code} and set session cookie |
GET /me |
Current creator or null |
PATCH /profile |
{handle,displayName}; handle is permanent |
POST /auth/logout |
Revoke current credential |
POST /auth/device |
Start CLI device flow; empty JSON object |
POST /auth/device/poll |
{deviceCode}; pending returns 202 |
POST /auth/device/approve |
Browser only: {userCode,approve:true} |
GET /tokens |
List current creator’s CLI credentials |
DELETE /tokens/:id |
Revoke own CLI credential |
Device flow returns deviceCode, userCode, verificationUri, expiresIn, and interval. Poll at that interval; approval returns accessToken. The device code is confidential and is not the public user code.
Tiles
| Method and path | Purpose |
|---|---|
GET /tiles |
Original worlds, current slots, published/reserved tiles, 144 variants |
POST /tiles/reserve |
{q,r,variant}; returns ID and canonical contract |
GET /tiles/:id |
Own reservation and full contract |
DELETE /tiles/:id |
Release own unused reservation |
Reservations are atomically unique by coordinate. World creation requires an owned reservation; upload requires its exact canonical contract.
Packages
| Method and path | Purpose |
|---|---|
GET /packages?kind=asset&q=beacon |
Public published catalog |
GET /packages?mine=1 |
Authenticated creator’s packages and states |
POST /packages |
{name,kind,title,description,tileId?} |
GET /packages/:id |
Metadata, versions; own page includes installers |
GET /resolve?name=@creator/name&version=1.0.0 |
Public exact version, manifest and file hashes |
DELETE /packages/:id |
Delete own unpublished package |
Omit version or use latest to resolve the highest published numeric version. Use exact versions in dependency manifests.
Upload lifecycle
POST /packages/:id/versionswith the full package manifest, including file paths, byte lengths and SHA-256 hashes.PUT /packages/:id/versions/:version/files?path=…with each file’s raw bytes.POST /packages/:id/versions/:version/validatewith{}. The server measures uploaded geometry; a valid version becomes ready.- Review the owner-only preview.
POST /packages/:id/versions/:version/publishwith{}to publish.
GET /packages/:id/versions/:version/files?path=… serves bytes. Ready and draft files require the owner’s credential. Published files are public and immutable. Uploaded HTML/JavaScript is served as an attachment with a restrictive CSP and is not executed by the site.
DELETE /packages/:id/versions/:version removes an unpublished draft. Published versions cannot be changed or deleted.
Installations
After verifying and writing all files, the CLI calls POST /packages/:id/install with {version,projectId}. projectId is a random project UUID, not its name or path. DELETE at the same endpoint with {projectId} removes that active installation.
These records describe CLI-reported installations, not arbitrary downloads or proof that a package is actively rendered. Package owners see public creator handles and versions; no private project data.