# Intégration des SDK

Utilisez les SDK Tripo officiels pour soumettre une tâche de génération de modèle à partir de texte, attendre son achèvement, vérifier son état final et télécharger le modèle généré. Les sources d’installation ci-dessous sont verrouillées sur les versions utilisées pour vérifier cette page.

## SDK pris en charge

| Langage | API | Version verrouillée | Source d’installation |
| --- | --- | --- | --- |
| JavaScript / TypeScript | V3 | [`e351348`](https://github.com/VAST-AI-Research/tripo-js-sdk/tree/e35134801b339caac0b84f36fe02d08e73e217b2) | Commit Git officiel |
| 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) | Pseudo-version Go `v0.0.0-20260713072120-2c8c8d4e6a9e` |
| Rust | V3 | [`f992f6a`](https://github.com/VAST-AI-Research/tripo-rust-sdk/tree/f992f6a7cf7a28c10781f9fa28e4630c7802291c) | Dépendance Git Cargo |
| Java | V3 | [`7b6a68d`](https://github.com/VAST-AI-Research/tripo-java-sdk/tree/7b6a68d855e01a0b098775b1ee14ce7f3c8ac7d9) | Compilation depuis les sources ; Maven local `0.1.0-SNAPSHOT` |

## 1. Configurer une clé API et une région

Créez une clé dans la [console Tripo](https://platform.tripo3d.ai/) et exposez-la uniquement à votre processus côté serveur. Ne placez pas de clé API dans le code du navigateur et ne la validez pas dans le contrôle de version.

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

JavaScript, Go et Rust utilisent `https://openapi.tripo3d.ai/v3` dans le monde et `https://openapi.tripo3d.com/v3` en Chine. Java sélectionne `TripoRegion.GLOBAL` ou `TripoRegion.CN` ; le SDK part de l’origine `.ai` ou `.com` correspondante et ajoute `/v3`. Le client V2 principal de Python 0.4.2 utilise `https://api.tripo3d.ai/v2/openapi` dans le monde et `https://api.tripo3d.com/v2/openapi` en Chine ; son flux limité de segmentation V3 utilise aussi l’origine correspondante `https://openapi.tripo3d.ai` ou `.com`.

## 2. Installer le SDK

Installez chaque SDK depuis sa source de production verrouillée.

### 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 compilation Java installe `ai.tripo3d:tripo-sdk:0.1.0-SNAPSHOT` dans le dépôt Maven local. Ajoutez cette coordonnée à votre application une fois la compilation depuis les sources terminée.

## 3. Soumettre, attendre et télécharger

Chaque exemple côté serveur lit `TRIPO_API_KEY`, soumet une tâche de génération de modèle à partir de texte, attend un résultat final, vérifie la réussite et enregistre immédiatement le modèle principal. Les URL des modèles générés sont temporaires.

### 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 et Java utilisent délibérément des clients HTTP natifs pour l’URL signée du modèle et n’ajoutent pas d’en-tête `Authorization`. Les méthodes de téléchargement des SDK Go et Rust récupèrent également l’URL signée sans la clé API.

## 4. Prise en charge des routes V3

La matrice réunit les cinq implémentations de SDK aux versions verrouillées ci-dessus. Une coche signifie qu’un flux public du SDK atteint la route HTTP V3 finale, directement ou via une étape interne ; les constantes de route inutilisées ne comptent pas.

| Route HTTP | Objectif | JavaScript | Python | Go | Rust | Java |
| --- | --- | :---: | :---: | :---: | :---: | :---: |
| `POST /v3/generation/text-to-model` | Générer un modèle à partir de texte | ✓ | — | ✓ | ✓ | ✓ |
| `POST /v3/generation/image-to-model` | Générer un modèle à partir d’une image | ✓ | — | ✓ | ✓ | ✓ |
| `POST /v3/generation/multiview-to-model` | Générer un modèle à partir de plusieurs vues | ✓ | — | ✓ | ✓ | ✓ |
| `POST /v3/generation/text-to-image` | Générer une image à partir de texte | ✓ | — | ✓ | ✓ | — |
| `POST /v3/generation/image-to-image` | Transformer une image | ✓ | — | ✓ | ✓ | — |
| `POST /v3/generation/image-to-multiview` | Générer des images multivues | ✓ | — | ✓ | ✓ | ✓ |
| `POST /v3/generation/edit-multiview` | Modifier une sortie multivue | ✓ | — | ✓ | ✓ | — |
| `POST /v3/generation/image-to-splat` | Générer un splat gaussien | — | — | — | — | ✓ |
| `POST /v3/models/refine` | Affiner un modèle préliminaire | — | — | — | — | ✓ |
| `POST /v3/models/texture` | Appliquer ou régénérer des textures | ✓ | — | ✓ | ✓ | ✓ |
| `POST /v3/models/stylize` | Styliser un modèle | — | — | — | — | ✓ |
| `POST /v3/models/convert` | Convertir le format d’un modèle | ✓ | — | ✓ | ✓ | ✓ |
| `POST /v3/models/import` | Importer un modèle externe | — | — | — | — | ✓ |
| `POST /v3/mesh/segment` | Segmenter un maillage | ✓ | ✓ | ✓ | ✓ | ✓ |
| `POST /v3/mesh/complete` | Compléter ou réparer un maillage | ✓ | — | ✓ | ✓ | ✓ |
| `POST /v3/mesh/decimate` | Réduire le nombre de faces | ✓ | — | ✓ | ✓ | ✓ |
| `POST /v3/animations/rig-check` | Vérifier si un modèle peut être riggé | ✓ | — | ✓ | ✓ | ✓ |
| `POST /v3/animations/rig` | Ajouter un squelette | ✓ | — | ✓ | ✓ | ✓ |
| `POST /v3/animations/retarget` | Appliquer une animation prédéfinie | ✓ | — | ✓ | ✓ | ✓ |
| `GET /v3/tasks/{task_id}` | Récupérer une tâche | ✓ | ✓ | ✓ | ✓ | ✓ |
| `POST /v3/tasks/list` | Récupérer plusieurs tâches | ✓ | — | ✓ | ✓ | ✓ |
| `POST /v3/files` | Téléverser un fichier | ✓ | ✓ | ✓ | ✓ | ✓ |
| `POST /v3/files/presign` | Créer un téléversement présigné | — | — | — | — | ✓ |
| `GET /v3/account/balance` | Obtenir le solde du compte | ✓ | — | ✓ | ✓ | ✓ |
| `GET /v3/account/usage` | Obtenir l’historique d’utilisation | — | — | — | — | ✓ |

Dans cette version verrouillée, Java est le seul à exposer image-to-splat, refine, stylize, import, presign et usage. Java n’expose pas text-to-image, image-to-image ni edit-multiview. Son descripteur interne pour `/v3/files/upload-credentials` ne possède ni service ni méthode cliente publique et n’est donc pas compté comme pris en charge.

Python reste principalement un SDK V2. Sa branche `mesh_segmentation(..., model_version="v2.0-20260430")` utilise également `POST /v3/mesh/segment`, `GET /v3/tasks/{task_id}` et `POST /v3/files` lorsqu’un `ref_image` local doit être téléversé.

### Prise en charge des routes Python V2

Python 0.4.2 expose cinq routes HTTP V2 finales. `POST /v2/openapi/task` est partagée par ses méthodes de génération, de traitement de modèles, de maillage et d’animation ; elle ne se limite pas au texte vers modèle.

| Route HTTP | Objectif |
| --- | --- |
| `POST /v2/openapi/task` | Soumettre toute tâche V2 prise en charge |
| `GET /v2/openapi/task/{task_id}` | Interroger l’état et la sortie de la tâche |
| `GET /v2/openapi/user/balance` | Obtenir le solde du compte |
| `POST /v2/openapi/upload/sts/token` | Obtenir des identifiants de téléversement STS lorsque `boto3` est disponible |
| `POST /v2/openapi/upload` | Téléverser un fichier via le repli multipart historique du SDK |

Java et les autres SDK V3 transmettent la sélection du modèle via leurs modèles de paramètres V3 officiels. Sur le protocole Java, le champ s’appelle `model`.

## 5. Résolution des problèmes

- **Clé manquante :** définissez `TRIPO_API_KEY` dans le processus serveur. Consultez [Authentification](./authentication).
- **Région incorrecte :** sélectionnez le point de terminaison mondial ou chinois correspondant au SDK et à la version d’API utilisés.
- **Échec ou expiration de la tâche :** conservez le `task_id`, examinez l’état final et consultez [Cycle de vie des tâches](./task-lifecycle) et [Gestion des erreurs](./error-handling).
- **URL du modèle expirée :** interrogez de nouveau la tâche lorsque le SDK le permet, puis téléchargez immédiatement le modèle. Ne conservez pas une URL signée temporaire comme ressource permanente.

## Dépôts officiels

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