API Reference
Documentation API
API REST pour intégrer la cabine d'essayage virtuel IA dans vos boutiques e-commerce, et tracker les conversions générées.
https://cabine.ai/api
· V1 (essayage produit unique) : /v1/*
· V2 (personal shopper Looks) : /v2/*
· Format : application/json
Authentification
Toutes les requêtes nécessitent une clé API dans l'en-tête HTTP. Générez votre clé depuis Mon compte → Clés API. La même clé fonctionne pour V1 et V2.
Via l'en-tête X-Api-Key (recommandé)
X-Api-Key: vf_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Via Authorization Bearer
Authorization: Bearer vf_live_xxxxxxxxxxxxxxxxxxxxxxxx
Gestion des erreurs
Toutes les réponses d'erreur suivent ce format :
{
"success": false,
"error": "error_code",
"message": "Description lisible en français"
}
| HTTP | Code erreur | Endpoint(s) | Description |
|---|---|---|---|
| 400 | invalid_json | tous | Corps JSON malformé |
| 401 | authentication_error | tous | Clé API manquante, invalide ou révoquée |
| 402 | no_active_subscription | /generate · /look-tryon | Aucun abonnement actif sur ce compte |
| 403 | model_not_allowed | /generate | Modèle non inclus dans votre plan |
| 404 | no_looks_available | /look-tryon | Aucun Look publié disponible pour ce marchand (et/ou cette catégorie) |
| 422 | invalid_param | tous | Paramètre manquant, invalide ou image non décodable |
| 422 | invalid_param | /generate | prompt_type invalide (valeurs acceptées : mirror, universe, thematic) |
| 422 | invalid_model | /generate | Identifiant de modèle inconnu — consultez /models |
| 422 | invalid_category | /look-tryon | Catégorie introuvable ou inactive |
| 422 | no_usable_look | /look-tryon | Aucun Look exploitable (le top match et ses alternatives n'ont pas de prompt try-on configuré) |
| 429 | quota_exceeded | /generate · /look-tryon | Quota de crédits mensuel épuisé |
| 500 | generation_failed | /generate · /look-tryon | Erreur API Gemini ou génération impossible |
| 500 | profile_analysis_failed | /look-tryon | L'analyse stylistique de la photo utilisateur a échoué |
| 500 | matching_failed | /look-tryon | Le matcher n'a pu sélectionner aucun Look |
Génération d'essayage V1
Envoie deux images (produit + photo du client) et retourne une URL de téléchargement de l'image générée. Consomme 1 crédit par appel.
Sources d'images — 3 modes (mixables)
product_image_* et user_photo_* acceptent chacun 3 formats. Priorité : URL > base64 > multipart. Utilisez celui qui correspond à votre architecture.
| Paramètre | Type | Description | |
|---|---|---|---|
| IMAGE PRODUIT — fournir exactement l'un des 3 | |||
| product_image_url | string | URL | URL HTTPS publique de l'image produit. Doit être accessible depuis nos serveurs. |
| product_image_b64 | string | base64 | Image encodée en base64, avec ou sans préfixe data:image/...;base64,. Min. 1 Ko décodé. |
| product_image | file | multipart | Fichier image en multipart/form-data. Formats acceptés : JPEG, PNG, WebP. |
| PHOTO UTILISATEUR — fournir exactement l'un des 3 | |||
| user_photo_url | string | URL | URL HTTPS publique de la photo de la personne. |
| user_photo_b64 | string | base64 | Photo encodée en base64. |
| user_photo | file | multipart | Fichier photo en multipart/form-data. |
| OPTIONS | |||
| model | string | optionnel | Identifiant du modèle IA. Défaut : gemini-3-pro-image-preview. Consultez GET /models pour la liste complète. |
| prompt | string | optionnel | Instructions personnalisées. Si absent, le prompt haute-fidélité par défaut est utilisé. |
| PROMPTS PAR CATÉGORIE — nouveaux champs optionnels | |||
| category | string | nouveau | Libellé libre de la catégorie produit : "robe courte", "t-shirt", "lunettes de soleil"… cabine.ai associe automatiquement votre libellé à la meilleure catégorie interne via un matching intelligent (mots-clés + tokens + genre). Si une catégorie est reconnue ET qu'un prompt actif existe pour ce couple (catégorie, type), il remplace le prompt fourni. |
| prompt_type | string | nouveau | Type de rendu souhaité : mirror (reflet réaliste), universe (univers éditorial premium) ou thematic (mise en scène thématique : fées, dinosaures, super-héros…). Défaut : mirror si category est fourni. |
| product_name | string | nouveau | Nom complet du produit (ex : "Robe d'été rouge à motifs"). Améliore la précision du matching de catégorie, surtout si category est vague ou absent. |
| TRACKING — optionnels mais fortement recommandés pour le suivi des conversions | |||
| product_id | int | recommandé | ID du produit côté CMS. Utilisé pour lier automatiquement les conversions à cette génération. |
| cart_id | int | recommandé | ID du panier côté CMS. Clé de jonction principale avec l'endpoint POST /conversion. |
| customer_id | int | optionnel | ID du client côté CMS. Pour filtrage et exports. |
category, ni prompt_type, ni product_name, le comportement est strictement identique à l'API précédente. Aucune mise à jour de votre intégration n'est requise.
Mode 1 — URL publique (JSON)
curl -X POST https://cabine.ai/api/v1/generate \
-H "X-Api-Key: vf_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"product_image_url": "https://maboutique.com/img/robe.jpg",
"user_photo_url": "https://maboutique.com/uploads/client.jpg",
"product_id": 42,
"cart_id": 67890,
"customer_id": 12345
}'
Mode 2 — Base64 ✅ recommandé pour PrestaShop
curl -X POST https://cabine.ai/api/v1/generate \
-H "X-Api-Key: vf_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"product_image_b64": "data:image/jpeg;base64,/9j/4AAQ...",
"user_photo_b64": "data:image/jpeg;base64,/9j/4AAQ...",
"product_id": 42,
"cart_id": 67890,
"customer_id": 12345
}'
Mode 3 — Multipart/form-data (upload direct)
curl -X POST https://cabine.ai/api/v1/generate \
-H "X-Api-Key: vf_live_xxx" \
-F "product_image=@/chemin/robe.jpg" \
-F "user_photo=@/chemin/client.jpg" \
-F "product_id=42" \
-F "cart_id=67890" \
-F "customer_id=12345"
Mode 4 — Avec prompt premium « Univers » nouveau
Déclenche le prompt éditorial premium configuré côté cabine.ai pour la catégorie « robe courte ». Aucun prompt à fournir : le contenu est géré dans le back-office.
curl -X POST https://cabine.ai/api/v1/generate \
-H "X-Api-Key: vf_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"product_image_b64": "data:image/jpeg;base64,/9j/4AAQ...",
"user_photo_b64": "data:image/jpeg;base64,/9j/4AAQ...",
"category": "robe courte",
"prompt_type": "universe",
"product_name": "Robe courte en soie rouge collection été",
"product_id": 42,
"cart_id": 67890
}'
Mode 5 — Avec prompt « Thématisé » pour collection enfant nouveau
Pour une collection vêtements enfant avec mise en scène dinosaures. Le prompt thématique correspondant est configuré côté back-office cabine.ai pour la catégorie « t-shirt enfant ».
curl -X POST https://cabine.ai/api/v1/generate \
-H "X-Api-Key: vf_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"product_image_b64": "data:image/jpeg;base64,/9j/4AAQ...",
"user_photo_b64": "data:image/jpeg;base64,/9j/4AAQ...",
"category": "t-shirt enfant",
"prompt_type": "thematic",
"product_name": "T-shirt enfant dinosaures collection Jurassic",
"product_id": 142
}'
Réponse succès (200)
{
"success": true,
"result_url": "https://cabine.ai/generation/a3f8...b2/download",
"generation_id": 1042,
"credits_used": 1,
"credits_remaining": 163,
"processing_time_ms": 8420
}
Champs de la réponse
| Champ | Type | Description |
|---|---|---|
| success | bool | true si la génération a réussi |
| result_url | string | URL de téléchargement (token 64 hex, accessible sans authentification). Sauvegardez-la en BDD. |
| generation_id | int | ID interne de la génération — à conserver pour le lien avec POST /conversion |
| credits_used | int | Crédits consommés (toujours 1 par essayage) |
| credits_remaining | int | Crédits restants sur votre abonnement ce mois-ci |
| processing_time_ms | int | Durée de traitement en millisecondes |
Après expiration, la route retourne
HTTP 410 Gone.
Prompts & catégories nouveau
cabine.ai permet d'utiliser des prompts spécialisés, configurés par catégorie de produit et par type de rendu, pour obtenir des résultats bien plus pertinents qu'avec un prompt générique. Les prompts sont gérés depuis votre back-office et appliqués automatiquement selon les informations que vous envoyez à l'API.
Principe de fonctionnement
À chaque appel à POST /generate, cabine.ai applique cette logique de priorité :
- Si
categoryouproduct_nameest fourni : recherche d'une catégorie correspondante via matching intelligent. Si un prompt actif existe pour ce couple (catégorie × type), il est utilisé. - Sinon, le champ
promptfourni par le client est utilisé (ancien comportement). - Sinon, le prompt haute-fidélité par défaut de cabine.ai est utilisé.
Les trois types de prompts
| Type | Description | Cas d'usage |
|---|---|---|
mirror |
Reflet réaliste du client dans son contexte naturel, portant le vêtement. Préservation maximale de l'identité faciale, de la morphologie et de la taille réelles. | E-commerce classique, aide à la décision d'achat, réduction des retours. |
universe |
Immersion éditoriale : le client est placé dans l'univers premium de la marque, avec direction artistique, lumière studio, ambiance de campagne publicitaire. | Marques de luxe, collections premium, contenu social media, storytelling. |
thematic |
Mise en scène thématique ludique : personnages, décors et ambiances imaginaires (fées, dinosaures, super-héros, pirates, espace, forêt enchantée…). Préserve l'identité faciale mais transpose le cadre dans un univers narratif. | Collections enfants, collections saisonnières (Halloween, Noël), boutiques déguisements, marques de jouets, éditions limitées thématiques. |
Matching intelligent des catégories
Vous n'avez pas besoin de connaître les slugs internes de cabine.ai. Envoyez simplement le libellé tel qu'il apparaît dans votre catalogue — le matcher trouve la meilleure correspondance grâce à un algorithme local (mots-clés, tokens, détection de genre) :
| Libellé envoyé | → | Catégorie résolue |
|---|---|---|
| "robe courte d'été" | → | robe_courte |
| "mini robe rouge" | → | robe_courte |
| "short pour homme" | → | short_homme |
| "short femme plage" | → | short_femme |
| "Ray-Ban aviateur" | → | lunettes_soleil |
| "chemise lin oversize" | → | chemise |
| "xyz1234" | → | aucune — fallback sur prompt ou défaut |
category (catégorie CMS) et product_name (nom complet du produit) pour le meilleur matching. Si votre CMS ne renseigne qu'un champ vague, envoyer les deux augmente les chances de résolution correcte.
Catégories disponibles par défaut
cabine.ai fournit un catalogue initial qui couvre la majorité des cas e-commerce mode & accessoires :
- robe_longue
- robe_courte
- robe_mariee
- robe_couture
- jupe
- pantalon
- short_homme
- short_femme
- t_shirt
- chemise
- pull
- veste
- manteau
- casquette
- bonnet
- chapeau
- lunettes_soleil
- lunettes_vue
- chaussures
- sac
- maillot_bain
Besoin d'une catégorie supplémentaire (ex : bijouterie, montres, lingerie…) ? Contactez support@cabine.ai.
Gérer vos propres prompts
Les comptes Scale et Enterprise peuvent créer leurs propres prompts personnalisés depuis le back-office cabine.ai, section Prompts. Chaque prompt est lié à une catégorie et à un type, versionné automatiquement à chaque modification, avec historique et restauration en un clic.
Exemple complet — flux PrestaShop avec catégorie
// Récupération du produit + catégorie CMS côté PrestaShop
$product = new Product((int) Tools::getValue('id_product'));
$categoryName = Category::getLinkRewrite($product->id_category_default, Context::getContext()->language->id);
$payload = json_encode([
'product_image_b64' => 'data:image/jpeg;base64,' . base64_encode(file_get_contents($productImagePath)),
'user_photo_b64' => 'data:image/jpeg;base64,' . base64_encode(file_get_contents($userPhotoTmpPath)),
'category' => $categoryName, // "robe-longue", "t-shirt-homme"…
'prompt_type' => 'universe', // ou 'mirror'
'product_name' => $product->name[Context::getContext()->language->id],
'product_id' => (int) $product->id,
'cart_id' => (int) Context::getContext()->cart->id,
'customer_id' => (int) Context::getContext()->customer->id,
]);
Enregistrement de conversion V1
Enregistre une conversion : une commande passée après qu'un client a effectué un essayage virtuel. L'API relie automatiquement la commande à la génération d'origine grâce au cart_id et au product_id envoyés lors de l'essayage.
Cet endpoint est idempotent : un second appel avec le même order_id retourne la conversion déjà enregistrée sans créer de doublon.
product_id et cart_id lors du POST /generate ou POST /look-tryon, l'API retrouve la génération correspondante et remplit linked_generation_id automatiquement.
Paramètres
| Paramètre | Type | Description | |
|---|---|---|---|
| order_id | string | requis | ID ou référence de la commande côté CMS (PrestaShop, WooCommerce…). Accepte les références alphanumériques. |
| product_id | int | recommandé | ID du produit acheté côté CMS. Utilisé pour retrouver la génération d'origine. |
| cart_id | int | recommandé | ID du panier à l'origine de la commande. Clé de jonction principale avec la génération. |
| customer_id | int | optionnel | ID du client côté CMS. |
| metadata | object | optionnel | Données complémentaires libres : montant, devise, SKU, etc. (JSON arbitraire) |
Exemple — appel depuis PrestaShop
curl -X POST https://cabine.ai/api/v1/conversion \
-H "X-Api-Key: vf_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"order_id": "PS-00012345",
"product_id": 42,
"cart_id": 67890,
"customer_id": 12345,
"metadata": {
"amount": 89.90,
"currency": "EUR",
"sku": "ROBE-BLEU-M"
}
}'
Réponse succès (201 Created)
{
"success": true,
"conversion_id": 58,
"linked_generation_id": 1042,
"already_recorded": false
}
Réponse — conversion déjà enregistrée (200, idempotent)
{
"success": true,
"conversion_id": 58,
"linked_generation_id": 1042,
"already_recorded": true
}
Champs de la réponse
| Champ | Type | Description |
|---|---|---|
| success | bool | true dans tous les cas de succès |
| conversion_id | int | ID interne de la conversion enregistrée |
| linked_generation_id | int|null | ID de la génération liée automatiquement, ou null si aucune génération trouvée pour ce cart_id + product_id |
| already_recorded | bool | true si la conversion existait déjà (réponse idempotente) |
Intégration PrestaShop — hook actionOrderStatusPostUpdate
// À appeler depuis le hook de confirmation de commande
public function hookActionOrderStatusPostUpdate($params)
{
$order = $params['order'];
$status = $params['newOrderStatus'];
// Ne déclencher que sur commandes validées/payées
if (!in_array($status->id, [2, 12])) return;
foreach ($order->getProducts() as $product) {
$payload = json_encode([
'order_id' => (string) $order->reference,
'product_id' => (int) $product['product_id'],
'cart_id' => (int) $order->id_cart,
'customer_id' => (int) $order->id_customer,
'metadata' => [
'amount' => (float) $order->total_paid,
'currency' => Context::getContext()->currency->iso_code,
'sku' => $product['reference'],
],
]);
file_get_contents('https://cabine.ai/api/v1/conversion', false,
stream_context_create(['http' => [
'method' => 'POST',
'header' => "X-Api-Key: vf_live_xxx\r\nContent-Type: application/json",
'content' => $payload,
'timeout' => 5,
'ignore_errors' => true, // Ne pas bloquer la confirmation commande
]])
);
}
}
5s). Ne laissez pas une éventuelle erreur réseau bloquer la confirmation de commande côté boutique.Consulter son quota V1
Retourne le détail des crédits de l'abonnement actif. Aucun paramètre requis. Le quota retourné couvre les appels V1 et V2 (1 crédit chacun).
curl https://cabine.ai/api/v1/quota \
-H "X-Api-Key: vf_live_xxx"
Réponse succès (200)
{
"success": true,
"plan": "Growth",
"plan_slug": "growth",
"credits_total": 200,
"credits_used": 37,
"credits_bonus": 0,
"credits_remaining": 163,
"usage_percent": 18,
"renews_at": "2025-02-01"
}
Champs de la réponse
| Champ | Type | Description |
|---|---|---|
| plan | string | Nom lisible du plan actif |
| plan_slug | string | Identifiant machine du plan |
| credits_total | int | Crédits mensuels inclus dans le plan |
| credits_used | int | Crédits consommés ce mois-ci (V1 + V2) |
| credits_bonus | int | Crédits bonus ajoutés manuellement (hors quota mensuel) |
| credits_remaining | int | Crédits restants (inclut les crédits bonus) |
| usage_percent | int | Pourcentage d'utilisation des crédits du plan (hors bonus) |
| renews_at | string | Date de renouvellement du quota (format YYYY-MM-DD) |
Modèles disponibles V1
Retourne la liste des modèles IA disponibles et indique lesquels sont accessibles avec votre plan. Aucun paramètre requis.
curl https://cabine.ai/api/v1/models \
-H "X-Api-Key: vf_live_xxx"
Réponse succès (200)
{
"success": true,
"models": [
{
"id": "gemini-3-pro-image-preview",
"label": "Flash Image — défaut ✅",
"credits_per_generation": 1,
"available": true
}
]
}
Champs par modèle
| Champ | Type | Description |
|---|---|---|
| id | string | Identifiant à passer dans le champ model de POST /generate |
| label | string | Nom lisible du modèle |
| credits_per_generation | int | 1 pour V1 — 2 pour V2 (look-tryon, ajoute l'analyse stylistique + matching) |
| available | bool | true si le modèle est inclus dans votre plan actif |
Look Try-On — Personal Shopper IA V2
L'API V2 propose un essayage virtuel d'un Look complet (tenue entière coordonnée par la marque) avec recommandation stylistique automatique. Le client envoie uniquement sa photo : Cabine.ai analyse son profil stylistique, sélectionne le Look le plus adapté parmi ceux publiés par le marchand, et génère l'essayage.
POST /api/v1/generate — essayage d'UN produit unique fourni en input par le client (1 crédit)POST /api/v2/look-tryon — recommandation + essayage d'un LOOK COMPLET sélectionné par l'IA dans le catalogue marchand (1 crédit)
Pipeline complet
category_id et/ou collection_id/api/v1/generate (queue asynchrone, débit d'1 crédit, persistance, stockage). La V2 hérite ainsi de toute la robustesse de la V1.Coût et architecture
L'appel V2 coûte 1 crédit, comme un essayage /api/v1/generate. L'analyse stylistique du profil et le matching des Looks ne consomment pas de crédit supplémentaire — seule la génération photoréaliste finale est facturée, exactement comme en V1. En interne, la V2 délègue la génération d'image au même orchestrateur que la V1 (file d'attente asynchrone, persistance, gestion d'erreur, stockage), ce qui garantit un comportement et une fiabilité identiques entre les deux endpoints.
Essayage d'un Look V2
Envoie uniquement la photo du client. L'API retourne le Look recommandé (avec raison de la sélection et liste des produits cliquables), l'image d'essayage générée, et 2 alternatives pour proposer un « Vous pourriez aussi aimer… ». Consomme 1 crédit par appel (comme un essayage V1).
Paramètres
| Paramètre | Type | Description | |
|---|---|---|---|
| PHOTO UTILISATEUR — fournir exactement l'un des 3 | |||
| user_image_url | string | URL | URL HTTPS publique de la photo de la personne. Doit être accessible depuis nos serveurs. |
| user_image_b64 | string | base64 | Photo encodée en base64, avec ou sans préfixe data:image/...;base64,. Formats : JPEG, PNG, WebP. |
| user_photo | file | multipart | Fichier photo en multipart/form-data. |
| FILTRES — optionnels (restreignent l'univers de matching) | |||
| category_id | int | optionnel | ID d'une catégorie Cabine.ai existante. Restreint le matching aux Looks de cette catégorie. Si absent, tous les Looks publiés du marchand sont éligibles. |
| collection_id | string | optionnel | ID/GID libre de collection (Shopify GID, PrestaShop, etc.) tel que renseigné lors de la création des Looks. Permet de cibler une collection précise (« été 2026 », « capsule Pierre Hardy »…). |
| ESSAYAGE DIRECT — optionnel | |||
| look_id | int | optionnel | ID d'un Look précis à essayer directement, sans recommandation. Typiquement le id d'une alternative reçue lors d'un précédent appel : le client demande « essayez plutôt celui-ci ». Voir Mode essayage direct ci-dessous. |
Mode essayage direct (look_id)
Par défaut, l'endpoint fonctionne en mode recommandation : il analyse la photo, sélectionne le meilleur Look et renvoie 2 alternatives. Si le client souhaite ensuite essayer l'une de ces alternatives, rappelez le même endpoint en ajoutant son look_id — c'est le mode direct.
Le champ mode de la réponse vaut alors "direct" (vs "recommendation"). L'essayage est généré sur le Look demandé, et le bloc alternatives propose d'autres Looks du catalogue compatibles avec le profil.
gender_mismatch — la cohérence prime sur la demande.
Le coût est identique (1 crédit), et la réponse a la même structure que le mode recommandation.
# 1er appel — recommandation
curl -X POST https://cabine.ai/api/v2/look-tryon \
-H "Authorization: Bearer VOTRE_CLE" \
-F user_photo=@client.jpg
# Réponse → alternatives: [{ "id": 47, ... }, { "id": 52, ... }]
# 2e appel — le client veut essayer l'alternative #47
curl -X POST https://cabine.ai/api/v2/look-tryon \
-H "Authorization: Bearer VOTRE_CLE" \
-F user_photo=@client.jpg \
-F look_id=47
Mode 1 — URL publique (JSON, sans filtre)
curl -X POST https://cabine.ai/api/v2/look-tryon \
-H "X-Api-Key: vf_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"user_image_url": "https://maboutique.com/uploads/client.jpg"
}'
Mode 2 — Base64 ✅ recommandé pour intégrations CMS
curl -X POST https://cabine.ai/api/v2/look-tryon \
-H "X-Api-Key: vf_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"user_image_b64": "data:image/jpeg;base64,/9j/4AAQ...",
"category_id": 14,
"collection_id": "gid://shopify/Collection/289346731"
}'
Mode 3 — Multipart/form-data (upload direct)
curl -X POST https://cabine.ai/api/v2/look-tryon \
-H "X-Api-Key: vf_live_xxx" \
-F "user_photo=@/chemin/client.jpg" \
-F "category_id=14"
Réponse succès (200)
{
"success": true,
"selected_look": {
"id": 42,
"name": "Urban Minimal Denim",
"description": "Look casual minimal avec veste denim et pantalon beige.",
"reason": "Ce look fonctionne particulièrement bien avec votre carnation, les couleurs s'accordent à votre palette — un équilibre subtil pensé pour vous mettre en valeur.",
"match_score": 0.78,
"image_url": "https://cdn.marque.com/looks/look-042.jpg",
"tags": {
"style": ["casual", "minimal", "urban"],
"occasion": ["daily", "weekend"],
"season": ["spring", "summer"],
"colors": ["navy blue", "beige", "white"]
},
"products": [
{
"name": "Veste denim oversize",
"product_url": "https://maboutique.com/p/veste-denim-oversize",
"product_id": "shopify_gid_xxx"
},
{
"name": "Pantalon droit beige",
"product_url": "https://maboutique.com/p/pantalon-droit-beige",
"product_id": "shopify_gid_yyy"
}
]
},
"alternatives": [
{
"id": 47,
"name": "Soft Cream Layering",
"description": "Layering doux crème et beige.",
"match_score": 0.71,
"image_url": "https://cdn.marque.com/looks/look-047.jpg",
"tags": { /* idem */ },
"products": [ /* idem */ ]
},
{
"id": 53,
"name": "Workwear Heritage",
"description": "Workwear chino et chambray.",
"match_score": 0.68,
"image_url": "https://cdn.marque.com/looks/look-053.jpg",
"tags": { /* idem */ },
"products": [ /* idem */ ]
}
],
"tryon": {
"status": "completed",
"image_url": "https://cabine.ai/api/v1/result/a3f8...b2"
},
"generation_id": 2087,
"credits_used": 1,
"credits_remaining": 161,
"processing_time_ms": 12340
}
Réponse — génération encore en cours (202 Accepted)
La génération d'image est asynchrone (même infrastructure que /api/v1/generate). Si elle dépasse le délai d'attente synchrone, l'API répond 202 Accepted avec tryon.status = "pending" et une poll_url. Le matching et les recommandations (selected_look, alternatives) sont déjà disponibles ; seule l'image se fait attendre.
{
"success": true,
"selected_look": { /* … identique … */ },
"alternatives": [ /* … identique … */ ],
"tryon": {
"status": "pending",
"poll_url": "https://cabine.ai/api/v1/generation/2087/status"
},
"generation_id": 2087,
"message": "Génération en cours. Interrogez poll_url pour récupérer le résultat."
}
GET /api/v1/generation/{id}/status. Quand status passe à success, récupérez result_url. Le crédit n'est débité qu'une fois — au lancement de la génération.
Champs de la réponse — niveau racine
| Champ | Type | Description |
|---|---|---|
| success | bool | true si le pipeline (analyse + matching + lancement génération) a réussi |
| selected_look | object | Look sélectionné par le matcher (voir détail ci-dessous) |
| alternatives | array | 2 Looks suivants du ranking (sans génération try-on). Permet d'afficher « Vous pourriez aussi aimer… » sans nouvel appel API. |
| tryon | object | Résultat de la génération : { status: "completed", image_url } si prête, ou { status: "pending", poll_url } si encore en cours |
| generation_id | int | ID interne — à conserver pour le polling et le lien avec POST /conversion |
| credits_used | int | Toujours 1 pour cet endpoint (comme V1) — présent uniquement si status = completed |
| credits_remaining | int | Crédits restants sur l'abonnement — présent uniquement si status = completed |
| processing_time_ms | int | Durée totale du pipeline en millisecondes — présent uniquement si status = completed |
Champs du selected_look
| Champ | Type | Description |
|---|---|---|
| id | int | ID interne du Look |
| name | string | Nom du Look (court, évocateur) |
| description | string|null | Description marchande du Look (FR) |
| reason | string | Justification humaine en français : « ce look fonctionne avec votre carnation, les couleurs s'accordent à votre palette… ». À afficher au client comme « explication du personal shopper ». |
| match_score | float | Score de matching (0.0 à 1.0). Sert au tri et à la transparence. |
| image_url | string | URL de l'image de référence du Look (telle que renseignée par la marque) |
| tags | object | { style[], occasion[], season[], colors[] } — pour badges/filtres côté front |
| products | array | Liste des pièces du Look avec leur URL fiche produit cliquable et leur ID CMS. C'est le point de conversion. |
Mode test
Avec une clé API en mode test (vf_test_xxx), l'endpoint retourne un placeholder en quelques centaines de millisecondes sans appel Gemini ni débit de crédits. La réponse expose is_test_mode: true pour permettre à votre intégration de l'identifier.
Créer des Looks V2
La création et la gestion des Looks se fait depuis le back-office Cabine.ai (pas via l'API). Chaque Look est :
- Une tenue complète validée par la marque (image d'un mannequin / photo éditoriale / flatlay)
- Rattaché à une catégorie Cabine.ai et optionnellement à une collection (ID libre côté CMS)
- Décrit par un breakdown forensique de chaque pièce (couleur, matière, finition, hardware, branding…) généré automatiquement par Gemini à l'upload
- Doté d'un prompt try-on dédié (structure rigoureuse mirror-style, verrouillage de l'identité utilisateur, fidélité 1:1 du produit) éditable par la marque
- Doté de tags stylistiques (style, occasion, saison, couleurs) et de compatibilités cibles (carnation, cheveux, morphologie) pour le matcher
- Associé à une liste de produits cliquables (nom + URL fiche produit + ID CMS)
Cycle de vie d'un Look
| Statut | Matchable par /look-tryon ? | Description |
|---|---|---|
draft | non | Look en cours de validation marchande. N'apparaît pas dans les recommandations. |
published | oui | Validé par la marque, visible et matchable par l'API V2. |
archived | non | Retiré du catalogue (collection passée, fin de stock). Conservé pour historique mais non recommandé. |
Workflow recommandé en BO
- Aller dans Mon compte → Looks → « Nouveau Look »
- Upload de l'image du Look (JPEG · PNG · WebP, max 15 Mo)
- Cliquer « Analyser avec Gemini » : le formulaire se pré-remplit (nom, description, tags, targeting, pièces détectées, prompt try-on)
- Renseigner les URLs des fiches produit pour chaque pièce (point de conversion essentiel)
- Ajuster les tags/targeting/prompt si besoin
- « Publier » → le Look devient matchable par
POST /api/v2/look-tryon
Bonnes pratiques pour la qualité du matching
- Image du Look : mannequin de face, plein corps visible, fond uni ou éditorial clair, résolution ≥ 800 × 1066 px (ratio portrait 3:4 recommandé)
- Tags stylistiques : remplissez systématiquement style, occasion, saison et couleurs — Gemini fait un bon premier jet, mais une revue humaine améliore significativement le matching
- Targeting morphologique : laissez vide si le Look est universel ; ne remplissez que si une compatibilité est vraiment dominante (ex : robe ajustée → hourglass, rectangle)
- URLs produit : renseignez-les toutes, même pour les accessoires — c'est ce qui transforme l'essayage en revenu
- Catalogue minimum : visez 20+ Looks publiés couvrant 3-4 catégories pour que le matcher ait de la matière. En dessous, les résultats peuvent paraître répétitifs.
Codes d'erreur spécifiques V2 V2
L'endpoint POST /api/v2/look-tryon ajoute plusieurs codes spécifiques à son pipeline. Ils sont retournés avec leur code HTTP approprié et un message lisible en français.
| HTTP | Code | Quand | Action recommandée |
|---|---|---|---|
| 402 | no_active_subscription | Aucun abonnement actif sur le compte | Souscrire un plan |
| 404 | no_looks_available | Aucun Look publié pour le marchand (et/ou cette category_id/collection_id) |
Publier au moins un Look dans le BO ; vérifier les filtres envoyés |
| 404 | look_not_found | look_id fourni mais introuvable, non publié, ou n'appartenant pas à ce compte |
Utiliser un id issu du bloc alternatives d'une réponse précédente |
| 409 | gender_mismatch | look_id valide mais incompatible avec le genre détecté sur la photo |
Proposer un Look adapté au profil ; ce garde-fou est volontaire |
| 422 | invalid_param | Aucune photo utilisateur fournie (ou format/encodage invalide) | Vérifier que user_image_url, user_image_b64 ou user_photo est bien envoyé |
| 422 | invalid_category | category_id fourni mais introuvable ou désactivée |
Omettre le paramètre ou utiliser un category_id valide |
| 422 | no_usable_look | Le Look matché (et ses alternatives) n'ont pas de prompt try-on configuré | Relancer l'analyse Gemini ou saisir manuellement le prompt depuis le BO |
| 429 | quota_exceeded | Aucun crédit disponible | Attendre le renouvellement ou upgrader le plan ; la réponse inclut needed et remaining |
| 500 | profile_analysis_failed | L'analyse stylistique Gemini de la photo utilisateur a échoué (image illisible, contenu non analysable, surcharge Gemini) | Réessayer avec une autre photo (face caméra, bonne luminosité, ≥ 400 × 400 px) |
| 500 | matching_failed | Le matcher n'a pu sélectionner aucun Look (cas pathologique) | Contacter le support — incident exceptionnel |
| 500 | generation_failed | Échec de Gemini Image lors de la génération photoréaliste | Réessayer après 5 s (max 3 tentatives) — aucun crédit n'est débité en cas d'échec |
Exemple de réponse d'erreur — quota insuffisant
{
"success": false,
"error": "quota_exceeded",
"message": "Crédits insuffisants pour générer l'essayage.",
"needed": 2,
"remaining": 1
}
Intégration PrestaShop
Le module cabineai supporte nativement l'API cabine.ai en mode SaaS. Configurez votre clé API depuis Mon compte → Clés API.
Configuration du module
# BO PrestaShop → Modules → cabineai → Configurer
Mode : SaaS (API externe)
API Endpoint : https://cabine.ai/api/v1/generate
API Key : vf_live_xxxxxxxx... ← Depuis Mon compte → Clés API
Type de rendu : mirror | universe ← Optionnel, active le prompt par catégorie
Flux complet recommandé
1. Client clique "Essayer ce vêtement" sur la fiche produit
2. Upload photo → module encode en base64
POST /api/v1/generate avec :
- product_id, cart_id, customer_id (tracking)
- category, product_name, prompt_type (prompts intelligents)
3. API résout la catégorie → sélectionne le prompt adapté
4. API génère l'image (~15-90s selon le modèle)
5. API retourne result_url + generation_id → module affiche l'image
6. Client passe commande
7. Webhook PrestaShop → POST /api/v1/conversion avec order_id, product_id, cart_id
8. L'API relie automatiquement la commande à l'essayage d'origine
Appel génération — exemple PHP complet
// Dans le controller AJAX du module (controllers/front/ajax.php)
$product = new Product((int) Tools::getValue('id_product'));
$category = new Category($product->id_category_default, Context::getContext()->language->id);
$payload = json_encode([
'product_image_b64' => 'data:image/jpeg;base64,' . base64_encode(file_get_contents($productImagePath)),
'user_photo_b64' => 'data:image/jpeg;base64,' . base64_encode(file_get_contents($userPhotoTmpPath)),
// Prompts intelligents (optionnels — ignorés si aucun match)
'category' => $category->name,
'product_name' => $product->name[Context::getContext()->language->id],
'prompt_type' => Configuration::get('CABINEAI_PROMPT_TYPE', 'mirror'),
// Tracking (recommandé)
'product_id' => (int) Tools::getValue('id_product'),
'cart_id' => (int) Context::getContext()->cart->id,
'customer_id' => (int) Context::getContext()->customer->id, // 0 si visiteur
]);
$response = file_get_contents('https://cabine.ai/api/v1/generate', false,
stream_context_create(['http' => [
'method' => 'POST',
'header' => "X-Api-Key: vf_live_xxx\r\nContent-Type: application/json",
'content' => $payload,
'timeout' => 120,
'ignore_errors' => true,
]])
);
$data = json_decode($response, true);
if ($data['success']) {
$resultUrl = $data['result_url'];
$generationId = $data['generation_id'];
}
Modèle de crédits
V2 : 1 appel
/look-tryon = 1 crédit (identique à un essayage V1 ; analyse et matching offerts).Modèle par défaut :
gemini-3-pro-image-preview.
Les crédits sont renouvelés le 1er de chaque mois. Les crédits non utilisés ne sont pas reportés. Les crédits bonus (ajoutés manuellement par le support) s'ajoutent aux crédits du plan et sont inclus dans credits_remaining. Aucun crédit n'est débité en cas d'échec du pipeline (transactionnel).
Bonnes pratiques
Génération V1 — Essayage produit unique
- Images produit : fond blanc ou uni, vêtement visible en entier, résolution ≥ 800 px
- Photos utilisateur : portrait face caméra, haut du corps visible, bonne luminosité, résolution ≥ 400 × 400 px
- Timeout client : prévoyez 120 s — la génération peut prendre jusqu'à 90 s selon la charge
- Prompts intelligents : envoyez toujours
category+product_name+prompt_typepour bénéficier des prompts optimisés par catégorie - Tracking : passez toujours
product_idetcart_idpour activer le lien automatique avec les conversions
Look Try-On V2 — Personal shopper
- Photo utilisateur : plein corps si possible (le matcher exploite la morphologie), face caméra, bonne luminosité, ≥ 600 × 800 px
- Timeout client : prévoyez 180 s — le pipeline complet (analyse + matching + génération) est plus long que V1
- Catalogue Looks : visez 20+ Looks publiés pour un matching pertinent ; couvrez plusieurs catégories pour ne pas avoir de bruit dans les recommandations
- Filtres : n'utilisez
category_id/collection_idque si vous avez une intention claire (page collection, contexte saisonnier) — sinon laissez l'IA choisir parmi tous les Looks - Affichage côté front : exploitez
selected_look.reasontel quel pour créer un effet « personal shopper » authentique ; affichez lesalternativessous l'image principale pour augmenter le panier moyen - Conversion : les
selected_look.products[].product_urlsont vos boutons « Acheter cette pièce » ; trackez les clics pour mesurer le taux de transformation par Look
Commun aux deux versions
- Conversions : appelez
POST /conversiondepuis un hook de confirmation de commande, avec un timeout court etignore_errors: truepour ne pas bloquer la boutique - Stockage : sauvegardez
result_url/tryon.image_urlen base de données — les fichiers sont conservés 4 minutes puis supprimés directement (sauf la génération d'un essayage partagée par l'utilisateur) - Quota : vérifiez
GET /quotaavant un batch pour anticiper les erreurs 429 ; V1 et V2 consomment 1 crédit par appel - Retry : en cas d'erreur 500, attendez 5 s avant de réessayer (max 3 tentatives) — aucun crédit n'est débité tant qu'aucune réponse 200 n'a été retournée
Des questions ? support@cabine.ai
Créer un compte gratuit →