> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aihubmix.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 3D Generation API

> AiHubMix provides a unified 3D model generation API supporting text-to-3D and image-to-3D in an asynchronous task mode, starting with Tencent Hunyuan 3D (hy-3d-3.1), with outputs in obj / glb / stl / usdz / fbx formats and PBR materials

## Quick Start

3D generation is an asynchronous operation. The whole process is divided into three steps:

```text theme={null}
1. Submit task → get generation_id
2. Poll status → wait until status becomes completed
3. Download outputs → download the 3D files directly via the content_url in output
```

**Minimal Example**

```shellscript theme={null}
# Step 1: Submit the 3D generation task (text-to-3D)
curl -X POST https://aihubmix.com/v1/3d/generations \
  -H "Authorization: Bearer $AIHUBMIX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "hy-3d-3.1",
    "prompt": "A Shiba Inu wearing a hat"
  }'

# Example response:
# {
#   "id": "eyJtb2RlbCI6Imh5LTNkLTMuMSIsIml...",
#   "object": "3d.generation",
#   "model": "hy-3d-3.1",
#   "status": "queued",
#   "output": null,
#   "error": null,
#   "created_at": 1752728000,
#   "completed_at": null,
#   "expires_at": 1752814400
# }

# Step 2: Poll the status (query every 10-15 seconds until status is completed)
curl https://aihubmix.com/v1/3d/generations/{generation_id} \
  -H "Authorization: Bearer $AIHUBMIX_API_KEY"

# Step 3: Download the outputs (content_url is a temporary URL; download directly, no authentication required)
curl "{content_url}" --output model.glb
```

## API Overview

| Endpoint       | Method | Path                                 | Description                   |
| :------------- | :----- | :----------------------------------- | :---------------------------- |
| Create 3D Task | POST   | `/v1/3d/generations`                 | Submit a 3D generation task   |
| Query Status   | GET    | `/v1/3d/generations/{generation_id}` | Query task status and outputs |

Base URL: `https://aihubmix.com`

Authentication: Bearer Token

```shellscript theme={null}
Authorization: Bearer $AIHUBMIX_API_KEY
```

<Note>
  Unlike the video API, the 3D API has **no** `/content` download endpoint and no `DELETE` endpoint: outputs are downloaded directly via the `content_url` in the `output[]` array of the query response.
</Note>

## Supported Models

| Vendor  | Model Name  | Features                                                                                        |
| ------- | ----------- | ----------------------------------------------------------------------------------------------- |
| Tencent | `hy-3d-3.1` | Hunyuan 3D 3.1, supports text-to-3D, image-to-3D, and sketch-to-3D, with optional PBR materials |

**Generation Types (`generate_type`)**

| Type       | Description                                                             |
| :--------- | :---------------------------------------------------------------------- |
| `Normal`   | Standard generation (default), geometry + texture                       |
| `Geometry` | Untextured geometry mesh only, no texture                               |
| `Sketch`   | Sketch-to-3D; allows passing both a sketch image and a text description |

## API Details

### Request Headers

```shellscript theme={null}
Authorization: Bearer $AIHUBMIX_API_KEY
Content-Type: application/json
```

### Create a 3D Generation Task

```shellscript theme={null}
POST /v1/3d/generations
```

#### **Request Body**

| Parameter          | Type   | Required    | Description                                                                                                                                                                                                                                                                            |
| :----------------- | :----- | :---------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `model`            | string | Yes         | Model name: `hy-3d-3.1`                                                                                                                                                                                                                                                                |
| `prompt`           | string | Conditional | Text description, up to 1024 characters; at least one of `prompt` and `input_references` must be provided                                                                                                                                                                              |
| `input_references` | array  | Conditional | Reference image array (image-to-3D), currently limited to 1 image; within each item, provide exactly one of `image_url` or `image_base64`                                                                                                                                              |
| `generate_type`    | string | No          | Generation type: `Normal` (default) / `Geometry` / `Sketch`, case-insensitive                                                                                                                                                                                                          |
| `enable_pbr`       | bool   | No          | Whether to generate PBR materials, default `false`                                                                                                                                                                                                                                     |
| `face_count`       | int    | No          | Target face count, range `3000` \~ `1500000`; if omitted, the model default applies                                                                                                                                                                                                    |
| `format`           | string | No          | Output format: `stl` / `usdz` / `fbx`, case-insensitive; if omitted, the upstream default applies (Normal typically returns obj + glb, Geometry returns glb only); a specified format is generated **in addition** (e.g. `format: "stl"` returns glb + stl rather than replacing them) |
| `extra_body`       | object | No          | Pass-through for other upstream native parameters (see the note below)                                                                                                                                                                                                                 |

**Parameter Validation Rules**

* `prompt` and `input_references` are **mutually exclusive** (only one may be provided); the only exception is `generate_type: "Sketch"`, which allows both together (sketch + text description).
* Within each `input_references` item, exactly one of `image_url` and `image_base64` must be provided:
  * `image_url` only supports public `http(s)` URLs; **data URLs are not supported** (use `image_base64` instead);
  * `image_base64` must not exceed **6MB** after decoding.
* `hy-3d-3.1` does not support the `LowPoly` generation type.
* The total request body size must not exceed **10MB**.

<Note>
  **Using `extra_body`**: Upstream native parameters (such as `polygon_type`) can be placed at the top level of `extra_body` for pass-through. The following parameters **must be passed as top-level fields** — including them in `extra_body` returns 400: `model`, `prompt`, `image_url`, `image_base64`, `generate_type`, `enable_pbr`, `face_count`, `result_format`; `multi_view_images` (multi-view images) is not supported yet.
</Note>

#### Example Response

```json theme={null}
{
  "id": "eyJtb2RlbCI6Imh5LTNkLTMuMSIsIml...",
  "object": "3d.generation",
  "model": "hy-3d-3.1",
  "status": "queued",
  "output": null,
  "error": null,
  "created_at": 1752728000,
  "completed_at": null,
  "expires_at": 1752814400
}
```

#### Status Values

| Status        | Description                                                             |
| :------------ | :---------------------------------------------------------------------- |
| `queued`      | Queued                                                                  |
| `in_progress` | Generating                                                              |
| `completed`   | Generation complete; `output` contains the download URLs of the outputs |
| `failed`      | Generation failed; `error` contains the error information               |

### Query Task Status

```shellscript theme={null}
GET /v1/3d/generations/{generation_id}
```

Poll this endpoint to check whether the task is complete. We recommend querying every **10-15 seconds**. Queries are not billed.

#### **Example Response (Generation Complete)**

```json theme={null}
{
  "id": "eyJtb2RlbCI6Imh5LTNkLTMuMSIsIml...",
  "object": "3d.generation",
  "model": "hy-3d-3.1",
  "status": "completed",
  "output": [
    {
      "type": "obj",
      "b64_json": null,
      "content_url": "https://example-cos.tencentcos.cn/.../model.obj?sign=...",
      "preview_url": "https://example-cos.tencentcos.cn/.../preview.png?sign=..."
    },
    {
      "type": "glb",
      "b64_json": null,
      "content_url": "https://example-cos.tencentcos.cn/.../model.glb?sign=..."
    }
  ],
  "error": null,
  "created_at": 1752728000,
  "completed_at": 1752728180,
  "expires_at": 1752814400
}
```

**`output[]` Field Description**

| Field         | Description                                                                                        |
| :------------ | :------------------------------------------------------------------------------------------------- |
| `type`        | Output file type (lowercase), e.g. `obj`, `glb`, `stl`                                             |
| `b64_json`    | Always `null` (3D outputs are never returned inline; they are always downloaded via `content_url`) |
| `content_url` | Output download URL (temporary upstream link); **download and save it promptly**                   |
| `preview_url` | Preview thumbnail URL (when provided by the upstream)                                              |

<Warning>
  `content_url` and `preview_url` are **temporary links** that expire after a period of time. Download the files and transfer them to your own storage as soon as the task completes. The task ID remains queryable for **24 hours** after creation (the `expires_at` field indicates the query deadline); querying after expiration returns an error. The temporary links only support GET requests; HEAD requests return 403.
</Warning>

## Usage Examples

<CodeGroup>
  ```shellscript Text-to-3D theme={null}
  curl -X POST https://aihubmix.com/v1/3d/generations \
    -H "Authorization: Bearer $AIHUBMIX_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "hy-3d-3.1",
      "prompt": "A retro steampunk-style motorcycle, brass texture, rich in detail",
      "enable_pbr": true
    }'
  ```

  ```shellscript Image-to-3D (URL) theme={null}
  curl -X POST https://aihubmix.com/v1/3d/generations \
    -H "Authorization: Bearer $AIHUBMIX_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "hy-3d-3.1",
      "input_references": [
        { "image_url": "https://example.com/cat.png" }
      ]
    }'
  ```

  ```shellscript Image-to-3D (Base64) theme={null}
  curl -X POST https://aihubmix.com/v1/3d/generations \
    -H "Authorization: Bearer $AIHUBMIX_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "hy-3d-3.1",
      "input_references": [
        { "image_base64": "<BASE64_ENCODED_IMAGE>" }
      ]
    }'
  ```

  ```shellscript Sketch-to-3D (Sketch) theme={null}
  curl -X POST https://aihubmix.com/v1/3d/generations \
    -H "Authorization: Bearer $AIHUBMIX_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "hy-3d-3.1",
      "generate_type": "Sketch",
      "prompt": "A sci-fi style aircraft with a metallic shell",
      "input_references": [
        { "image_url": "https://example.com/sketch.png" }
      ]
    }'
  ```

  ```shellscript Specify Face Count and Format theme={null}
  curl -X POST https://aihubmix.com/v1/3d/generations \
    -H "Authorization: Bearer $AIHUBMIX_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "hy-3d-3.1",
      "prompt": "A medieval knight helmet",
      "generate_type": "Normal",
      "enable_pbr": true,
      "face_count": 40000,
      "format": "fbx"
    }'
  ```
</CodeGroup>

## Complete Invocation Examples

<CodeGroup>
  ```python Python theme={null}
  import requests
  import time

  API_KEY = "AIHUBMIX_API_KEY"
  BASE_URL = "https://aihubmix.com"
  HEADERS = {
      "Authorization": f"Bearer {API_KEY}",
      "Content-Type": "application/json"
  }

  # Step 1: Create the 3D generation task
  response = requests.post(
      f"{BASE_URL}/v1/3d/generations",
      headers=HEADERS,
      json={
          "model": "hy-3d-3.1",
          "prompt": "A Shiba Inu wearing a hat",
          "enable_pbr": True
      }
  )
  result = response.json()
  generation_id = result["id"]
  print(f"Task created, generation_id: {generation_id}")

  # Step 2: Poll the status
  while True:
      status_response = requests.get(
          f"{BASE_URL}/v1/3d/generations/{generation_id}",
          headers=HEADERS
      )
      status_data = status_response.json()
      current_status = status_data["status"]
      print(f"Current status: {current_status}")

      if current_status == "completed":
          print("3D generation complete!")
          break
      elif current_status == "failed":
          error = status_data.get("error") or {}
          print(f"Generation failed: {error.get('message', 'Unknown error')}")
          exit(1)

      time.sleep(15)  # Query every 15 seconds

  # Step 3: Download the outputs (content_url is a temporary URL; download directly)
  for item in status_data["output"]:
      file_url = item["content_url"]
      file_name = f"model.{item['type']}"
      file_response = requests.get(file_url)
      with open(file_name, "wb") as f:
          f.write(file_response.content)
      print(f"Saved {file_name} ({len(file_response.content) / 1024 / 1024:.1f} MB)")
  ```

  ```javascript Node.js theme={null}
  const API_KEY = "your_aihubmix_api_key";
  const BASE_URL = "https://aihubmix.com";

  async function generate3D() {
    // Step 1: Create the task
    const createResponse = await fetch(`${BASE_URL}/v1/3d/generations`, {
      method: "POST",
      headers: {
        "Authorization": `Bearer ${API_KEY}`,
        "Content-Type": "application/json"
      },
      body: JSON.stringify({
        model: "hy-3d-3.1",
        prompt: "A Shiba Inu wearing a hat",
        enable_pbr: true
      })
    });
    const { id: generationId } = await createResponse.json();
    console.log(`Task created: ${generationId}`);

    // Step 2: Poll the status
    let result;
    while (true) {
      await new Promise(resolve => setTimeout(resolve, 15000));
      const statusResponse = await fetch(
        `${BASE_URL}/v1/3d/generations/${generationId}`,
        { headers: { "Authorization": `Bearer ${API_KEY}` } }
      );
      result = await statusResponse.json();
      console.log(`Current status: ${result.status}`);
      if (result.status === "completed" || result.status === "failed") break;
    }

    if (result.status === "failed") {
      console.error(`Generation failed: ${result.error?.message}`);
      return;
    }

    // Step 3: Download the outputs
    const fs = require("fs");
    for (const item of result.output) {
      const fileResponse = await fetch(item.content_url);
      const buffer = Buffer.from(await fileResponse.arrayBuffer());
      fs.writeFileSync(`model.${item.type}`, buffer);
      console.log(`Saved model.${item.type}`);
    }
  }

  generate3D();
  ```
</CodeGroup>

## Billing

* Billed **per generation**: the price is determined by the combination of `model × generate_type × PBR enabled × face count specified × format specified`. See the [Model Gallery](https://aihubmix.com/models) for specific prices.
* Billing occurs when the **task is created successfully**; querying task status and downloading outputs are not billed.
* Parameter combinations without a configured price return 400 directly at creation time and incur no charge.

## FAQ

### How long does 3D generation take?

It usually takes several minutes, depending on the model, generation type, and face count settings. We recommend polling the query endpoint at a 10-15 second interval.

### How long are the output links and the task valid?

* The task ID remains queryable for **24 hours** after creation; the `expires_at` field in the response indicates the query deadline.
* `content_url` / `preview_url` are temporary upstream links that expire after a period of time; **download and save them promptly** after the task completes.

### Can I pass both `prompt` and a reference image?

No — the two are mutually exclusive. The only exception is `generate_type: "Sketch"` (sketch-to-3D), which allows passing both a sketch image and a text description.

### What are the differences between the `generate_type` options?

| Type       | Description                                         |
| :--------- | :-------------------------------------------------- |
| `Normal`   | Standard generation (geometry + texture), default   |
| `Geometry` | Untextured geometry mesh only, no texture           |
| `Sketch`   | Sketch-to-3D; image and text can be passed together |

### How do I handle a failed task?

When `status` is `failed`, the `error` field in the response contains error information:

```json theme={null}
{
  "status": "failed",
  "error": {
    "message": "...",
    "type": "z3d_generation_error"
  }
}
```

Common failure reasons include: content policy violations, unsupported image formats, inaccessible reference images, etc. Adjust based on the error message and retry.

***

Last updated: 2026-07-17
