Errors
Errors come back as JSON with an error field, which can be a string or a Strapi object containing message, name, and details. Some endpoints add extra context (status, detail, textures, or a failed composition in data).
{ "error": "Insufficient credits" }Status codes
Section titled “Status codes”| Status | Meaning | Example body |
|---|---|---|
400 | Bad request | { "error": "Unsupported format: .xyz. Allowed: glb, gltf, ..." } |
400 | Bad ZIP layout | { "error": "Archive must contain exactly one .obj/.gltf/.usd file" } |
400 | PLY without faces | { "error": "This PLY file is a 3D Gaussian splat (78,426 splats, no faces). ..." } · "... is a point cloud (N points, no faces). ..." |
400 | Invalid filename | { "error": "Invalid filename" } |
400 | Invalid format on download | { "error": "Invalid format. Expected one of: usd, mjcf, all" } |
400 | Invalid asset_license | { "error": "asset_license must be a string of 200 characters or less (...)" } |
401 | Missing / invalid auth | { "error": "Authentication required" } · { "error": "Invalid API key" } |
402 | Out of credits | { "error": "Insufficient credits" } |
503 | Service temporarily unavailable | Retry later. Pricing failures do not charge the customer. |
404 | Not found / not your job | { "error": "Conversion job not found" } |
404 | MJCF unavailable | { "error": "MJCF package is not available for this conversion" } |
409 | Wrong job state | { "error": "Job not yet completed", "status": "running" } |
409 | Source not completed for simulate | { "error": "Source job must be completed before simulation" } |
413 | Image too big | { "error": "Image too large (max 10MB): front.jpg" } |
429 | Interactive conversation length reached | 40 stored messages; delaying and retrying does not shorten the conversation. |
422 | Missing or long composition prompt | { "error": "prompt is required and must be 2000 characters or less" } |
422 | Missing or long robot task | { "error": "robot_task is required and must be 2000 characters or less" } |
422 | Invalid automatic asset class | { "error": "asset_class must be auto, rigid, or articulated" } |
422 | Invalid generation method | { "error": "generation_method must be auto, procedural, or generative" } |
422 | Generate requested for articulation | { "error": "Generate supports rigid assets only. Use Build for working articulation." } |
409 | Method change during an active attempt | { "error": "The generation method cannot change during an active attempt" } |
422 | Invalid geometry builder | { "error": "geometry_builder must be responses or codex" } |
422 | Invalid composition image count | { "error": "images must contain 0, 1, or 4 files" } |
422 | Unsupported automatic class | { "error": "Automatic generation does not support deformable assets" } |
422 | Bad image format | { "error": "Unsupported source image format for foo.tiff" } |
422 | Texture map on a second UV set | { "error": "Texture maps must use the first UV set (TEXCOORD_0); the conversion refuses a map on any other", "detail": "node \"…\": material 0 \"…\" normalTexture reads TEXCOORD_1. ..." } |
422 | Cannot simulate a simulation | { "error": "Cannot simulate a simulation job" } |
502 | Upstream pipeline unavailable | { "error": "Conversion service unavailable: ..." } |
502 | Automated composition failed | { "error": "Automated composition failed" } |
502 | Simulation service down | { "error": "Simulation service unavailable: ..." } |
POST /api/compositions/generate validates request fields before planning, but currently wraps later prototype-start failures as 502, including unavailable pricing, insufficient credits, and Generate requested for articulation. Its response includes the failed composition in data. Read data.id and data.workflow.error before deciding what to do; a 502 is not necessarily a temporary network failure.
Idempotency and credits
Section titled “Idempotency and credits”- Prototype charges are atomic — Asset Composer deducts the quoted price when generation starts.
- Failed prototype generation or rendering auto-refunds once — an internal idempotency guard prevents duplicate refunds.
401and400never charge — authentication and format validation happen before billing.- A SimReady conformance failure has no billing effect — the conversion completes without a refund, the asset is delivered, and the verdict is in
report.validation. See SimReady Validation. - Automatic generation does not require an idempotency key — overlapping identical requests are coalesced server-side.
How to react
Section titled “How to react”| You see… | Do this |
|---|---|
401 | Check the key. Was it revoked? Has it expired? Is the prefix correct (rgyd_live_)? |
402 | Top up at app.rigyd.com/billing. Show the user — don’t silently retry. |
409 | For result downloads or simulation of an unfinished source, keep polling the source. For an active prototype or method-change conflict, inspect the existing composition before submitting again. |
422 | Surface the message — it’s a request-shape issue and the fix is on the caller side. |
503 | Refresh pricing and wait until the required key is available. |
502 / 5xx | Retry reads with bounded backoff. For a submission, retain any returned job or composition ID and inspect its state first; a new request can create a new paid attempt. A failed paid step is auto-refunded once. |