Skip to main content

Why does worlds:generate return 400 Bad request?

A 400 Bad request means the request was rejected before generation started. The response body is generic and includes a request_id, but not the exact cause. Other status codes narrow things down: 401 is an authentication problem, 402 is insufficient API credits, 422 is a schema validation error, and 429 is a rate limit. The most common cause is a request body that is not valid JSON. This is the usual reason a request that works in curl fails from another HTTP client. Some libraries send an object’s string form instead of JSON. For example, a Java Map.toString() produces key=value pairs with unquoted keys:
Serialize the payload with a JSON library (Jackson, Gson, encoding/json, and similar) before sending it, and set Content-Type: application/json. Setting that header while sending non-JSON bytes still fails. To confirm, log the exact bytes you send and compare them against a working curl payload. Other causes to check:
  • An input URL that World Labs cannot fetch. For an image_prompt or video_prompt with source: "uri", the URL must be reachable with no cookies, referer, or auth. Hosts that block hotlinking or use expiring links fail. Upload the file as a media asset or inline it with source: "data_base64" instead.
  • Input that was rejected by content policy.
  • An invalid model value. Use one of marble-1.0-draft, marble-1.0, marble-1.1, or marble-1.1-plus.
  • A field constraint, such as display_name over 64 characters or more than 10 tags.
Keep the request_id from the response so support can trace the exact failure.

Can I retrieve PLY files from the API?

Yes. Use Export a world to convert a generated world’s SPZ splats into a cached .ply download:
The response is an operation. PLY conversions usually return with done: true and a signed download URL in response.url. You can also export a high-quality mesh with {"asset_type":"mesh","format":"glb"}; mesh exports are asynchronous, so poll the returned operation until it completes.

How do I convert a generated world to real-world (metric) scale?

Generated splat assets are exported in arbitrary model units, not meters. The semantics_metadata object on the world response tells you how to convert to a metric, ground-aligned frame:
  • metric_scale_factor: multiply every XYZ coordinate (and isotropic scale) by this to get meters.
  • ground_plane_offset: after scaling, subtract this from the Y coordinate to place the ground plane at y=0.
For Gaussian splat sizes, renderer coordinate systems, and log-scale scale_0 fields, see Rendering Marble SPZ files in third-party engines.

How does API billing work?

Billing for the World API is separate from billing for the Marble web app.
  • Credits purchased for the Marble app cannot be used with the API
  • API usage requires credits purchased through the World Labs Platform
If you plan to use the API, make sure you purchase credits on the World Labs Platform, NOT in the Marble app.

How do I get a panorama image from my world generation?

Every world generation includes a panorama image in the response, accessible via assets.imagery.pano_url. This panorama is automatically generated as part of the world creation process. The panorama URL will be available in the response at operation.response.assets.imagery.pano_url or when you fetch the world via GET /marble/v1/worlds/{world_id}.

What is the difference between marble-1.0, marble-1.1, and marble-1.1-plus?

World Labs currently offers three API model variants for world generation:
  • marble-1.0 provides standard world generation at a fixed cost.
  • marble-1.1 provides newer standard world generation at a fixed cost.
  • marble-1.1-plus provides the most expansive generation path and may add 0-1,500 variable world generation cost for larger worlds, determined automatically by the system during inference.
For the latest pricing details, see the API pricing page.

Where can I read more about World Labs policies?

Please view our Terms of Service and Privacy Policy for details.