---
title: "SimReady Asset Composer"
description: "Compose a rigid or articulated simulation asset from intent and optional visual references."
---

import { Aside } from '@astrojs/starlight/components';

SimReady Asset Composer is the planning and generation layer before conversion. Give it the object you need, the robotic task it must support, and optionally one reference image or four ordered views. It composes those inputs into a simulation brief, chooses a rigid or articulated structure, generates the prototype, and can submit that prototype to SimReady automatically.

The workflow is input-agnostic: text-only, text plus one image, and text plus four views use the same endpoint and return the same composition resource. The API route is non-interactive and never pauses for clarification; the Rigyd web app uses the same composer concepts with an interactive review flow.

Set `auto_submit: true` for an unattended Composition → SimReady run. Leave it `false` to inspect the generated prototype before submitting it.

<Aside type="tip">
  Prefer a terminal command? `rigyd compose "object description" --task "robotic task" --asset-class auto` creates, polls, submits, and downloads the workflow. Add `--review` to stop at `ready`. See [CLI & Python SDK](/tools/cli).
</Aside>

## Request

```bash
curl -X POST https://api.rigyd.com/api/compositions/generate \
  -H "Authorization: Bearer rgyd_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "A stainless steel cabinet with two hinged doors",
    "robot_task": "Open and close either door with a parallel gripper",
    "asset_class": "articulated",
    "geometry_builder": "codex",
    "auto_submit": true,
    "physical_context": {
      "dimensions_m": { "length": 0.8, "width": 0.45, "height": 1.2 },
      "mass_kg": 32,
      "materials": ["stainless steel"],
      "fixed_base": true
    }
  }'
```

JSON and multipart requests are supported. For multipart requests, attach images with repeated `images[]` fields. Image count must be `0`, `1`, or `4`; four views are ordered front, right, back, left.

| Field | Required | Rules |
|---|---:|---|
| `prompt` | yes | 1–2,000 characters |
| `robot_task` | yes | 1–2,000 characters |
| `asset_class` | no | `auto`, `rigid`, or `articulated`; default `auto` |
| `geometry_builder` | no | Articulated prototype builder: `responses` or `codex`; default `responses` |
| `auto_submit` | no | Boolean; default `false` |
| `negative_prompt` | no | Up to 255 characters |
| `physical_context` | no | `dimensions_m`, `mass_kg`, `materials`, and `fixed_base` |
| `images` | no | 0, 1, or 4 JPEG, PNG, or WebP files; 10 MB each |

An explicit `rigid` or `articulated` class overrides inference. `auto` requests classified as deformable or mixed fail before a prototype charge is taken.

`geometry_builder` only changes articulated prototype generation. `responses` uses the existing single Responses API build. `codex` runs the articulated Three.js skill in an isolated Codex worker, verifies the Physiq contract, visually reviews closed and articulated poses with Playwright, and exports the approved GLB from that same worker.

<Aside type="note">
  This endpoint does not require an `Idempotency-Key`. Overlapping identical requests for the same customer coalesce while the first request starts generation. A later identical batch job remains valid.
</Aside>

## Response and polling

The endpoint returns `202 Accepted`. Poll `GET /api/compositions/:id`:

```json
{
  "data": {
    "id": "composition-id",
    "interaction_mode": "non_interactive",
    "requested_asset_class": "articulated",
    "geometry_builder": "codex",
    "physical_context": {
      "dimensions_m": { "length": 0.8, "width": 0.45, "height": 1.2 },
      "mass_kg": 32,
      "materials": ["stainless steel"],
      "fixed_base": true
    },
    "workflow": {
      "status": "running",
      "stage": "prototype_generation",
      "progress": 45,
      "auto_submit": true,
      "assumptions": [],
      "error": null
    },
    "conversion_job_id": null
  }
}
```

Workflow statuses are `running`, `ready`, `completed`, `failed`, and `cancelled`. `ready` means the prototype is available and awaits manual SimReady submission. `completed` means automatic SimReady conversion completed.

Stages are `composing`, `planning`, `prototype_generation`, `prototype_rendering`, and `simready_conversion`. Poll every 3–5 seconds.

Composition IDs and conversion-job IDs are different. Poll the composition while it is planning or generating. Once submitted, `conversion_job_id` identifies the SimReady conversion used by the [conversion-job endpoints](/jobs/retrieve).

<Aside type="note">
  Articulated requests still run `prototype_rendering` when `auto_submit=false`. That stage exports the closed-pose GLB, articulation manifest, and four canonical captures used for review. It does not start SimReady conversion.
</Aside>

## Submit a reviewed prototype

When `auto_submit=false`, wait for workflow status `ready`, then submit the stored prototype:

```bash
curl -X POST https://api.rigyd.com/api/compositions/composition-id/submit \
  -H "Authorization: Bearer rgyd_live_..." \
  -H "Content-Type: application/json" \
  -d '{}'
```

The endpoint returns `202 Accepted` with the conversion job, not another composition envelope:

```json
{
  "data": {
    "id": "conversion-id",
    "status": "queued",
    "progress": 0,
    "job_type": "authored_to_simready",
    "credits_charged": 0,
    "composition_id": "composition-id"
  }
}
```

Poll `GET /api/conversions/:id` for that returned ID. The original composition also exposes it as `conversion_job_id` and advances through `simready_conversion` to `completed`.

## List compositions

`GET /api/compositions?page=1&pageSize=25` lists your composition workflows newest first. These are not returned by `GET /api/conversions`; only the SimReady conversion created after submission appears in the conversion-job list.