API Cabine.ai · v1 & v2
Documentation API
Offrez à vos clients un styliste et une cabine d'essayage, sur n'importe quelle plateforme : site sur mesure, WooCommerce, Magento, application mobile… Cette API donne accès aux mêmes services que nos modules Shopify et PrestaShop.
URL de base : https://cabine.ai/api · Format : JSON (UTF-8) · Toutes les requêtes en HTTPS.
Démarrage rapide
- Créez une clé API dans votre espace : Compte › Clés API. Elle commence par
vf_live_(production) ouvf_test_(tests : aucun crédit consommé, résultats d'exemple). - Vérifiez votre accès en consultant votre solde de crédits :
curl https://cabine.ai/api/v1/quota \
-H "X-Api-Key: vf_test_xxxxxxxxxxxx"
- Lancez un premier essayage avec une photo produit et une photo de personne :
curl -X POST https://cabine.ai/api/v1/generate \
-H "X-Api-Key: vf_test_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"product_image_url": "https://maboutique.com/img/robe-lin.jpg",
"user_photo_url": "https://maboutique.com/uploads/client.jpg",
"product_name": "Robe en lin écru",
"product_id": 42
}'
La réponse contient result_url : l'image de votre client portant la robe. Vous avez votre premier essayage.
Authentification
Chaque requête porte votre clé dans l'en-tête X-Api-Key (ou Authorization: Bearer …).
Architecture recommandée
C'est l'architecture de nos modules officiels. Elle garde la clé secrète, vous permet d'appliquer vos propres règles (quotas par client, contrôle anti-abus) et de relier les essayages à vos paniers.
- Créez sur votre serveur une route par action (essayer, ouvrir le miroir, recommander, importer…) qui appelle l'API avec votre clé et renvoie la réponse au navigateur.
- Protégez ces routes : jeton CSRF de votre plateforme, limite de requêtes par visiteur (par exemple 10 recommandations par 10 minutes).
- Transmettez à Cabine.ai les identifiants utiles au suivi :
product_id,cart_id,customer_id.
Crédits et limites
| Action | Coût | Remarque |
|---|---|---|
| Essayage photo HD | 1 crédit | Produit seul ou look du Personal Shopper. |
| Miroir vivant | 2 crédits / 20 s | Débités à l'ouverture, rendus automatiquement si le miroir ne démarre pas. Forfaits payants. |
| Recommandation | gratuite | Personal Shopper inclus dans votre forfait (nombre de looks selon l'offre). |
| Import de catalogue | gratuit | Compte dans le nombre de looks inclus dans votre forfait. |
| Conversion, solde, statut | gratuit | — |
Les clés vf_test_ ne consomment aucun crédit. Les crédits se renouvellent à chaque échéance de votre forfait ; consultez-les avec GET /v1/quota.
Essayage photo HD
Votre client fournit une photo de lui ; vous fournissez la photo du produit. Cabine.ai compose une photo haute définition de votre client portant la pièce, en respectant sa silhouette et sa carnation.
Paramètres
Chaque image accepte trois formats : URL publique (*_url), base64 (*_b64, avec ou sans préfixe data:) ou fichier en multipart/form-data.
| Champ | Type | Description |
|---|---|---|
| product_image_url · _b64 · product_image | image | requis Photo du produit (de préférence la pièce seule ou portée de face). JPEG, PNG ou WebP. |
| user_photo_url · _b64 · user_photo | image | requis Photo du client, de face, en pied ou à mi-corps. |
| product_name | string | Nom complet du produit. Améliore la fidélité du rendu. |
| category | string | Catégorie libre (« robe courte », « blazer »…). Active les réglages de rendu définis pour cette catégorie dans votre espace. |
| prompt_type | string | mirror (rendu réaliste, défaut), universe (mise en scène éditoriale) ou thematic (mise en scène thématique, collections enfant). |
| model | string | auto (défaut) : le meilleur rendu inclus dans votre forfait, choisi et mis à jour par Cabine.ai. |
| product_id | int | Identifiant du produit chez vous. Recommandé pour la mesure des conversions. |
| cart_id | int | Identifiant du panier. Recommandé : relie l'essayage à la commande. |
| customer_id | int | Identifiant du client (optionnel). |
Réponse
{
"success": true,
"result_url": "https://cabine.ai/generation/a3f8…b2/download",
"generation_id": 1042,
"credits_used": 1,
"credits_remaining": 163,
"processing_time_ms": 21400
}
result_url est accessible sans authentification grâce à un jeton de 64 caractères, pendant une durée limitée : téléchargez l'image sur votre serveur si vous devez la conserver. Comptez 15 à 40 secondes de traitement : prévoyez un délai d'attente de 180 s côté serveur.Suivre un essayage
Statut d'un essayage (pending, completed, error) et, s'il est terminé, son result_url. Utile si votre requête a expiré avant la fin du traitement : interrogez toutes les 3 secondes, 2 minutes au maximum.
Partager un essayage
Crée une page de partage publique de l'essayage (réseaux sociaux, messagerie), à proposer à votre client sur l'écran de résultat.
Consulter son solde
{
"success": true,
"plan": "Boutique", "plan_slug": "boutique",
"credits_total": 700, "credits_used": 137, "credits_bonus": 0,
"credits_remaining": 563, "usage_percent": 20, "renews_at": "2026-11-01"
}
Miroir vivant
Via sa webcam, votre client se voit porter la pièce en temps réel : il tourne, s'avance, recule. La session dure 20 secondes et coûte 2 crédits. Le meilleur usage, celui de nos modules : afficher le miroir pendant la préparation de la photo HD, que votre client découvre à la fin (voir la recette).
Le flux vidéo circule directement entre le navigateur et le service temps réel de Cabine.ai ; votre serveur ouvre la session et en suit le déroulement. Côté navigateur, utilisez le SDK Cabine Live :
<!-- Module ES, à charger à la demande -->
const { CabineLive } = await import('https://cabine.ai/sdk/live/v1/cabine-live.js');
| Méthode | Rôle |
|---|---|
| new CabineLive({ video, api }) | video : élément <video> d'affichage. api : { liveStarted(url), liveEnded(url, reason, durationMs) }, appelés par le SDK pour prévenir votre serveur. |
| prepare({ token, stream, referenceUrl, referenceUrls, prompt, onEnded }) | Connecte la session. token : la réponse d'ouverture de session (voir ci-dessous), complétée par vos URL de suivi. stream : flux webcam (getUserMedia). referenceUrl : photo du produit ; referenceUrls : autres photos de repli. Renvoie true quand le miroir est prêt. |
| reveal({ onTick }) | Affiche le miroir et lance le décompte (onTick(secondesRestantes)). |
| stop(reason) | Arrête la session (user, leave, completed). |
Ouvrir une session
| Champ | Type | Description |
|---|---|---|
| origin | string | requis Origine de votre boutique, telle que vue par le navigateur (https://www.maboutique.com). La session n'est utilisable que depuis cette origine. |
| channel | string | woocommerce, prestashop ou api (défaut). |
| product_id · product_name | string | Produit essayé (statistiques). |
| customer_id | int | Client connecté (plafonds par client). |
| client_key | string | Identifiant de session du visiteur anonyme (plafonds par visiteur ; haché par Cabine.ai). |
| client_ip | string | Adresse IP du visiteur (protection anti-abus). |
{
"success": true,
"session_id": 8812,
"duration_s": 20,
"credits": 2,
"connect_timeout_s": 20,
"expiresAt": "2026-10-07T09:41:12Z",
"session": "cl1.GEAFD1ZLEw5yGlgVBzFM…"
}
session est un jeton opaque réservé au SDK Cabine Live : ne l'interprétez pas, ne le stockez pas (il expire en quelques minutes). Renvoyez l'objet tel quel au navigateur, en y ajoutant deux URL de votre serveur : started_url et ended_url. Le SDK les appelle au démarrage et à la fin du miroir ; votre serveur relaie alors vers les routes de suivi ci-dessous.
Suivi de session
Le miroir s'est affiché : les crédits sont acquis.
Corps : { "reason": "completed|user|leave|failed", "duration_ms": 20140 }. Si le miroir n'a jamais démarré, la réponse indique "credits_refunded": 2. Le SDK peut l'envoyer en text/plain (sendBeacon) quand l'onglet se ferme : acceptez ce format sur votre serveur.
Personal Shopper
À partir d'une photo et de quelques réponses (style, budget, type de pièce), Cabine.ai lit la colorimétrie, la silhouette et la corpulence de votre client, puis classe les looks de votre catalogue selon leur compatibilité avec lui. Vos looks et vos questions se gèrent dans votre espace (Personal Shopper) ou s'alimentent par l'import de catalogue.
- Configuration : vérifiez la disponibilité et récupérez les questions à poser.
- Recommandation (gratuite) : envoyez la photo et les réponses ; recevez le look n° 1, les alternatives classées, la raison du choix et un
selection_idvalable 15 minutes. - Essayage (1 crédit) : générez la photo HD de n'importe quel look de la recommandation. Nos modules le font automatiquement pour le look n° 1 : votre client se découvre directement dans le look.
Configuration
{
"success": true,
"enabled": true, // inclus dans le forfait ET au moins un look publié
"tryon_enabled": true, // crédits disponibles pour l'essayage
"published_looks": 124,
"questions": [
{ "id": 3, "label": "Quel style vous ressemble ?", "type": "intent",
"answers": [ { "id": 11, "label": "Chic intemporel" }, { "id": 12, "label": "Casual" } ] },
{ "id": 4, "label": "Votre budget pour ce look ?", "type": "budget", "answers": [ … ] }
]
}
Mettez cette réponse en cache 5 minutes sur votre serveur : elle change rarement. N'affichez le Personal Shopper que si enabled vaut true.
Recommandation
| Champ | Type | Description |
|---|---|---|
| user_photo_b64 | string | requis Photo du client (JPEG, PNG ou WebP, 8 Ko à 8 Mo). |
| answer_ids | int[] | Identifiants des réponses choisies (une par question, questions passées omises). |
| channel | string | woocommerce, prestashop ou api : apparaît dans votre historique des recommandations. |
{
"success": true,
"selected_look": {
"id": 57, "name": "Blouse rouille & jupe midi", "image_url": "https://…",
"match_score": 0.94, "styling_advice": "Le rouille près du visage réchauffe votre teint.",
"total_price": 158.0, "currency": "EUR",
"products": [ { "name": "Blouse col V", "price": 69, "product_url": "https://…", "image_url": "https://…" } ]
},
"alternatives": [ { "id": 61, "name": "Robe vert forêt", "match_score": 0.88, … } ],
"why": {
"profile": ["Automne profond", "Silhouette en A"],
"reasons": [ { "label": "Harmonie colorimétrique", "text": "…" } ]
},
"selection_id": "sel_4f0c…",
"selection_ttl": 900,
"tryon_enabled": true
}
why explique le choix à votre client : affichez-le sous le look n° 1 (« Pourquoi ce look vous va »). La photo n'est pas conservée après l'analyse.
Essayer un look
Corps : { "selection_id": "sel_…", "look_id": 61 }. Sans look_id, le look n° 1 est essayé. La sélection reste utilisable pour essayer d'autres looks pendant sa durée de validité.
{ "success": true, "generation_id": 2210,
"tryon": { "status": "completed", "image_url": "https://…" } }
Si tryon.status vaut pending, suivez l'essayage avec la route suivante.
Suivre l'essayage
Réponse : { "status": "pending" | "completed" | "error", "image_url": … }. Interrogez toutes les 3 secondes, 150 secondes au maximum.
Importer des produits
Envoyez vos produits depuis votre base : Cabine.ai télécharge leurs photos en pleine définition et caractérise chaque vêtement (saisons colorimétriques, morphologies et corpulences qu'il flatte, style, occasion). Chaque produit devient un look du Personal Shopper.
| Champ | Type | Description |
|---|---|---|
| products[] | object[] | requis Voir le détail ci-dessous. |
| source | string | woocommerce, prestashop ou api. |
| auto_publish | bool | Publier les looks sans relecture (sinon : brouillons, à valider dans votre espace). |
| target_gender | string | female, male, unisex ; absent : détecté automatiquement. |
| products[].champ | Type | Description |
|---|---|---|
| url | string | requis Lien de la fiche produit (ou de la déclinaison de couleur). Sert aussi à éviter les doublons. |
| name | string | requis Nom du produit (ajoutez la couleur pour une déclinaison). |
| images[] | string[] | requis 1 à 4 URL de photos en pleine définition, accessibles depuis Internet. |
| price · currency | number · string | Prix TTC et devise ISO (EUR). |
| category_raw · brand | string | Catégorie et marque, telles que dans votre catalogue. |
| description | string | Description courte (600 caractères max.). |
| external_id | string | Votre identifiant (par exemple woo:812:3341). |
{ "success": true, "batch_id": 318, "looks": 24,
"follow_url": "https://cabine.fit/account/personal-shopper/import/318" }
La caractérisation prend 15 à 30 secondes par produit. Suivez l'avancement avec GET /api/v2/looks/import/{batch_id} ou dans votre espace. Un seul import peut être en cours à la fois.
Conversions
À appeler quand une commande est payée, une fois par produit. Cabine.ai la relie à l'essayage d'origine grâce au cart_id et au product_id transmis lors de l'essayage, et alimente vos statistiques de conversion. Un second appel avec le même order_id ne crée pas de doublon.
| Champ | Type | Description |
|---|---|---|
| order_id | string | requis Référence de la commande. |
| product_id · cart_id | int | Recommandés : clés de rapprochement avec l'essayage. |
| customer_id | int | Optionnel. |
| metadata | object | Libre : montant, devise, SKU… |
Recette · Bouton « Essayer » sur la fiche produit
- Un bouton ouvre une fenêtre ; le client choisit une photo produit et importe sa photo.
- Le navigateur redresse et réduit la photo (2 048 px, JPEG) puis l'envoie à votre serveur.
- Votre serveur appelle
/v1/generateavec la photo, l'image produit et vos identifiants (product_id,cart_id). - Affichez le résultat avec la mention « Généré par IA », un bouton « Ajouter au panier » et le partage.
<?php // Votre route serveur — exemple PHP générique
$payload = [
'user_photo_b64' => $_POST['photo'], // envoyé par votre page
'product_image_url' => $product->getImageUrl('large'), // votre catalogue
'product_name' => $product->getName(),
'product_id' => $product->getId(),
'cart_id' => $cart->getId(),
];
$ch = curl_init('https://cabine.ai/api/v1/generate');
curl_setopt_array($ch, [
CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 180,
CURLOPT_HTTPHEADER => ['X-Api-Key: ' . getenv('CABINE_API_KEY'), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$response = json_decode(curl_exec($ch), true);
header('Content-Type: application/json');
echo json_encode(['ok' => $response['success'] ?? false, 'image' => $response['result_url'] ?? null]);
Recette · Miroir vivant puis photo HD
L'expérience de nos modules : le miroir occupe les 20 secondes de préparation de la photo HD.
- Le client importe sa photo et lance l'essayage : votre page appelle votre route « essayage HD » et, en parallèle, votre route « ouvrir le miroir ».
- Votre serveur ouvre la session (
/v2/live/session) et renvoie l'objet au navigateur, avec vosstarted_url/ended_url. - Le navigateur active la webcam, prépare le SDK, puis révèle le miroir avec son décompte.
- À la fin du miroir (ou sur « Passer »), affichez la photo HD, prête entre-temps.
// Navigateur
const stream = await navigator.mediaDevices.getUserMedia({ video: { facingMode: 'user' }, audio: false });
const session = await fetch('/cabine/live-open', { method: 'POST', body: formData }).then(r => r.json());
const { CabineLive } = await import('https://cabine.ai/sdk/live/v1/cabine-live.js');
const live = new CabineLive({
video: document.querySelector('#mirror'),
api: {
liveStarted: (url) => fetch(url, { method: 'POST', keepalive: true }),
liveEnded: (url, reason, ms) => navigator.sendBeacon(url, JSON.stringify({ reason, duration_ms: ms })),
},
});
const ready = await live.prepare({
token: session, // réponse de votre serveur (+ started_url / ended_url)
stream,
referenceUrl: product.images[0], // photo du produit
referenceUrls: product.images.slice(1),
prompt: 'Dress the person in the garment shown: ' + product.name,
onEnded: () => showHdResultWhenReady(),
});
if (ready) live.reveal({ onTick: (s) => countdown.textContent = s + ' s' });
else showHdResultWhenReady(); // miroir indisponible : crédits rendus, on passe à la photo HD
Recette · Bulle Personal Shopper
- Au chargement de vos pages, votre serveur lit
/v2/stylist/config(en cache) et n'affiche la bulle que sienabled. - Fenêtre : photo du client, puis questions une par une, chacune pouvant être passée.
- Votre serveur appelle
/v2/stylist/match(limitez à 10 demandes par visiteur et par 10 minutes). - Affichez le look n° 1 avec son conseil et le bloc « Pourquoi ce look vous va » (
why), puis les alternatives. - Recommandé : lancez aussitôt
/v2/stylist/tryonpour le look n° 1. Affichez la photo du client avec « Nous vous habillons… », puis remplacez-la par le résultat : votre client se découvre dans le look. Les alternatives gardent leurs photos produit et un bouton « L'essayer sur moi ». - Pour chaque pièce de votre boutique : « Ajouter » (votre panier) et « Essayer » (votre fiche produit, cabine ouverte).
Recette · Synchroniser le catalogue
- Dans votre administration, proposez des filtres (catégorie, couleur, recherche) et une sélection de 50 produits au plus.
- Pour chaque produit, construisez l'objet attendu : lien, nom, prix TTC, devise, catégorie, marque, description courte et photos d'origine.
- Envoyez le lot à
/v2/looks/importet affichez le lien de suivi.
// Exemple WooCommerce (PHP) — un produit par couleur
$products = [];
foreach ($selectedIds as $id) {
$p = wc_get_product($id);
$images = array_filter(array_map('wp_get_attachment_url',
array_merge([$p->get_image_id()], $p->get_gallery_image_ids())));
$products[] = [
'url' => get_permalink($id),
'name' => $p->get_name(),
'price' => (float) wc_get_price_including_tax($p),
'currency' => get_woocommerce_currency(),
'category_raw' => wp_strip_all_tags(wc_get_product_category_list($id)),
'description' => wp_strip_all_tags($p->get_short_description()),
'external_id' => 'woo:' . $id,
'images' => array_slice(array_values($images), 0, 4),
];
}
$res = wp_remote_post('https://cabine.ai/api/v2/looks/import', [
'headers' => ['X-Api-Key' => CABINE_API_KEY, 'Content-Type' => 'application/json'],
'body' => wp_json_encode(['source' => 'woocommerce', 'products' => $products]),
'timeout' => 60,
]);
Erreurs
Toute erreur suit le même format : { "success": false, "error": "code", "message": "Description lisible" }. Affichez un message adapté à votre client à partir du code, jamais le message brut.
| HTTP · code | Signification | Que faire |
|---|---|---|
| 400 invalid_json | Corps illisible. | Vérifiez l'encodage JSON. |
| 401 authentication_error | Clé absente, invalide ou révoquée. | Vérifiez la clé côté serveur. |
| 402 no_active_subscription | Aucun forfait actif. | Choisissez un forfait. |
| 403 stylist_disabled | Personal Shopper non inclus dans le forfait. | Masquez la bulle. |
| 403 live_requires_paid_plan | Miroir réservé aux forfaits payants. | Proposez la photo HD seule. |
| 404 no_looks_available | Aucun look publié. | Publiez ou importez des looks. |
| 404 selection_not_found | Sélection expirée (15 min). | Relancez une recommandation. |
| 422 invalid_param · invalid_photo | Paramètre ou photo invalide. | Indiquez au client de reprendre sa photo. |
| 429 quota_exceeded | Crédits épuisés. | Masquez l'essayage, rechargez des crédits. |
| 429 quota_anonymous · quota_customer | Plafond de miroirs atteint pour ce visiteur ou ce client. | Proposez la photo HD seule. |
| 429 rate_limited | Trop de demandes rapprochées. | Patientez quelques secondes. |
| 503 live_disabled · token_failed | Miroir momentanément indisponible. | Passez directement à la photo HD. |
| 502 profile_analysis_failed | Photo inexploitable pour l'analyse. | Demandez une photo de face, bien éclairée. |
| 502 · 500 generation_failed | Essayage impossible. | Aucun crédit débité ; proposez de réessayer. |
Bonnes pratiques
Photos
- Redressez la photo avant l'envoi. Les photos prises au téléphone sont souvent enregistrées « couchées » avec une simple indication d'orientation : redessinez-les dans le bon sens (par exemple
createImageBitmap(file, { imageOrientation: 'from-image' })puis un canvas), au format JPEG, 2 048 px au plus. - Photo produit : la meilleure définition disponible, la pièce bien visible, sans texte incrusté.
- Photo client : de face, en pied ou à mi-corps, bonne lumière, fond simple.
Fiabilité
- Délais d'attente serveur : 180 s pour un essayage, 100 s pour une recommandation, 60 s pour un import.
- En cas d'expiration, suivez l'essayage par sa route de statut plutôt que de le relancer : vous éviterez un double débit.
- Mettez en cache la configuration du Personal Shopper (5 minutes).
Sécurité
- Clé API uniquement côté serveur, dans une variable d'environnement.
- Jeton CSRF et limite de requêtes sur chacune de vos routes.
- Ne transmettez jamais de données sans rapport avec l'essayage (adresse, paiement…).
Données personnelles
- La photo du client sert à l'analyse et à l'essayage ; elle n'est pas conservée pour la recommandation, et les résultats d'essayage ne restent accessibles que pendant une durée limitée.
- L'historique des recommandations (looks proposés, réponses, explication) est conservé 90 jours, sans photo.
- Chaque essayage affiché doit porter une mention indiquant qu'il est généré par intelligence artificielle et peut différer légèrement du vêtement réel.
- Informez vos clients dans votre politique de confidentialité ; un modèle de clause est disponible sur demande.
Historique
| Date | Nouveautés |
|---|---|
| 2026-10-07 | Jeton de session opaque pour le miroir (session) ; moteur de rendu auto ; import de catalogue (/v2/looks/import) ; explication why dans la recommandation ; historique des recommandations par canal. |
| 2026-10-06 | Miroir vivant (/v2/live/*) et SDK Cabine Live ; Personal Shopper (/v2/stylist/*). |
| 2026-08 | Rendus par catégorie (category, prompt_type) ; conversions. |