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, thumbnail, reference_image. Default: glb. |
textures | string | GLB only. png (default) or webp. |
draco | boolean | GLB only. Draco geometry compression. Default: false. |
target | string | FBX only. The engine the file is for: generic (default), roblox, unity or ue5. See FBX for an engine. |
skeleton | boolean | FBX only. false drops a rigged model's skeleton and skin weights, keeping its rest pose. Default: true. |
index | integer | Index for reference_image format (0–5). Default: 0. |
Example Request
GLB is served straight from storage:
curl -L -o model.glb https://api.thrixel.com/api/v1/a1b2c3d4-.../download?format=glbAny other format triggers a conversion, so the first request for it may take a few seconds:
curl -L -o model.fbx https://api.thrixel.com/api/v1/a1b2c3d4-.../download?format=fbxShipping a GLB to a browser
If the model is going into a web page or a browser game, ask for WebP textures:
curl -L -o model.glb https://api.thrixel.com/api/v1/a1b2c3d4-.../download?format=glb&textures=webpMeasured 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.
FBX for an engine
Every FBX embeds its textures, carries metallic and roughness maps, and writes no
extra end bones. Any mesh over 20,000 triangles is split into pieces under that, so
a high-detail model still imports into engines with a per-mesh limit. Add target
to shape the file for one engine:
target | What changes |
|---|---|
generic | Nothing beyond the above. |
roblox | A .zip: the FBX as a Roblox R15 rig, textures at 1024 px, and a textures/ folder with each material's ColorMap, NormalMap, RoughnessMap and MetalnessMap PNGs for a SurfaceAppearance. See Roblox R15. |
unity | Bones renamed for Unity's Humanoid avatar (Hips, LeftUpperLeg...). |
ue5 | Bones renamed to the UE5 Mannequin (pelvis, thigh_l...), with a root bone above pelvis. |
Bone names only change on a humanoid Rig; any other model gets the same file
as generic, except that roblox still applies its texture size and maps.
curl -L -o model-roblox.zip https://api.thrixel.com/api/v1/a1b2c3d4-.../download?format=fbx&target=robloxRoblox R15
On a humanoid Rig, target=roblox rebuilds the skeleton to Roblox's
R15 layout:
- 15 bones (
LowerTorso,UpperTorso,Head, andUpper/Lower/HandandUpper/Lower/Footon each side) underRoot>HumanoidRootNode. - Joints R15 does not have fold into the bone they sit on, weights included: the
spine and clavicles into
UpperTorso, the neck intoHead, fingers into the hand, toes into the foot. LowerTorsoandRootat the origin, at most 4 bones per vertex, none onRoot.- One mesh per body part, named after its bone (
LeftUpperArm_Geo...). A part over 20,000 triangles is still split, so it arrives as two meshes.
The advanced R15 bones (fingers, extra spine joints) and the avatar attachments are not included.
Importing into Roblox Studio. Roblox does not build materials from an FBX, so a
model imported on its own shows grey. Import the .fbx with the 3D Importer, then
for each MeshPart add a SurfaceAppearance and set its ColorMap, NormalMap,
RoughnessMap and MetalnessMap from the matching PNGs in the zip's textures/
folder (each file is named after its material). SurfaceAppearance.txt in the zip
lists, per material, the MeshParts that use it and the files to set.
Glowing parts. A part that glows in the model (a lamp, a headlight, a neon sign)
comes with an EmissiveMask PNG, a flat ColorMap, and an EmissiveStrength and
EmissiveTint in SurfaceAppearance.txt: set EmissiveMaskContent,
EmissiveStrength and EmissiveTint on that part's SurfaceAppearance. This covers
models made with Create and Edit; Sculptor and Detailer results do not carry a glow
yet.