Skip to main content
The Gizmo public API supports assets only: generate individual 3D assets, manage your asset library, and download exports for your simulator. You only need job and asset IDs. To create or export a full scene, use the browser editor. Scene operations are not part of the public API. Base URL: https://api.gizmo.antimlabs.com/v1

Authentication

Create a key in Settings → API Keys and send it with every request:

Generate and download an asset

1. Start generation

The response is 202 Accepted. Save the job_id. Example fields:
For generation from a reference image:
Replace the example URL with a publicly accessible image. Generation time varies; estimated_seconds is advisory, not a deadline.

Upload local files and supply multiple views

Upload local files as multipart/form-data; you do not need to host images yourself. Use the repeated field name files. Let your HTTP client set the multipart boundary (do not manually set a JSON Content-Type for this request).
The 201 Created response contains images in upload order. Each item has id, content_type, size_bytes, width, height, and sha256. Save the returned IDs:
Send that JSON to POST /v1/assets. Replace the placeholder IDs with real upload IDs. Each reference has exactly one of image_id or url. Accepted view labels are front, back, left, right, top, bottom, perspective, and detail. Labels are optional user descriptions, not calibrated camera poses. You can supply several details or perspectives. With both reference fields present, legacy reference_image_urls come first, followed by reference_images in order. Limits: 8 files per upload; 8 references per generation; 20 MiB and 40 million pixels per file; 80 MiB of file content per upload batch. Supported formats are non-animated PNG, JPEG, and WebP. Invalid files are rejected before the batch is stored. Original bytes are retained without a mandatory crop or concept redraw; model-specific resized copies can be derived separately. Uploads with identical bytes reuse the same ID within your account. Image IDs are private and cannot be used by another account. Uploads currently remain stored without automatic expiry. GET /v1/images/{id} reads metadata. GET /v1/images/{id}/content downloads the exact original bytes. Queued jobs resolve fresh access URLs when they run, so an upload ID does not expire while a job is waiting. External URLs must remain accessible when the worker runs; use uploads if you need a durable reference. Multiple supplied images use the Blender authoring path because the static mesh backend accepts only a single image. All original views and labels are retained. reference_intent.requested_views is a separate advanced option for generated hypotheses; it is not how you attach observed views and is empty by default.

Retry generation safely

Give each intended generation a unique Idempotency-Key (1–128 ASCII letters, digits, dots, underscores, colons or hyphens):
Retry a lost response with the same key and same JSON body. Once accepted, retries return the original job, with Idempotency-Replayed: true. A different body with the same key returns 409 idempotency_key_reused. Concurrent or interrupted acceptance returns 409 request_in_progress with Retry-After: 5; retry the same key. If that persists, contact support with X-Request-ID rather than creating a new key and risking a duplicate job. Keys are scoped to your account and API deployment, and currently retained without automatic expiry. Recorded 4xx responses are replayed too; after correcting such a request, use a new key. Requests without a key create a new job each time. The 202 response includes Location: /v1/jobs/{id} and Retry-After: 30.

2. Wait for the result

Poll every 30–60 seconds until job.status is succeeded, failed, or cancelled. While the job is queued or running, result is null. On success, the result includes the generated asset:
These examples show the fields needed for this workflow; responses can include additional metadata. Use result.asset.id as the asset ID. Job timestamps are Unix milliseconds. If the job fails, inspect job.error; do not attempt an export until generation succeeds.

3. Download the export

Replace ASSET_ID with result.asset.id. The required format is a query parameter. There is no request body. The response contains the file bytes, not JSON or a download URL. Use -o asset.usdz when requesting format=usdz. Content-Disposition supplies a suggested filename. X-Export-File-Count and X-Export-Warnings provide export metadata. GLB export is available in the editor.

Endpoints

Browse your library

GET /v1/assets?limit=20 returns assets newest first. limit defaults to 20 and accepts 1–100. Large records can produce a shorter page. When has_more is true, send the returned next_cursor as the next request’s cursor query parameter. Continue until has_more is false; an empty page alone does not mean you reached the end.

Completion notifications

Generation continues on the server when your client disconnects. Save the job_id to check the result later; you do not need to keep sending requests to keep generation running. Choose either polling every 30–60 seconds or one SSE connection for progress and completion. The API does not provide webhooks or a guaranteed completion email. Any account email notifications are supplementary; use the job status or SSE done event to drive your integration.

Streaming progress

Progress events include a sequence number. Reconnect with ?after=LAST_SEQUENCE to receive later events. Progress event types can vary; ignore types your client does not recognize. ping is a keepalive. done includes the terminal status and job_id, and closes the stream. Fetch the job with include_result=true to retrieve the asset after success.

Errors and limits

Check the HTTP status before reading JSON or saving export bytes. Errors on documented public endpoints use this shape:
Request validation errors return 422 with detail.error.code: "validation_error" and an additional fields array inside detail.error, identifying field locations and messages. Responses include an X-Request-ID for support. Errors from an upstream proxy may have a different body; always check HTTP status first. Rate-limited API-key responses include X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset (Unix seconds). Honor Retry-After on 429 and use exponential backoff with jitter for transient failures. Retry generation with its original idempotency key. Generation uses your account’s credits. See the OpenAPI specification for request schemas and the interactive reference to try requests.

Reference fidelity

Uploaded product photos are preserved for reconstruction by default. For an object inside a scene, the planner keeps the selected original photos and binds them to that object’s name. It does not generate a replacement product shot first. The optional reference_intent request field selects reconstruct, extract, modify, or design. Use modify for requested changes to the pictured object, or design when asking for a new design inspired by the inputs. Your prompt remains the user instruction. Additional generated views are optional hypotheses, not measurements of unseen surfaces.

Python: local files and URL references

For URL-only generation, omit the upload and use reference_image_urls or reference_images: [{"url": "https://your-host/your-image.jpg", "view": "front"}]. Replace all example URLs with accessible images. API keys belong on your server, not in browser bundles. SSE responses include event IDs; resume using Last-Event-ID or ?after=SEQUENCE. Polling and SSE are supported; webhook delivery is not currently implemented. Reference URLs must serve image bytes directly. Redirect responses are not followed; use the final image URL or upload the local file with POST /v1/images.