Build · Try-on virtuel

Intégrez une fonctionnalité de try-on virtuel à votre application

En une phrase

Réceptionnez la photo du produit sur votre backend, envoyez-la en POST à /api/v1/tryon/apparel avec un identifiant de mannequin, effectuez le polling de l'identifiant de génération retourné depuis un background worker (jamais dans le thread de la requête HTTP) jusqu'à ce que le status passe à completed, puis persistez l'output_url dans votre propre stockage objet et affichez-la dans l'UI.

  • Crédits: 5 crédits en 2K · 6 crédits en 4K
  • Délai typique: 1.5–4 min
  • Traitement: asynchrone, polling

Chaque chiffre sur cette page provient de la documentation de l'API Photta · vérifié

Une implémentation pensée pour la production : le client téléverse une photo du produit, votre backend met en file d'attente un job de try-on Photta, un worker effectue le polling jusqu'à la fin du traitement, et le frontend affiche le résultat sur modèle. Pas de requêtes bloquantes, pas de clés d'API exposées, pas de faux SDK.

RESPONSE=$(curl -s -X POST https://api.photta.app/api/v1/tryon/apparel \
  -H "Authorization: Bearer $PHOTTA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "product_type": "top",
  "product_images": [
    "https://cdn.yourstore.com/products/shirt-front.jpg"
  ],
  "product_back_image": "https://cdn.yourstore.com/products/shirt-back.jpg",
  "product_category": "t_shirt",
  "mannequin_id": "mnk_f3a9b1",
  "pose_id": "pose_c2d4e5",
  "background": "https://cdn.yourstore.com/backgrounds/studio-loft.jpg",
  "lock_background": true,
  "resolution": "2K",
  "aspect_ratio": "3:4",
  "body_size": "M",
  "expression": "neutral",
  "user_instruction": "Keep the collar pattern crisp and centered."
}')
ID=$(echo "$RESPONSE" | jq -r '.data.id')

Comment ça fonctionne

De l'upload à l'image sur modèle

Six étapes concrètes. Prévoyez dix à quinze minutes d'intégration lors du premier essai.

  1. Étape 1

    Schématiser le flux de données

    Appareil du client → votre backend (upload) → API Photta (soumission) → API Photta (polling) → votre base de données (miroir de statut) → appareil du client (rendu). Tracez ce flux sur papier avant d'écrire la moindre ligne — la séparation entre votre backend et celui de Photta est essentielle.

  2. Étape 2

    Générer et stocker une clé d'API

    Les clés de production commencent par photta_live_. Placez-la dans une variable d'environnement. Ne l'exposez jamais au navigateur. Une seule clé couvre toutes les capacités de Photta : vous n'avez pas besoin de clés distinctes pour le try-on, les bijoux ou le mannequin fantôme.

  3. Étape 3

    Connecter l'endpoint d'upload

    Réceptionnez d'abord la photo du produit du client dans un stockage objet. Fournir une URL publique à Photta est plus simple que d'utiliser du base64 et vous garantit un historique d'audit pour chaque requête.

  4. Étape 4

    Soumettre le job depuis le serveur

    POST /api/v1/tryon/apparel avec l'URL du produit, mannequin_id, resolution et aspect_ratio. L'API renvoie 202 Accepted + un identifiant de génération. Stockez cet ID dans votre base de données afin que votre client interroge votre propre endpoint, et non celui de Photta.

  5. Étape 5

    Effectuer le polling depuis un background worker

    N'effectuez pas de polling dans la requête HTTP — le job nécessite 1.5 à 4 minutes, ce qui dépasse la plupart des timeouts serverless. Utilisez Trigger.dev, Inngest, BullMQ, Vercel Cron ou votre propre file d'attente pour replanifier un poll toutes les 3 secondes jusqu'à ce que le traitement se termine.

  6. Étape 6

    Afficher le résultat

    Quand le status passe à completed, copiez data.output_url dans votre base de données et émettez un événement temps réel (websocket, SSE ou long-polling) vers l'appareil du client. L'UI remplace le squelette de chargement par l'image. Terminé.

Trois exemples de code complets

Handler d'upload, dispatcheur de jobs, poller côté worker — tous les éléments nécessaires pour déployer la fonctionnalité.

// POST /app/try-on → your backend upload handler
import { put } from "@vercel/blob";

export async function uploadProduct(file: File) {
  const { url } = await put(`products/${crypto.randomUUID()}.jpg`, file, {
    access: "public",
  });
  return url;
}
const res = await fetch("https://api.photta.app/api/v1/tryon/apparel", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.PHOTTA_API_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({
    "product_type": "top",
    "product_images": [
      "https://cdn.yourstore.com/products/shirt-front.jpg"
    ],
    "product_back_image": "https://cdn.yourstore.com/products/shirt-back.jpg",
    "product_category": "t_shirt",
    "mannequin_id": "mnk_f3a9b1",
    "pose_id": "pose_c2d4e5",
    "background": "https://cdn.yourstore.com/backgrounds/studio-loft.jpg",
    "lock_background": true,
    "resolution": "2K",
    "aspect_ratio": "3:4",
    "body_size": "M",
    "expression": "neutral",
    "user_instruction": "Keep the collar pattern crisp and centered."
  }),
});
const { data } = await res.json(); // data.id, data.status
// Trigger.dev / Inngest / BullMQ task
const BASE = "https://api.photta.app/api/v1";

export const pollTryOnTask = task({
  id: "poll-try-on",
  run: async ({ generationId, attempt = 0 }) => {
    const res = await fetch(`${BASE}/tryon/apparel/${generationId}`, {
      headers: { Authorization: `Bearer ${process.env.PHOTTA_API_KEY}` },
    });
    const { data } = await res.json();
    if (data.status === "completed") return data.output_url;
    if (data.status === "failed") throw new Error(data.error_message);
    if (attempt >= 120) throw new Error("try-on timed out");
    // Re-schedule this same task after 3 seconds.
    return ctx.retry.after(3000, { generationId, attempt: attempt + 1 });
  },
});

Questions fréquentes des développeurs

Questions avant de mettre en production

Puis-je le faire sans backend ?

Non. Votre clé d'API Photta doit rester côté serveur. Même un simple route handler Next.js ou un Cloudflare Worker fait office de backend à cet effet — la clé doit simplement résider là où un user-agent ne peut pas la lire.

Comment éviter les requêtes HTTP qui restent en suspens ?

Ne faites jamais de polling dans un gestionnaire de requête. Soumettez le job de manière synchrone, renvoyez l'ID de génération au client et effectuez le polling depuis un worker d'arrière-plan. Le client effectue le polling sur VOTRE status endpoint, pas sur celui de Photta — de cette façon, les rate limits relèvent de votre gestion, pas de celle de chaque utilisateur.

Que se passe-t-il si un job échoue en cours d'exécution ?

Photta rembourse automatiquement les crédits en cas d'échec, et la réponse contient data.error_code + data.error_message. Affichez un message clair à l'utilisateur et proposez un bouton de nouvelle tentative qui relance un nouveau job.

Puis-je afficher une progression en temps réel ?

Photta n'émet pas de progression intermédiaire — le statut est processing, completed ou failed. Une solution efficace consiste à utiliser une barre de progression temporelle calibrée sur la fenêtre de 1.5–4 minutes, ou un simple skeleton loader. N'affichez pas de pourcentages trompeurs.

L'URL du résultat est-elle permanente ?

L'URL du CDN est stable, mais votre produit ne devrait pas en dépendre pour l'affichage à long terme. Téléchargez les octets une seule fois et stockez-les dans votre propre bucket S3/GCS/R2 — ainsi, votre PDP reste opérationnelle même si le CDN de Photta change.

Déployez le try-on virtuel en un après-midi

Chaque exemple de code sur cette page correspond à la documentation officielle de Photta. Récupérez une clé d'API et vous aurez un prototype fonctionnel avant la fin de votre café.