# Integración de SDK

Usa los SDK oficiales de Tripo para enviar una tarea de texto a modelo, esperar a que termine, verificar el estado final y descargar el modelo generado. Las fuentes de instalación que figuran a continuación están fijadas a las versiones utilizadas para verificar esta página.

## SDK compatibles

| Lenguaje | API | Versión fijada | Fuente de instalación |
| --- | --- | --- | --- |
| JavaScript / TypeScript | V3 | [`e351348`](https://github.com/VAST-AI-Research/tripo-js-sdk/tree/e35134801b339caac0b84f36fe02d08e73e217b2) | Commit oficial de Git |
| Python | V2 + limited V3 | [`v0.4.2`](https://github.com/VAST-AI-Research/tripo-python-sdk/tree/v0.4.2) | PyPI `tripo3d==0.4.2` |
| Go | V3 | [`2c8c8d4`](https://github.com/VAST-AI-Research/tripo-go-sdk/tree/2c8c8d4e6a9e1fc9e49699fc055140eca689ee79) | Pseudoversión de Go `v0.0.0-20260713072120-2c8c8d4e6a9e` |
| Rust | V3 | [`f992f6a`](https://github.com/VAST-AI-Research/tripo-rust-sdk/tree/f992f6a7cf7a28c10781f9fa28e4630c7802291c) | Dependencia Git de Cargo |
| Java | V3 | [`7b6a68d`](https://github.com/VAST-AI-Research/tripo-java-sdk/tree/7b6a68d855e01a0b098775b1ee14ce7f3c8ac7d9) | Compilación desde el código fuente; Maven local `0.1.0-SNAPSHOT` |

## 1. Configurar una clave de API y la región

Crea una clave en la [consola de Tripo](https://platform.tripo3d.ai/) y exponla únicamente al proceso del servidor. No incluyas una clave de API en el código del navegador ni la añadas al control de versiones.

```bash
export TRIPO_API_KEY="tsk_..."
```

JavaScript, Go y Rust usan `https://openapi.tripo3d.ai/v3` globalmente y `https://openapi.tripo3d.com/v3` en China. Java selecciona `TripoRegion.GLOBAL` o `TripoRegion.CN`; el SDK parte del origen `.ai` o `.com` correspondiente y añade `/v3`. El cliente V2 principal de Python 0.4.2 usa `https://api.tripo3d.ai/v2/openapi` globalmente y `https://api.tripo3d.com/v2/openapi` en China; su flujo limitado de segmentación V3 también usa el origen correspondiente `https://openapi.tripo3d.ai` o `.com`.

## 2. Instalar el SDK

Instala cada SDK desde su fuente de producción fijada.

### JavaScript

```bash
npm install github:VAST-AI-Research/tripo-js-sdk#e35134801b339caac0b84f36fe02d08e73e217b2
```

### Python

```bash
python -m pip install tripo3d==0.4.2
```

### Go

```bash
go get github.com/VAST-AI-Research/tripo-go-sdk@v0.0.0-20260713072120-2c8c8d4e6a9e
```

### Rust

```toml
[dependencies]
tripo3d-sdk = { git = "https://github.com/VAST-AI-Research/tripo-rust-sdk.git", rev = "f992f6a7cf7a28c10781f9fa28e4630c7802291c" }
tokio = { version = "1", features = ["full"] }
anyhow = "1"
```

### Java

```bash
git clone https://github.com/VAST-AI-Research/tripo-java-sdk.git
cd tripo-java-sdk
git checkout 7b6a68d855e01a0b098775b1ee14ce7f3c8ac7d9
./mvnw install
```

La compilación de Java instala `ai.tripo3d:tripo-sdk:0.1.0-SNAPSHOT` en el repositorio Maven local. Añade esas coordenadas a tu aplicación cuando termine la compilación desde el código fuente.

## 3. Enviar, esperar y descargar

Cada ejemplo del servidor lee `TRIPO_API_KEY`, envía una tarea de texto a modelo, espera un resultado final, comprueba que se haya completado correctamente y guarda de inmediato el modelo principal. Las URL de los modelos generados son temporales.

### JavaScript

```javascript
import { writeFile } from 'node:fs/promises';
import { TripoClient, ModelVersion, TaskStatus } from 'tripo3d-sdk-js';

const apiKey = process.env.TRIPO_API_KEY;
if (!apiKey) throw new Error('TRIPO_API_KEY is required');

const client = new TripoClient({
  apiKey,
  baseUrl: 'https://openapi.tripo3d.ai/v3',
});

const taskId = await client.textToModel({
  prompt: 'a cute red panda holding bamboo',
  model: ModelVersion.H3_1,
  texture: true,
  pbr: true,
  texture_quality: 'detailed',
});

const task = await client.waitForTask(taskId, {
  pollingIntervalMs: 2000,
  onProgress: (value) => console.log(`${value.status} — ${value.progress ?? 0}%`),
});

if (task.status !== TaskStatus.SUCCESS) {
  throw new Error(`Task did not succeed: ${task.status}`);
}

const modelUrl = task.output.model_url ?? task.output.model;
if (!modelUrl) throw new Error('Task returned no model URL');

const response = await fetch(modelUrl);
if (!response.ok) throw new Error(`Download failed: HTTP ${response.status}`);

await writeFile(`tripo-${taskId}.glb`, Buffer.from(await response.arrayBuffer()));
```

### Python

```python
import asyncio
import os
import shutil
from urllib.request import urlopen

from tripo3d import TripoClient
from tripo3d.models import TaskStatus


def download_file(url, path):
    with urlopen(url) as response, open(path, "wb") as output:
        shutil.copyfileobj(response, output)


async def main():
    api_key = os.environ["TRIPO_API_KEY"]
    os.makedirs("./output", exist_ok=True)

    async with TripoClient(api_key=api_key) as client:
        task_id = await client.text_to_model(
            prompt="a cute red panda holding bamboo",
            model_version="v2.5-20250123",
        )
        task = await client.wait_for_task(task_id, verbose=True)

        if task.status != TaskStatus.SUCCESS:
            raise RuntimeError(f"Task did not succeed: {task.status}")

        model_url = task.output.model
        if not model_url:
            raise RuntimeError("Task returned no model URL")

        output_path = "./output/model.glb"
        await asyncio.to_thread(download_file, model_url, output_path)
        print(f"Downloaded model: {output_path}")


asyncio.run(main())
```

### Go

```go
package main

import (
	"context"
	"fmt"
	"log"
	"os"
	"time"

	tripo3d "github.com/VAST-AI-Research/tripo-go-sdk"
)

func main() {
	apiKey := os.Getenv("TRIPO_API_KEY")
	if apiKey == "" {
		log.Fatal("TRIPO_API_KEY is required")
	}

	client, err := tripo3d.NewClient(tripo3d.ClientOptions{
		APIKey:  apiKey,
		BaseURL: "https://openapi.tripo3d.ai/v3",
	})
	if err != nil {
		log.Fatal(err)
	}

	ctx := context.Background()
	taskID, err := client.TextToModel(ctx, tripo3d.TextToModelParams{
		Prompt:         "a cute red panda holding bamboo",
		Model:          tripo3d.String(tripo3d.ModelVersionH31),
		Texture:        tripo3d.Bool(true),
		PBR:            tripo3d.Bool(true),
		TextureQuality: tripo3d.String("detailed"),
	})
	if err != nil {
		log.Fatal(err)
	}

	task, err := client.WaitForTask(ctx, taskID, tripo3d.WaitOptions{
		PollInterval: 2 * time.Second,
	})
	if err != nil {
		log.Fatal(err)
	}
	if task.Status != tripo3d.TaskStatusSuccess {
		log.Fatalf("Task did not succeed: %s", task.Status)
	}

	downloaded, err := client.DownloadModel(ctx, task)
	if err != nil {
		log.Fatal(err)
	}
	if downloaded == nil {
		log.Fatal("Task returned no model URL")
	}

	filename := fmt.Sprintf("tripo-%s.glb", taskID)
	if err := os.WriteFile(filename, downloaded.Data, 0o644); err != nil {
		log.Fatal(err)
	}
}
```

### Rust

```rust
use tokio::fs;
use tripo3d_sdk::{
    constants::model_version,
    params::TextToModelParams,
    ClientOptions,
    TaskStatus,
    TripoClient,
    WaitOptions,
};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let api_key = std::env::var("TRIPO_API_KEY")?;
    let client = TripoClient::new(ClientOptions {
        api_key: Some(api_key),
        base_url: Some("https://openapi.tripo3d.ai/v3".into()),
        ..Default::default()
    })?;

    let task_id = client
        .text_to_model(TextToModelParams {
            prompt: "a cute red panda holding bamboo".into(),
            model: Some(model_version::H3_1.to_string()),
            texture: Some(true),
            pbr: Some(true),
            texture_quality: Some("detailed".into()),
            ..Default::default()
        })
        .await?;

    let task = client
        .wait_for_task(&task_id, WaitOptions::default())
        .await?;
    if task.status != TaskStatus::Success {
        anyhow::bail!("Task did not succeed: {}", task.status);
    }

    let downloaded = client
        .download_model(&task)
        .await?
        .ok_or_else(|| anyhow::anyhow!("Task returned no model URL"))?;

    fs::write(format!("tripo-{task_id}.glb"), downloaded.data).await?;
    Ok(())
}
```

### Java

```java
import ai.tripo3d.sdk.api.TripoClient;
import ai.tripo3d.sdk.api.TripoClientConfig;
import ai.tripo3d.sdk.api.TripoRegion;
import ai.tripo3d.sdk.model.request.TaskRequestPayload;
import ai.tripo3d.sdk.model.response.TaskDetail;

import java.io.InputStream;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.Map;

public final class TripoQuickStart {
    public static void main(String[] args) throws Exception {
        String apiKey = System.getenv("TRIPO_API_KEY");
        if (apiKey == null || apiKey.trim().isEmpty()) {
            throw new IllegalStateException("TRIPO_API_KEY is required");
        }

        try (TripoClient client = TripoClient.create(
                TripoClientConfig.builder(apiKey)
                        .region(TripoRegion.GLOBAL)
                        .build())) {
            TaskDetail created = client.textToModel(TaskRequestPayload.builder()
                    .prompt("a wooden chair")
                    .model("v3.1-20260211")
                    .build());

            TaskDetail done = client.pollUntilTerminal(created.taskId());
            if (!"success".equalsIgnoreCase(done.status())) {
                throw new IllegalStateException(
                        "Task failed: status=" + done.status()
                                + ", message=" + done.errorMsg());
            }

            Map<String, Object> output = done.output();
            Object modelUrl = output == null ? null : output.get("model_url");
            if (!(modelUrl instanceof String)) {
                throw new IllegalStateException(
                        "Task output does not contain model_url");
            }

            try (InputStream input =
                         new URL((String) modelUrl).openStream()) {
                Files.copy(
                        input,
                        Paths.get("model.glb"),
                        StandardCopyOption.REPLACE_EXISTING);
            }
        }
    }
}
```

JavaScript, Python y Java usan deliberadamente clientes HTTP nativos para la URL firmada del modelo y no adjuntan un encabezado `Authorization`. Los métodos de descarga de los SDK de Go y Rust también obtienen la URL firmada sin la clave de API.

## 4. Compatibilidad con las rutas V3

La matriz reúne las cinco implementaciones de SDK en las versiones fijadas anteriormente. Una marca de verificación indica que un flujo público del SDK alcanza la ruta HTTP V3 final, directamente o mediante un paso interno; las constantes de ruta sin usar no cuentan.

| Ruta HTTP | Finalidad | JavaScript | Python | Go | Rust | Java |
| --- | --- | :---: | :---: | :---: | :---: | :---: |
| `POST /v3/generation/text-to-model` | Generar un modelo a partir de texto | ✓ | — | ✓ | ✓ | ✓ |
| `POST /v3/generation/image-to-model` | Generar un modelo a partir de una imagen | ✓ | — | ✓ | ✓ | ✓ |
| `POST /v3/generation/multiview-to-model` | Generar un modelo a partir de varias vistas | ✓ | — | ✓ | ✓ | ✓ |
| `POST /v3/generation/text-to-image` | Generar una imagen a partir de texto | ✓ | — | ✓ | ✓ | — |
| `POST /v3/generation/image-to-image` | Transformar una imagen | ✓ | — | ✓ | ✓ | — |
| `POST /v3/generation/image-to-multiview` | Generar imágenes multivista | ✓ | — | ✓ | ✓ | ✓ |
| `POST /v3/generation/edit-multiview` | Editar la salida multivista | ✓ | — | ✓ | ✓ | — |
| `POST /v3/generation/image-to-splat` | Generar un splat gaussiano | — | — | — | — | ✓ |
| `POST /v3/models/refine` | Refinar un modelo preliminar | — | — | — | — | ✓ |
| `POST /v3/models/texture` | Aplicar o regenerar texturas | ✓ | — | ✓ | ✓ | ✓ |
| `POST /v3/models/stylize` | Estilizar un modelo | — | — | — | — | ✓ |
| `POST /v3/models/convert` | Convertir el formato del modelo | ✓ | — | ✓ | ✓ | ✓ |
| `POST /v3/models/import` | Importar un modelo externo | — | — | — | — | ✓ |
| `POST /v3/mesh/segment` | Segmentar una malla | ✓ | ✓ | ✓ | ✓ | ✓ |
| `POST /v3/mesh/complete` | Completar o reparar una malla | ✓ | — | ✓ | ✓ | ✓ |
| `POST /v3/mesh/decimate` | Reducir el número de caras | ✓ | — | ✓ | ✓ | ✓ |
| `POST /v3/animations/rig-check` | Comprobar si se puede aplicar rigging a un modelo | ✓ | — | ✓ | ✓ | ✓ |
| `POST /v3/animations/rig` | Añadir un esqueleto | ✓ | — | ✓ | ✓ | ✓ |
| `POST /v3/animations/retarget` | Aplicar una animación predefinida | ✓ | — | ✓ | ✓ | ✓ |
| `GET /v3/tasks/{task_id}` | Obtener una tarea | ✓ | ✓ | ✓ | ✓ | ✓ |
| `POST /v3/tasks/list` | Obtener varias tareas | ✓ | — | ✓ | ✓ | ✓ |
| `POST /v3/files` | Subir un archivo | ✓ | ✓ | ✓ | ✓ | ✓ |
| `POST /v3/files/presign` | Crear una carga prefirmada | — | — | — | — | ✓ |
| `GET /v3/account/balance` | Obtener el saldo de la cuenta | ✓ | — | ✓ | ✓ | ✓ |
| `GET /v3/account/usage` | Obtener el historial de uso | — | — | — | — | ✓ |

En esta versión fijada, solo Java expone image-to-splat, refine, stylize, import, presign y usage. Java no expone text-to-image, image-to-image ni edit-multiview. Su descriptor interno para `/v3/files/upload-credentials` no tiene servicio ni método público del cliente, por lo que no se cuenta como compatible.

Python sigue siendo principalmente un SDK V2. Su rama `mesh_segmentation(..., model_version="v2.0-20260430")` también usa `POST /v3/mesh/segment`, `GET /v3/tasks/{task_id}` y `POST /v3/files` cuando debe cargar un `ref_image` local.

### Compatibilidad con las rutas V2 de Python

Python 0.4.2 expone cinco rutas HTTP V2 finales. `POST /v2/openapi/task` es compartida por sus métodos de generación, procesamiento de modelos, mallas y animación; no se limita a texto a modelo.

| Ruta HTTP | Finalidad |
| --- | --- |
| `POST /v2/openapi/task` | Enviar cualquier tarea V2 compatible |
| `GET /v2/openapi/task/{task_id}` | Consultar el estado y la salida de la tarea |
| `GET /v2/openapi/user/balance` | Obtener el saldo de la cuenta |
| `POST /v2/openapi/upload/sts/token` | Obtener credenciales de carga STS cuando `boto3` está disponible |
| `POST /v2/openapi/upload` | Cargar un archivo mediante el modo multipart heredado del SDK |

Java y los demás SDK V3 envían la selección del modelo mediante sus modelos de parámetros V3 oficiales. En el formato de Java, el campo se llama `model`.

## 5. Solución de problemas

- **Falta la clave:** configura `TRIPO_API_KEY` en el proceso del servidor. Consulta [Autenticación](./authentication).
- **Región incorrecta:** selecciona el endpoint global o de China correspondiente al SDK y a la versión de la API que utilices.
- **Tarea fallida o con tiempo de espera agotado:** conserva el `task_id`, revisa el estado final y consulta [Ciclo de vida de las tareas](./task-lifecycle) y [Gestión de errores](./error-handling).
- **URL del modelo caducada:** vuelve a consultar la tarea cuando el SDK lo admita y descarga el modelo inmediatamente. No guardes una URL firmada temporal como recurso permanente.

## Repositorios oficiales

- [SDK de JavaScript](https://github.com/VAST-AI-Research/tripo-js-sdk)
- [SDK de Python](https://github.com/VAST-AI-Research/tripo-python-sdk)
- [SDK de Go](https://github.com/VAST-AI-Research/tripo-go-sdk)
- [SDK de Rust](https://github.com/VAST-AI-Research/tripo-rust-sdk)
- [SDK de Java](https://github.com/VAST-AI-Research/tripo-java-sdk)
