Download
Unified download endpoint and async format conversion.
GLB is produced when a submission completes. Other formats are converted on-demand:
either inline via the unified /download endpoint (which waits for the result), or
asynchronously via the /convert job API.
Download a submission asset
GET /api/v1/{submission_id}/download
Public.
Unified endpoint for all downloadable artifacts. GLB is always ready; FBX/OBJ/STL/USDZ trigger an on-demand conversion if not yet cached.
Path Parameters
| Name | Type | Description |
|---|---|---|
submission_id | string (required) | UUID of the submission. |
Query Parameters
| Name | Type | Description |
|---|---|---|
format | string | Asset format. Values: glb, fbx, obj, stl, usdz, py, thumbnail, reference_image. Default: glb. |
textures | string | GLB only. png (default) or webp. |
draco | boolean | GLB only. Draco geometry compression. Default: false. |
index | integer | Index for reference_image format (0–5). Default: 0. |
Example Request
Shipping a GLB to a browser
If the model is going into a web page or a browser game, ask for WebP textures:
Measured at export on real submissions:
| Model | Default (png) | textures=webp | + draco=true |
|---|---|---|---|
| Geometry-heavy (15% textures) | 7.00 MB | 6.28 MB | 1.18 MB |
| Texture-heavy (100% textures) | 18.33 MB | 0.95 MB | 0.91 MB |
Textures are where most of the weight is on most models, and WebP is a plain
image format the browser decodes natively - nothing extra to install, and a
reader that cannot handle it fails visibly. This is the setting to reach for
first. Thrixel's own web viewer serves exactly this: textures=webp, no Draco.
When to add Draco
draco=true compresses the geometry rather than the textures, so it only pays
off on models that are mostly geometry - the first row above, where it turns
6.28 MB into 1.18 MB. On a texture-heavy model it buys about 4%.
Draco needs a decoder on the other end
KHR_draco_mesh_compression is read by three.js (with DRACOLoader), Babylon,
model-viewer and Blender 4.x, but three.js fetches a ~200KB WASM decoder at
runtime and you have to wire it up. A reader without a Draco decoder
usually does not raise an error - it returns the mesh with every vertex at the
origin. Do not hand a Draco file to an unknown tool, and do not feed one back
into a pipeline of your own.
Both flags are independent, and neither changes the model: same parts, same triangle count, same bounds.