---
type: AI Model
id: idol
title: Idol API
provider: Sperid Labs
description: "Idol by Sperid Labs — turn one image of an object into a 3D Gaussian splat (.ply), including the sides the image never showed."
resource: https://www.pixazo.ai/models/idol
docs_url: https://www.pixazo.ai/models/idol
latest_version: v1
tags:
  - 3d-models
  - sperid-labs
variants:
  - id: idol-v1
    name: Idol
    version: 1.0
    capabilities:
      - Image to 3D (Gaussian Splat)
timestamp: 2026-11-11T13:16:00.655Z
---

# Idol API

> Provider: **Sperid Labs**
> Source: https://www.pixazo.ai/models/idol

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

## Idol

### Image to 3D (Gaussian Splat)

## Idol Image to 3D 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-3d
```

## Authentication

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

HTTP Python JavaScript cURL

```
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"
}
```

[Try Now](https://api.pixazo.ai/api-details#api=idol&operation=image-to-3d)

## 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.
