Changelog
What each published version of the api.scenebrew.com contract added, and how to migrate across the breaking ones.
The contract is published as @scenebrew/public-api-spec; its version is the
info.version the API reports at /openapi.json and the version shown at the
bottom of this site's sidebar.
Scenebrew is a development preview, so the contract is pre-1.0 and there is no major version: a change that breaks callers bumps the minor like any other and says so in its entry below, which is where the warning lives rather than in the digit. Releases up to and including 0.9.0 were originally numbered 1.0.0 to 5.0.0; they were renumbered onto this scheme, one release per minor, without any change to what they contain.
0.14.0 — September 2026
Add a file to an existing asset. Additive.
add_asset_file—POST /v1/assets/{id}/fileswith an uploaded file id and a role (mesh,texture, or a material channel:albedo,normal,roughness,height,metallic,ao,emission,opacity,mask) fills an empty role of an asset, whether or not a recipe already references it. Answers the asset withETag= the role's digest:201when it filled the role,200when the role already held exactly these bytes. A role holding different bytes is never replaced here:409 role_fillednames the recipes (with slots) and themes using the asset underconsumers. There is no force flag. See Library → Add a file to an asset.replace_asset_file—PUT /v1/assets/{id}/files/{role}with an uploaded file id andIf-Matchon the digest the role holds (files[role].sha256) replaces the bytes deliberately: stale412 precondition_failedwithcurrent_sha256, missing header428, empty role412. The replaced digest keeps resolving throughdownload_asset_file?sha256=for the retention period.- Problem documents carry the platform's extension members (
consumers,current_sha256,role) next tocode;412and428join the relayed statuses. The MCP server exposes both operations (tools 0.6.0).
0.13.0 — September 2026
Theme export. Additive.
export_theme—GET /v1/themes/{id}/exportanswers the theme and everything reachable from it (its designs, their recipes, the assets those slot and the assets those reference, embedded once each) as one Scenebrew entity container (.sbe,application/vnd.scenebrew.entity+json): the file a Unity project or the standalone Architect imports. The body is byte for byte what the library wrote;X-Scenebrew-Content-Hashcarries the container's hash, the same whatever the attachment mode.?attachments=full|by-size|by-role|reference(defaultby-size) decides whether asset bytes ride inline or by reference;rolesandslots(repeatable) name whatby-roleinlines. Every attachmenturiisdownload_asset_fileby digest (/v1/assets/{id}/files/{role}?sha256=), never a storage URL. A theme in another project is a404. See Library → Export a theme; the MCP server exposes it asexport_theme(tools 0.5.0).EntityContainerandEmbeddedEntityjoin the published schemas, so generated clients type the export's body.
0.12.0 — September 2026
Assets by role, recipe slots as identity. Breaking in two places; the rest is additive.
AssetRecord.files— the asset's stored bytes as attachments keyed by role:meshfor a mesh asset, one map per channel for a material (albedo,normal,roughness,height,metallic,ao,emission,opacity,mask),texturefor a texture asset. The record also carries what its type holds:format/resolution(texture),shader_name/shader_parameters/texture_refs(material),meshes/materials/textures(mesh).attachmentstays on texture records, deprecated, for exports made before this version.download_asset_fileisGET /v1/assets/{id}/files/{role}and takes?sha256=: with a digest it serves those bytes while they are retained, not the asset's current binding. Breaking:AssetOut.filesis now the record's map by role; the presigned list moved tostored_files(withmedia_type,sha256,size_bytes). Migration: read download URLs fromstored_files, roles fromfiles.link_recipe_assetrequiresslot. A slot holds one asset (409when filled); one asset may fill several slots. Newunlink_recipe_slot(DELETE /v1/recipes/{id}/slots/{slot}) empties one slot. Breaking:create_recipetakesassets(slot → asset id) instead ofasset_ids. Migration: name the operator slot for every asset you bind.ThemeStyle— the style profile under a theme'smetadata.style, published as a schema and validated on write. Creates and updates acceptmetadata. New recipe typescatter_propsand design typescatter-props;DesignTypeOut.hda_operatoris nullable.
0.11.0 — September 2026
Stable asset files and the shared reference shapes. One schema rename; otherwise additive.
download_asset_file—GET /v1/assets/{id}/files/{filename}answers307to a short-lived presigned URL, likedownload_scene_artifactdoes for artifacts: the stable form of an attachment'suriin an exported entity container. The route never expires; the URL it redirects to does.EntityReferenceis nowReference, andAttachmentis scenebrew-formats' own model, so the API and the.sbecontainer share one definition of both shapes. Same keys, same constraints; only the schema name moved. Migration: rename the one generated type.
0.10.0 — September 2026
Library records — the entity container payloads. Additive.
- Records.
ThemeRecord,DesignRecord,RecipeRecordandAssetRecordare what a library entity is, independent of the cloud: the payload a Scenebrew entity container embeds. The responsesThemeOut,DesignOut,RecipeOut,AssetOutare each a record plus the server-only fields (id,slug,project_id,thumbnail_url,created_at,updated_at). - Theme:
world(the constraints-first world block),scene_parameterskeyed by planning module,designsas ordered references. Design:recipesas ordered references. Recipe:operator,operator_version,assetskeyed by operator slot. Asset:attachment. - Inputs:
create_theme/update_themeacceptworldandscene_parameters;create_recipe/update_recipeacceptoperator_version;link_recipe_assetacceptsslot.
0.9.1 — September 2026
Wording only. The delete operations now say what deletion does: a deleted project or scene is hidden at once and purged — rows, stored artifacts, uploaded files and conversation transcripts — 30 days later, and a Scenebrew user can restore it from the app's trash until then. No shape, status or field changed.
0.9.0 — September 2026
Artifact-format and validation follow-up. Breaking for the artifact kind enum; the rest is additive or a stricter upload check.
tilemapis no longer an artifact kind. A tilemap is never a standalone artifact — it rides inside theblueprintswfbpxpackage, alongside heightmaps and shapes.?kind=tilemapandGET …/artifacts/tilemapnow return422/404. Migration: read the blueprint; the tilemap is inside it.download_expires_at(RFC 3339) is added next todownload_expires_inon every presigned download — scene artifacts, files, asset files and recipe previews — the absolute instant the URL stops working.- Upload validation. The
sddis open-ended (an AI reads it): only UTF-8 is required, plus that every image it references is embedded inline as adata:URI (SDD_IMAGE_NOT_CONTAINEDotherwise). Thepegis fully schema-validated, and theblueprintswfbpxis schema- and integrity-validated, on upload — invalid documents answer400 INVALID_ARTIFACTbefore anything is stored.
0.8.0 — September 2026
The full developer surface: one name per action across REST, SDK and MCP; everything slow is an operation; cursor pagination; files as a resource; the library. Old names are gone — there are no aliases.
- Steps are named after the tool that runs them:
create_sdd → generate_scene_sdd,build_peg → generate_scene_peg,generate_layout → generate_scene_blueprint,brew_scene → generate_scene_model. Artifact kindglb → model. Declared but not yet available (501 not_implemented):revise_scene_sdd,revise_scene_peg,analyze_scene_image,decorate_scene. - Operations:
GET /v1/scenes/{id}/steps/{step_id}andGET /v1/sessions/{id}/turns/{turn_id}are replaced byGET /v1/operations/{id}(one resource for scene steps, session turns and library generations; statusesqueued | running | canceling | succeeded | failed | canceled),GET /v1/operations?target_id=(history) andPOST /v1/operations/{id}/cancel. Every write that starts work answers202with the operation and honoursPrefer: wait=N(N ≤ 60):200with the finished operation when it completes in time. - Pagination is
limit/cursorwithnext_cursoreverywhere (page/page_sizeare gone); transcripts page withbefore/aftermessage ids, newest first, and carryoperation_id. - Sessions:
POST /v1/projects/{id}/sessionsrequirestext— a session is born with its first message and returnsinitial_turn. AddedPATCH/DELETE /v1/sessions/{id},POST /v1/sessions/{id}/context,DELETE /v1/sessions/{id}/context/{kind}/{entity_id}; messages takefile_ids. - Files and artifacts:
POST /v1/files(many files per request, 100 MB) andGET /v1/files/{id}; scenes taketheme_idandsource_file_idat create;DELETE /v1/scenes/{id};GET /v1/scenes/{id}/sessions;GET /v1/scenes/{id}/artifacts/{kind}(?inlinefor SDD/PEG text),GET …/artifacts/{kind}/content(307 to the bytes) andPUT /v1/scenes/{id}/artifacts/{kind}to bring your own SDD, PEG or blueprint. - Projects, credits, models:
POST /v1/projects,GET/PATCH/DELETE /v1/projects/{id},GET /v1/me/creditsandGET /v1/models(modelis accepted on AI steps, sessions and generations). - Library:
/v1/projects/{id}/{themes,designs,recipes,assets}(list, create) and/v1/{themes,designs,recipes,assets}/{id}(get, update, delete), the three membership links,GET /v1/design-types,GET /v1/recipe-types,POST /v1/recipes/{id}/previewandPOST /v1/projects/{id}/generations(one contract for all four kinds;assetruns today). - MCP tools 0.2.0 at
mcp.scenebrew.com/v1/mcp: the same names as tools, alibrarytoolset via?toolsets=, every operation-backed tool takeswait.
Migration from 0.7.0: rename the four step values and the three tool
names, read kind: model where glb was read, poll GET /v1/operations/{id}
instead of the step/turn paths, page with limit/cursor, and give
POST /v1/projects/{id}/sessions a text. Prefer: wait=N replaces any
implicit hold a client relied on.
0.7.0 — September 2026
Layout and brew became steps, not synchronous calls: a brew of a real scene runs for minutes, longer than a request should stay open.
POST /v1/scenes/{id}/layoutandPOST /v1/scenes/{id}/brewwere removed. Both ran asPOST /v1/scenes/{id}/steps(generate_layout,brew_scene;202) and were polled like the AI steps. Preconditions409 MISSING_PEG/MISSING_BLUEPRINT; failureslayout_failed,brew_failed,runner_unavailable. The procedural steps stayed free.
0.6.0 — September 2026
AI work became keyed by scene, not by session.
POST /v1/sessions/{id}/turns(step runs) was removed; AI steps ran asPOST /v1/scenes/{id}/stepson a scene created with the newPOST /v1/projects/{id}/scenes.- A session carried
context— the scenes and library entities it refers to — instead of ascene_id; a turn described a posted message (POST /v1/sessions/{id}/messages). - Added
GET /v1/projects/{id}/sessionsandGET /v1/sessions/{id}/messages.
0.5.0 — September 2026
The first write surface: sessions, turns, layout, brew, scene updates, the
write scope, and the MCP server at mcp.scenebrew.com/v1/mcp.
0.4.0 — September 2026
size_bytesdeclaredint64on artifacts.- Contract version now equals the API's
info.version.
0.3.0 — September 2026
- Description-only changes.
0.2.0 — August 2026
- Scopes enforced:
readrequired on the data operations,403withWWW-Authenticate: Bearer error="insufficient_scope"otherwise.GET /v1/mestays scope-free.
0.1.0 — August 2026
Initial public API: GET /v1/me, GET /v1/projects,
GET /v1/projects/{project_id}/scenes, GET /v1/scenes/{scene_id}/artifacts
with presigned downloads; API keys in the app; problem+json errors.