Idol 1 API: Pricing, Documentation
by Sperid Labs
Idol by Sperid Labs — turn one image of an object into a 3D Gaussian splat (.ply), including the sides the image never showed.

Models Version
Get 10% Cashback on Your First Payment (up to $500)
Add funds and get 10% cashback on your first payment (up to $500).
Idol API Documentation
Turn one image of a single object into a 3D Gaussian splat: up to about a million small colored 3D Gaussians, including the sides the image never showed, delivered as a standard 3DGS .ply file. The background is removed and the object is framed for you, so a render, a generated image or a photo all work. Asynchronous: submit returns a request_id; poll the status endpoint until the request is COMPLETED.
POST https://gateway.pixazo.ai/idol/v1/image-to-3dAuthentication
All requests require an API key passed via header.
| Header | Type | Required | Description |
|---|---|---|---|
| Ocp-Apim-Subscription-Key | string | Yes | Your API subscription key |
Image to 3D - Idol
Request Code
POST https://gateway.pixazo.ai/idol/v1/image-to-3d
Content-Type: application/json
Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY
{
"image_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/minimax_images/h3-image/2026/11/11/a5a743ec-24cc-424d-98df-ecd6ef235998.jpg"
}import requests
url = "https://gateway.pixazo.ai/idol/v1/image-to-3d"
headers = {
"Content-Type": "application/json",
"Ocp-Apim-Subscription-Key": "YOUR_SUBSCRIPTION_KEY"
}
data = {
"image_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/minimax_images/h3-image/2026/11/11/a5a743ec-24cc-424d-98df-ecd6ef235998.jpg"
}
resp = requests.post(url, json=data, headers=headers)
print(resp.json())const res = await fetch("https://gateway.pixazo.ai/idol/v1/image-to-3d", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Ocp-Apim-Subscription-Key": "YOUR_SUBSCRIPTION_KEY"
},
body: JSON.stringify({
"image_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/minimax_images/h3-image/2026/11/11/a5a743ec-24cc-424d-98df-ecd6ef235998.jpg"
})
});
console.log(await res.json());curl -X POST 'https://gateway.pixazo.ai/idol/v1/image-to-3d' \
-H 'Content-Type: application/json' \
-H 'Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY' \
--data-raw '{"image_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/minimax_images/h3-image/2026/11/11/a5a743ec-24cc-424d-98df-ecd6ef235998.jpg"}'Output
{
"request_id": "idol_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"status": "QUEUED",
"polling_url": "https://gateway.pixazo.ai/v2/requests/status/idol_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}Webhook (Optional)
Instead of polling, you can receive a Webhook callback when the request reaches a terminal state. Provide a Webhook URL via header on the submit request.
| Header | Required | Description |
|---|---|---|
| X-Webhook-URL | To enable | HTTPS URL to receive the Webhook callback. |
| X-Webhook-Mode | No | terminal (default, one callback on COMPLETED/ERROR) or sync (per-poll callbacks). |
Callback Payload (success)
{
"request_id": "idol_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"status": "COMPLETED",
"model_id": "idol",
"error": null,
"output": {
"media_url": [
"https://pub-582b7213209642b9b995c96c95a30381.r2.dev/v1/idol_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/output.ply"
],
"media_type": "model/ply"
},
"created_at": "2026-11-11T12:56:10.571Z",
"updated_at": "2026-11-11 12:56:38",
"completed_at": "2026-11-11 12:56:37"
}Failure callback shape
{
"request_id": "idol_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"status": "ERROR",
"model_id": "idol",
"error": "Generation failed: the request was rejected (image_url: Failed to load the image. Please ensure the image file is not corrupted and is in a supported format).",
"output": null,
"created_at": "2026-11-11T12:58:51.848Z",
"updated_at": "2026-11-11 12:59:00",
"completed_at": "2026-11-11 12:59:00"
}Callbacks are idempotent on request_id — de-duplicate on it. Respond 200 within a few seconds; the Webhook endpoint must be HTTPS.
Request Parameters
| Parameter | Required | Type | Default | Allowed values / range | Description |
|---|---|---|---|---|---|
image_url | Yes | string | — | A public http(s) URL of the image | The image of ONE object. Renders, generated images and photos all work; the background is removed and the object is framed for you. |
image_type | No | string | synthetic | synthetic, real | synthetic for renders and generated images (the object is framed tightly); real for photographs (looser framing). |
num_inference_steps | No | integer | 50 | 1 to 50 | Sampling steps. Fewer are faster but lose some detail. |
guidance_scale | No | number | 3 | 0 to 10 | How strictly the object follows the image. |
num_gaussians | No | integer | 262144 | 32,768 to 1,048,576 | How many Gaussians the splat has, rounded down to a multiple of 32. More gives finer detail and a bigger file (see The output file). |
seed | No | integer | random | 0 to 2,147,483,647 | Fix it to get the same object again. |
enable_safety_checker | No | boolean | true | true | The input image is checked for unsafe content. It cannot be turned off. |
How usage is measured
Billed per 3D object: one per request, at the same rate whatever num_inference_steps or num_gaussians. The rate is in the pricing panel on this page. Nothing is charged for a request that fails.
Parameters not supported
Rejected with 400
Checked when you submit: the request is rejected before it is queued.
| Parameter | Why | Use instead |
|---|---|---|
steps | That is the Idol SDK's name for it. | num_inference_steps |
cfg_strength | That is the Idol SDK's name for it. | guidance_scale |
mode | That is the Idol SDK's name for it. | image_type |
image_urls, images, image | Idol builds one object from one image. | image_url |
prompt, negative_prompt | Idol works from the image alone; there is no text prompt. | — |
num_images, number_of_images, batch_size, n, count | One 3D object per request. | One request per image |
output_format | The splat is always a .ply file. | — |
model | This endpoint always runs Idol. | — |
input, parameters | Not accepted by this endpoint. | Send the parameters at the top level of the JSON body |
webhook_url, callback_url | Webhooks are set by header. | X-Webhook-URL header |
sync_mode set to true | Results are delivered through the status endpoint or a Webhook. | — |
enable_safety_checker set to false | The safety check cannot be turned off. | — |
image_url that cannot be downloaded | The image is fetched when you submit; if the URL answers an error (for example 404), the 400 says so under failures. | A public URL that serves the image |
Accepted, then the request fails
These pass the submit check, so the submit returns 202, but the request then fails with status: "ERROR". Nothing is charged.
| Parameter | When the request fails |
|---|---|
image_url | The file downloads but is not a readable image, for example a web page or a text file. |
image_url | The image is blocked by the content safety check. |
Accepted but ignored
Any other parameter is dropped and has no effect.
The output file
output.media_url is one .ply file (model/ply): a standard 3D Gaussian splatting (3DGS) PLY, binary_little_endian 1.0, with one vertex per Gaussian and 17 properties each: x, y, z, nx, ny, nz, f_dc_0, f_dc_1, f_dc_2, opacity, scale_0, scale_1, scale_2, rot_0, rot_1, rot_2, rot_3.
| num_gaussians | File size (measured at launch) |
|---|---|
| 262,144 (default) | 17.8 MB |
| 1,048,576 (maximum) | 71.3 MB |
Open it in any Gaussian splat viewer or editor, for example SuperSplat, or load it with the splat loaders for three.js and Babylon.js. A splat is not a mesh: it renders photoreal in splat viewers, but it has no polygons, so tools that need a mesh (3D printing, CAD, most game-engine imports) need a conversion step first. The object is centered, and the side the image did not show is generated.
Input tips
| Item | Guidance |
|---|---|
| Subject | One object, whole in frame. Several objects or a full scene give a poor result. |
| Background | Any; it is removed for you. A plain background gives the cleanest cut-out. |
| Kind of image | synthetic (default) for renders and generated images, real for photographs. |
| Detail | Raise num_gaussians for finer detail; lower it for a smaller file. |
Timing
A splat at the defaults took about 30 seconds from submit to result at launch, and one at the maximum num_gaussians about 45 seconds. Polling the status endpoint every 3 to 5 seconds is enough, or use a Webhook.
Example Request
{
"image_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/minimax_images/h3-image/2026/11/11/a5a743ec-24cc-424d-98df-ecd6ef235998.jpg"
}Example Response
{
"request_id": "idol_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"status": "QUEUED",
"polling_url": "https://gateway.pixazo.ai/v2/requests/status/idol_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}Example: a photo at the maximum detail
Request
{
"image_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/minimax_images/h3-image/2026/11/11/30eaadbd-7b48-4252-92d0-9b3513520e1f.jpg",
"image_type": "real",
"num_gaussians": 1048576,
"seed": 42
}Completed response
{
"request_id": "idol_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"status": "COMPLETED",
"model_id": "idol",
"error": null,
"output": {
"media_url": [
"https://pub-582b7213209642b9b995c96c95a30381.r2.dev/v1/idol_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/output.ply"
],
"media_type": "model/ply"
},
"created_at": "2026-11-11T12:56:11.162Z",
"updated_at": "2026-11-11 12:56:59",
"completed_at": "2026-11-11 12:56:58"
}Request Headers
| Header | Required | Description |
|---|---|---|
| Content-Type | Yes | application/json |
| Ocp-Apim-Subscription-Key | Yes | Your API subscription key. |
| X-Webhook-URL | No | Enable Webhook callbacks (see Webhook section). |
Response Handling
| Status Code | Meaning |
|---|---|
| 202 | Accepted — request queued; returns request_id and polling_url. |
| 400 | Bad request — the body failed the submit check (see Request Parameters) and was not queued. |
| 401 | Unauthorized — missing or invalid subscription key. |
| 402 | Insufficient balance. |
| 403 | Forbidden. |
| 429 | Too many requests. |
| 500 | Internal server error. |
Error Responses
A 400 names every rejected parameter in violations. This one was sent {"image_type": "photo", "steps": 10} with an image:
{
"error": "Invalid request parameters",
"message": "'image_type' must be one of: \"synthetic\", \"real\" (got \"photo\"); 'steps' is not a parameter here: use 'num_inference_steps' (1 to 50).",
"violations": [
"'image_type' must be one of: \"synthetic\", \"real\" (got \"photo\")",
"'steps' is not a parameter here: use 'num_inference_steps' (1 to 50)."
]
}An image_url that cannot be downloaded is also a 400, with the reason under failures:
{
"request_id": "idol_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"error": "Asset proxy failed",
"message": "Failed to proxy asset https://raw.githubusercontent.com/speridlabs/idol-sdk/main/no-such-image.png: 404 Not Found",
"failures": [
{
"url": "https://raw.githubusercontent.com/speridlabs/idol-sdk/main/no-such-image.png",
"error": "404 Not Found"
}
]
}Retrieving Results
Poll the status endpoint with the request_id until status is COMPLETED or ERROR, then download the splat from output.media_url.
curl 'https://gateway.pixazo.ai/v2/requests/status/idol_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' \
-H 'Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY'Completed response
Captured from a real Idol request at launch; the request id is masked.
{
"request_id": "idol_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"status": "COMPLETED",
"model_id": "idol",
"error": null,
"output": {
"media_url": [
"https://pub-582b7213209642b9b995c96c95a30381.r2.dev/v1/idol_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/output.ply"
],
"media_type": "model/ply"
},
"created_at": "2026-11-11T12:56:10.571Z",
"updated_at": "2026-11-11 12:56:38",
"completed_at": "2026-11-11 12:56:37"
}Response Fields
| Field | Type | Description |
|---|---|---|
| request_id | string | Unique request identifier. |
| status | string | QUEUED, PROCESSING, COMPLETED or ERROR. |
| model_id | string | The model that handled the request. |
| error | string or null | Error message when status is ERROR; otherwise null. |
| output.media_url | array of strings | URL of the .ply splat (one per request). Download it and keep your own copy. |
| output.media_type | string | model/ply. |
| created_at | string | Request creation timestamp. |
| updated_at | string | Last status change timestamp. |
| completed_at | string | Completion timestamp. |
| polling_url | string | Status URL for this request (in the submit response). |
Status Values & Flow
QUEUED → PROCESSING → COMPLETED (success) or ERROR (failure). Treat any status other than QUEUED, PROCESSING or COMPLETED as a failure.
Idol API Pricing
| Resolution | Price (USD) |
|---|---|
| Per 3D object (any settings) | $0.105 per generation |
⚡ Performance
Live usage measured on Pixazo's gateway, split by model version. Generation time is how long a generation takes end-to-end (lower is better). Success rate is the percent of generations that complete (higher is better).
〰 Uptime
Percent of generations that succeeded over the selected period, per model version.