Skip to content

Projects & Cloud Save

Beyond generation, the API exposes the endpoints the app uses to persist models, manage projects, browse the public gallery, and read account state. These store models in cloud storage (R2) and metadata in the projects database.

The Projects / Gallery UIImage to be added
The projects dashboard and public gallery these endpoints power.

Auto-saves a completed AI generation as a public gallery project. There is no paid-plan check — generation is already token-gated. Pass the serialized scene from an agentic build; the endpoint parses it into the project JSON format, uploads it (plus an optional thumbnail) to storage, and inserts the metadata row with is_ai_generated = true.

POST /api/generate/save

ParameterTypeRequiredDescription
sceneobjectYes*The serialized agentic scene payload (the /model build path).
vox_base64string—Deprecated. Raw .vox bytes from the old image pipeline; still accepted for back-compat but not used by current clients.
thumbnailstringNodata:image/...;base64,... preview captured client-side.
promptstringNoThe originating prompt, stored (gated) as original_prompt.
titlestringNoGallery title. Falls back to the scene name or a label; capped at 60 chars.
descriptionstringNoPublic SEO blurb (the finish-tool description).
tagsstring[]NoDiscovery keywords; merged with base voxel-art tags.
assetTypestringNoCategory hint for tagging.
genSizeintegerNoGeneration resolution, used in the fallback title.
source_job_idstringNoSource job; a flagged job is rejected with 403 CONTENT_FLAGGED.
projectIdstringNoAn existing owned project to update in place (the “modify” re-save) instead of inserting a duplicate.

* Provide scene. (vox_base64 is the deprecated alternative input; supply one or the other.)

Response — 201 on insert, 200 on an in-place update:

{ "projectId": "uuid", "slug": "crystal-tree-ab12cd", "name": "Crystal Tree" }

On a projectId update, the original title/description/slug are preserved (a “make it red” modify prompt would be a poor gallery title); only geometry, counts and thumbnail change.

GET /api/projects?limit={≤50}&offset={n}

Returns the caller’s projects, newest first:

{
"projects": [
{
"id": "uuid",
"name": "Crystal Tree",
"description": "...",
"is_public": true,
"thumbnail_url": "https://.../thumbnails/uuid.jpg",
"voxel_count": 1840,
"model_count": 1,
"created_at": "...",
"updated_at": "...",
"tags": ["voxel", "tree"],
"is_ai_generated": true,
"forked_from": null
}
]
}

POST /api/projects

ParameterTypeRequiredDescription
namestringYesProject name (≤ 200 chars).
dataobjectYesThe project JSON (models, materials, …) uploaded to storage.
descriptionstringNoDescription (≤ 500 chars).
isPublicbooleanNoVisibility. Default true. Free plans are public-only — a private request from a free plan is forced public.
thumbnailstringNodata:image/... preview.
ogImagestringNodata:image/... 1200×630 social card.
isAiGeneratedbooleanNoMarks the project as AI-generated.
tagsstring[]NoDiscovery tags; merged with base voxel-art tags.
forkedFromstringNoThe source project id when this is a fork/edit (adds an edited tag).

Response (201):

{ "id": "uuid", "name": "Crystal Tree", "isPublic": true }

GET /api/projects/{id} — public projects need no auth; private ones require the owner. Append ?meta=1 to fetch metadata without the stored scene data. The originating prompt is gated: the owner always sees it, other viewers only on a paid plan (otherwise promptLocked: true).

PUT /api/projects/{id} — owner only; full update including the stored scene. Fork-on-edit: editing an AI original whose geometry changed forks a new project owned by the editor (tagged edited) rather than overwriting the canonical original; metadata-only edits update in place.

PATCH /api/projects/{id} — owner only; metadata only (name, description, isPublic, tags), no scene write.

DELETE /api/projects/{id} — owner only; removes the stored objects and the database row.

GET /api/gallery?limit={≤48}&offset={n}&q={search}&filter={ai|manual}

Public, no auth. Searches names and tags, batches in author profiles, and returns the same project shape as the list endpoint with an added author.

GET /api/tokens

Returns the account’s current balance and plan. Lazily creates a balance record for new accounts (a one-time 6-token grant) and performs the monthly reset.

{ "balance": 4, "plan": "free" }