3D → SimReady
Upload a 3D model and Rigyd returns a SimReady USD asset — physics properties, collision meshes, and materials filled in automatically.
| Method | POST |
| Path | /api/conversions |
| Content-type | multipart/form-data |
| Job type | glb_to_simready |
| Credits | 5 |
Accepted formats
Section titled “Accepted formats”.glb, .gltf, .fbx, .obj, .stl, .ply, .usd, .usda, .usdc, .usdz, and .zip (for multi-file inputs).
.glb skips the preprocessing stage and is the fastest path unless you enable mesh optimization. Anything else goes through Blender-based cleanup first — see Supported formats for the rules around ZIP archives, OBJ + MTL, GLTF + bin, and USD with references.
Request fields
Section titled “Request fields”| Field | Type | Required | Notes |
|---|---|---|---|
file | file (upload) | yes | The 3D model. See accepted formats above. |
description | string | no | What the object is, in your words. Explicit material, size and mass claims in it outrank what the pipeline reads off the renders. Max 2000 characters. |
declared | JSON object | no | What you already KNOW: mass_kg, volume_m3, dimensions_m (length_m/width_m/height_m, any subset), materials (strings), object_category, construction and wall_mm. Outranks both the description and the renders. |
optimize | boolean | no | Run mesh optimization during preprocessing. Default false. |
target_triangle_count | int | when optimize=true | Target triangle count for optimization. 1000–1000000. |
threshold | float | no | CoACD collision-decomposition concavity threshold (advanced). |
llm_provider | string | no | Override the LLM used for material identification (advanced). |
skip_validation | boolean | no | Suppresses the internal correctness gate. Does not skip SimReady scoring. Leave unset. Default false. |
Size, mass and materials
Section titled “Size, mass and materials”Your file’s coordinates are taken as metres, which is what glTF requires, and the delivered asset keeps the size you uploaded. The pipeline only resizes a file that is off by more than a factor of two from any plausible size for the object — a model exported in millimetres or centimetres, or a generator’s unit cube.
description and declared say what the file cannot. Use declared whenever
you have the numbers: it is read as numbers, while a description is prose and
prose has to be interpreted. A declared box is applied per axis, so the
delivered asset measures exactly what you stated.
-F 'declared={"mass_kg": 0.411, "dimensions_m": {"length_m": 0.21, "width_m": 0.158, "height_m": 0.06}}'A partial declaration is fine — state the one axis you measured.
What the object is made of, and what it is
Section titled “What the object is made of, and what it is”A render shows shape, colour and finish. It cannot show what a thing is made of when the object imitates another material, and that is where the largest mass errors come from: a plastic lemon looks exactly like a lemon, a foam brick like a fired one. Two fields say what the pictures cannot.
materials is what it is made of. It replaces what the pipeline reads off the
renders, so state all of them if the object is genuinely mixed.
construction is how that material is arranged — "shell" (a wall around
empty space) or "solid" (a filled region) — with an optional wall_mm. This matters
more than it looks: naming the plastic in a replica lemon without saying it is
hollow makes it heavier, because plastic is denser than fruit peel.
object_category is the interior model, one of:
hollow_thin, hollow_thick, upholstered, padded, stuffed, solid,
solid_wood, composite_frame, electronic, wearable, packaged_dry,
packaged_wet
Sealed retail packaging converts as the product as sold — a cracker box is its
crackers, a soup can its soup. It is also how fill state is stated: an empty
box is hollow_thin, a full one packaged_dry (or packaged_wet for a can,
jar or bottle).
-F 'declared={"materials": ["hard plastic"], "construction": "shell", "wall_mm": 1.5, "object_category": "hollow_thin"}'Where each number came from
Section titled “Where each number came from”The job report labels the provenance of every physical fact it returns:
mass.source, geometry.dimensions_source, materials_source and
asset.category_source. declared is what you stated, mesh is measured off
your uploaded geometry, and recalled, identified and estimated are the
pipeline’s own inference. Anything you declare comes back labelled declared.
Examples
Section titled “Examples”curl -X POST https://api.rigyd.com/api/conversions \ -H "Authorization: Bearer rgyd_live_..." \ -F "file=@./toolbox.glb" \ -F "description=A steel hand-tool box, empty" \ -F 'declared={"mass_kg": 2.4, "dimensions_m": {"length_m": 0.48}}' \ -F "optimize=true" \ -F "target_triangle_count=50000"import fs from 'node:fs';
const form = new FormData();form.append('file', new Blob([fs.readFileSync('./toolbox.glb')]), 'toolbox.glb');form.append('description', 'A steel hand-tool box, empty');form.append('declared', JSON.stringify({ mass_kg: 2.4, dimensions_m: { length_m: 0.48 } }));form.append('optimize', 'true');form.append('target_triangle_count', '50000');
const res = await fetch('https://api.rigyd.com/api/conversions', { method: 'POST', headers: { Authorization: `Bearer ${process.env.RIGYD_API_KEY}` }, body: form,});const { data } = await res.json();import json, os, requests
with open("toolbox.glb", "rb") as f: res = requests.post( "https://api.rigyd.com/api/conversions", headers={"Authorization": f"Bearer {os.environ['RIGYD_API_KEY']}"}, files={"file": ("toolbox.glb", f, "model/gltf-binary")}, data={ "description": "A steel hand-tool box, empty", "declared": json.dumps({"mass_kg": 2.4, "dimensions_m": {"length_m": 0.48}}), "optimize": "true", "target_triangle_count": 50000, }, )job = res.json()["data"]Response — 202 Accepted
Section titled “Response — 202 Accepted”{ "data": { "id": "abc123...", "physiq_job_id": "phy_...", "status": "queued", "filename": "toolbox.glb", "progress": 0, "job_type": "glb_to_simready", "credits_charged": 5, "createdAt": "2026-05-06T12:00:00.000Z" }}For non-GLB inputs, status starts at preprocessing while the model is converted to a clean GLB, then transitions to queued → running → completed.