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.
Save a generated model
Section titled “Save a generated model”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
| Parameter | Type | Required | Description |
|---|---|---|---|
scene |
object |
Yes* | The serialized agentic scene payload (the /model build path). |
vox_base64 |
string |
— | Deprecated. Raw .vox bytes from the old image pipeline; still accepted for back-compat but not used by current clients. |
thumbnail |
string |
No | data:image/...;base64,... preview captured client-side. |
prompt |
string |
No | The originating prompt, stored (gated) as original_prompt. |
title |
string |
No | Gallery title. Falls back to the scene name or a label; capped at 60 chars. |
description |
string |
No | Public SEO blurb (the finish-tool description). |
tags |
string[] |
No | Discovery keywords; merged with base voxel-art tags. |
assetType |
string |
No | Category hint for tagging. |
genSize |
integer |
No | Generation resolution, used in the fallback title. |
source_job_id |
string |
No | Source job; a flagged job is rejected with 403 CONTENT_FLAGGED. |
projectId |
string |
No | An 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.
List your projects
Section titled “List your projects”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 } ]}Create a project
Section titled “Create a project”POST /api/projects
| Parameter | Type | Required | Description |
|---|---|---|---|
name |
string |
Yes | Project name (≤ 200 chars). |
data |
object |
Yes | The project JSON (models, materials, …) uploaded to storage. |
description |
string |
No | Description (≤ 500 chars). |
isPublic |
boolean |
No | Visibility. Default true. Free plans are public-only — a private request from a free plan is forced public. |
thumbnail |
string |
No | data:image/... preview. |
ogImage |
string |
No | data:image/... 1200×630 social card. |
isAiGenerated |
boolean |
No | Marks the project as AI-generated. |
tags |
string[] |
No | Discovery tags; merged with base voxel-art tags. |
forkedFrom |
string |
No | The source project id when this is a fork/edit (adds an edited tag). |
Response (201):
{ "id": "uuid", "name": "Crystal Tree", "isPublic": true }Read, update, and delete a project
Section titled “Read, update, and delete a project”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.
Browse the public gallery
Section titled “Browse the public gallery”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.
Token balance
Section titled “Token balance”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" }