Introduction
PrimeStyle Virtual Try-On lets shoppers see themselves wearing any product — directly on your website. Our AI generates photorealistic results in 15-20 seconds, plus AI-powered size recommendations. Three ways to integrate:
REST API
Full control. Virtual try-on, AI sizing, and size guide extraction endpoints. Build your own UI, handle the flow however you want.
React SDK
Ship in minutes. Drop-in React component with try-on and sizing built in. Auto-extracts product images — no backend work needed.
Shopify App
No code required. Install from the Shopify App Store and get try-on + AI sizing on all product pages automatically.
How it works — API Mode
How it works — SDK / Shopify App
Sizing API endpoints
In addition to virtual try-on, the API includes AI-powered sizing:
POST /v1/sizing/sizeguide—Extract size chart from product dataPOST /v1/sizing/recommend—Get AI size recommendation from measurementsQuick Start
Get your first virtual try-on result in under 5 minutes.
Get your API key
Sign up at myaifitting.com and grab your API key from the Developer Dashboard.
Submit a try-on request
Send the customer's photo as modelImage and the product image as garmentImage. The API returns immediately with a jobId while processing happens in the background.
curl -X POST https://myaifitting.com/api/v1/tryon \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "modelImage": "https://example.com/customer-photo.jpg", "garmentImage": "https://your-store.com/products/blue-shirt.jpg" }'Get the result
Option A — SSE stream (recommended): Open an SSE connection and listen for vto-update events. You get the result instantly when it's ready.
// Recommended: Use SSE instead of polling (faster)const eventSource = new EventSource( "https://myaifitting.com/api/v1/tryon/stream?key=YOUR_API_KEY");eventSource.addEventListener("vto-update", (e) => { const data = JSON.parse(e.data); if (data.jobId === myJobId) { if (data.status === "completed") { console.log("Result:", data.imageUrl); eventSource.close(); } if (data.status === "failed") { console.error("Error:", data.error); eventSource.close(); } }});Option B — Polling: If you can't use SSE, poll the status endpoint every 2 seconds until status is "completed".
// Poll for resultlet result;while (true) { const res = await fetch( `https://myaifitting.com/api/v1/tryon/status/${jobId}`, { headers: { "Authorization": "Bearer YOUR_API_KEY" } } ); result = await res.json(); if (result.status === "completed") { console.log("Result image:", result.imageUrl); break; } if (result.status === "failed") { console.error("Failed:", result.message); break; } // Wait 3 seconds before polling again await new Promise(r => setTimeout(r, 3000));}Completed Status Response
{ "jobId": "67b3a1f2e4b0c8d9a1234567", "status": "completed", "imageUrl": "https://res.cloudinary.com/.../result/abc123.png", "message": "Completed"}Authentication
Every API request must be authenticated. Include your API key in the Authorization header as a Bearer credential.
API Keys
Get your API key from the Developer Dashboard. Your key is scoped to your account and controls billing.
Authorization: Bearer YOUR_API_KEYImportant: Never expose your API key in client-side code. Always call the API from your server. For client-side integration, use the Drop-in SDK which handles authentication securely.
Try-On Balance
Each successful virtual try-on counts as one try-on from your account balance. If you don't have enough try-ons remaining, the API returns a 402 with your current balance. Failed try-ons are not counted.
// 402 Insufficient balance response{ "error": "INSUFFICIENT_BALANCE", "message": "Not enough try-ons remaining. Balance: 0", "required": 1, "currentBalance": 0}API Reference
Base URL: https://myaifitting.com/api
All endpoints require authentication. The try-on API is asynchronous — you submit a job and receive the result image via SSE stream or polling. We do not store your customer photos or garment images — only the generated result is returned.
Create Try-On Job
/v1/tryonAuth requiredSubmit a virtual try-on job. Send the customer's photo and a garment image — that's it. Returns immediately with a jobId (202 Accepted). Processing takes 15-20 seconds in the background. Use SSE or polling to get the result.
Request Body
| Name | Type | Description |
|---|---|---|
modelImage | string | URL or base64 data URI of the customer's photo. |
garmentImage | string | URL or base64 data URI of the garment/product image. |
Example Request
curl -X POST https://myaifitting.com/api/v1/tryon \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "modelImage": "https://example.com/customer-photo.jpg", "garmentImage": "https://your-store.com/products/blue-shirt.jpg" }'Response 202
{ "jobId": "67b3a1f2e4b0c8d9a1234567", "status": "processing", "tryOnsUsed": 1, "newBalance": 49}Get Try-On Status
/v1/tryon/status/:jobIdAuth requiredCheck the status of a try-on job. Poll this endpoint every 3 seconds until status is 'completed' or 'failed'. For real-time results, use the SSE stream instead (recommended).
Path Parameters
| Name | Type | Description |
|---|---|---|
jobId | string | The job ID returned from POST /v1/tryon |
Example Request
curl https://myaifitting.com/api/v1/tryon/status/67b3a1f2e4b0c8d9a1234567 \ -H "Authorization: Bearer YOUR_API_KEY"Response 200
// While processing:{ "jobId": "67b3a1f2e4b0c8d9a1234567", "status": "processing", "imageUrl": null, "message": "Processing..."}// When completed:{ "jobId": "67b3a1f2e4b0c8d9a1234567", "status": "completed", "imageUrl": "https://res.cloudinary.com/.../result/abc123.png", "message": "Completed"}// On failure (the try-on is not counted):{ "jobId": "67b3a1f2e4b0c8d9a1234567", "status": "failed", "imageUrl": null, "message": "Failed: Safety filter blocked the image"}Real-time Stream (SSE)
/v1/tryon/stream?key=YOUR_API_KEYAuth requiredOpen a persistent SSE connection to receive real-time try-on results. This is the recommended way to get results — faster than polling and you get the result image the instant it's ready. Pass your API key as a query parameter since EventSource can't set headers.
Example Request
// Open SSE connection (pass key as query param)const eventSource = new EventSource( "https://myaifitting.com/api/v1/tryon/stream?key=YOUR_API_KEY");// Listen for try-on resultseventSource.addEventListener("vto-update", (e) => { const data = JSON.parse(e.data); const { jobId, status, imageUrl, error } = data; if (status === "completed") { // Display the result image showResultImage(imageUrl); eventSource.close(); } if (status === "failed") { showError(error); // Failed try-ons are not counted eventSource.close(); }});eventSource.onerror = () => eventSource.close();Response 200
// SSE event format:event: vto-updatedata: {"jobId":"67b3a1...","status":"completed","imageUrl":"data:image/png;base64,...","error":null,"timestamp":1740067200000}Privacy: We do not store your customer photos or garment images. Images are processed in memory and only the generated result is returned. Failed try-ons are not counted against your balance.
Upload Image
/v1/tryon/uploadAuth requiredUpload a customer photo and get back a hosted URL. Use this if you need to convert a file upload into a URL before calling the try-on endpoint. Max file size: 50MB.
Example Request
const formData = new FormData();formData.append("file", customerPhotoFile);const res = await fetch("https://myaifitting.com/api/v1/tryon/upload", { method: "POST", headers: { "Authorization": "Bearer YOUR_API_KEY" }, body: formData,});const { url } = await res.json();// Use this URL as modelImage in your try-on requestResponse 200
{ "url": "https://res.cloudinary.com/.../tryon-uploads/abc123.jpg"}AI Size Recommendation
/v1/sizing/recommendAuth requiredGet an AI-powered size recommendation for a customer. Send the customer's body measurements (or height/weight for a quick estimate) along with product details and an optional size guide. Returns the recommended size, confidence level, international size conversions, and detailed measurement match analysis.
Request Body
| Name | Type | Description |
|---|---|---|
method | "exact" | "quick" | Use "exact" for body measurements, "quick" for height/weight estimate. |
measurements | object | Required when method is "exact". Customer body measurements in cm. |
measurements.gender | "male" | "female" | "unisex" | Customer gender for sizing context. |
measurements.chest | number | Chest circumference in cm. |
measurements.bust | number | Bust circumference in cm. |
measurements.waist | number | Waist circumference in cm. |
measurements.hips | number | Hip circumference in cm. |
measurements.shoulderWidth | number | Shoulder width in cm. |
measurements.sleeveLength | number | Sleeve length in cm. |
measurements.inseam | number | Inseam length in cm. |
measurements.footLengthCm | number | Foot length in cm (for shoes). |
quickEstimate | object | Required when method is "quick". |
quickEstimate.heightCm | number | Height in cm (100-250). |
quickEstimate.weightKg | number | Weight in kg (30-300). |
quickEstimate.gender | "male" | "female" | "unisex" | Customer gender. |
product | object | Product details for sizing context. |
product.title | string | Product title. |
product.vendor | string | Brand name. |
product.productType | string | Product type (e.g. "T-Shirt", "Jeans"). |
product.variants | array | Available product variants with size info. |
sizeGuide | object | Size guide data (from /v1/sizing/sizeguide or your own). Dramatically improves accuracy. |
sizeGuide.headers | string[] | Column headers, e.g. ["Size", "Chest (cm)", "Waist (cm)"]. |
sizeGuide.rows | string[][] | Row data matching headers, e.g. [["M", "94-100", "78-84"]]. |
locale | string | Customer region code (e.g. "US", "EU") to prioritize sizing format. |
Example Request
curl -X POST https://myaifitting.com/api/v1/sizing/recommend \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "method": "exact", "measurements": { "gender": "male", "chest": 104, "waist": 84, "hips": 96, "shoulderWidth": 46 }, "product": { "title": "Classic Fit Oxford Shirt", "vendor": "Brand Name", "productType": "Shirt", "variants": [ { "title": "S", "option1": "S" }, { "title": "M", "option1": "M" }, { "title": "L", "option1": "L" }, { "title": "XL", "option1": "XL" } ] }, "sizeGuide": { "headers": ["Size", "Chest (cm)", "Waist (cm)", "Hips (cm)"], "rows": [ ["S", "88-94", "76-82", "90-96"], ["M", "94-100", "82-88", "96-102"], ["L", "100-106", "88-94", "102-108"], ["XL", "106-112", "94-100", "108-114"] ] }, "locale": "US" }'Response 200
{ "recommendedSize": "L", "recommendedLength": null, "confidence": "high", "reasoning": "Your chest of 104cm falls within the L range of 100-106cm in the size guide. Waist of 84cm fits the M range (82-88cm) but L (88-94cm) provides a comfortable fit overall.", "internationalSizes": { "US": "L", "UK": "L" }, "matchDetails": [ { "measurement": "Chest", "userValue": "104 cm", "chartRange": "100-106 cm", "fit": "good" }, { "measurement": "Waist", "userValue": "84 cm", "chartRange": "88-94 cm", "fit": "loose" }, { "measurement": "Hips", "userValue": "96 cm", "chartRange": "102-108 cm", "fit": "tight" }, { "measurement": "Shoulders", "userValue": "46 cm", "chartRange": "44-47 cm", "fit": "good" } ]}Pro tip: Pass a sizeGuide for dramatically better results. Use the /v1/sizing/sizeguide endpoint below to auto-extract it from a product page, or provide your own structured size chart data.
Which measurements should I send?
Men's — Tops / Shirts / Jackets
{
"method": "exact",
"measurements": {
"gender": "male",
"chest": 104,
"waist": 84,
"shoulderWidth": 46,
"sleeveLength": 65,
"neckCircumference": 40
},
"product": {
"title": "Your Product Name",
"variants": [
{
"title": "S"
},
{
"title": "M"
},
{
"title": "L"
}
]
}
}Extract Size Guide
/v1/sizing/sizeguideAuth requiredAI-powered size guide extraction. Send product details (description, metafields, images) and the AI extracts the size chart if one exists. Supports size charts in HTML tables, plain text, images (vision), metafields, and third-party size guide apps. Returns structured data you can pass directly to /v1/sizing/recommend.
Request Body
| Name | Type | Description |
|---|---|---|
product | object | Product details to search for size chart data. |
product.title | string | Product title. |
product.description | string | Product description HTML — often contains size charts in tables. |
product.vendor | string | Brand name. |
product.productType | string | Product type. |
product.variants | array | Product variants (helps identify available sizes). |
product.options | array | Product options (e.g. Size, Color). |
product.metafields | array | Product metafields — may contain size chart data or references. |
domHtml | string | HTML extracted from the product page DOM (e.g. from a third-party size guide modal). |
domImages | string[] | Image URLs found in size guide modals/sections on the page. |
sizeGuideRaw | any | Raw size guide data in any format (JSON, HTML, text). The AI parses it into structured format. |
Example Request
curl -X POST https://myaifitting.com/api/v1/sizing/sizeguide \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "product": { "title": "Classic Fit Oxford Shirt", "vendor": "Brand Name", "description": "<table><tr><th>Size</th><th>Chest</th></tr><tr><td>M</td><td>94-100cm</td></tr></table>" } }'Response 200
// Size guide found:{ "found": true, "title": "Size Guide", "headers": ["Size", "Chest (cm)", "Waist (cm)", "Hips (cm)"], "rows": [ ["S", "86-91", "71-76", "86-91"], ["M", "91-97", "76-81", "91-97"], ["L", "97-102", "81-86", "97-102"], ["XL", "102-107", "86-91", "102-107"] ], "source": "extracted"}// No size guide found:{ "found": false}Flexible input. You can pass size guide data in any format — HTML tables in the product description, JSON from metafields, raw text, or even images of size charts. The AI extracts and structures it for you. Pass the result directly as the sizeGuide field in /v1/sizing/recommend.
Error Codes
All errors return a JSON object with a message and a code field:
{ "error": "INSUFFICIENT_BALANCE", "message": "Not enough try-ons remaining. Balance: 0", "required": 1, "currentBalance": 0}| Code | HTTP | Description |
|---|---|---|
UNAUTHORIZED | 401 | Missing or invalid API key |
MODEL_IMAGE_REQUIRED | 400 | No model (customer) image provided |
GARMENT_IMAGE_REQUIRED | 400 | No garment image provided |
INSUFFICIENT_BALANCE | 402 | Not enough try-ons remaining. Response includes required and currentBalance |
JOB_NOT_FOUND | 404 | Job ID does not exist or doesn't belong to your account |
VALIDATION_ERROR | 400 | Request body failed validation (invalid URL format, etc.) |
PROCESSING_FAILED | 500 | Internal error during generation. Failed try-ons are not counted |
Failed try-ons are free: If a try-on job fails during generation, it is not counted against your balance. You are only charged for successful try-ons.
React SDK
Add virtual try-on to your React / Next.js app with a single component. No API key props, no backend work — just install, set an env variable, and use the component:
- •API key from env — reads
NEXT_PUBLIC_PRIMESTYLE_API_KEYautomatically - •Typed props — full TypeScript support with typed callbacks
- •Fully customizable — style with Tailwind classes, CSS, or
buttonStyles/modalStylesprops - •Handles photo upload, compression, loading states, SSE streaming, and result display
Installation
1. Install the package
npm install @primestyleai/tryon2. Add your API key to .env.local
NEXT_PUBLIC_PRIMESTYLE_API_KEY=ps_live_your_key_hereGet your key from the Developer Dashboard.
3. Use the component
import { PrimeStyleTryon } from '@primestyleai/tryon/react';function ProductPage({ product }) { return ( <div> <h1>{product.name}</h1> <PrimeStyleTryon productImage={product.image} buttonText="Try It On" onComplete={(result) => { console.log('Result:', result.imageUrl); }} /> </div> );}Component & Props
PrimeStyleTryon Props
| Name | Type | Description |
|---|---|---|
productImage | string | URL of the garment/product image to try on. Recommended — pass this explicitly for best results. If omitted, the SDK auto-detects the main product image on the page (via og:image, Schema.org JSON-LD, or common selectors like .product-image). |
buttonText | string | Text on the trigger button (default: "Virtual Try-On") |
apiUrl | string | Custom API URL. Defaults to NEXT_PUBLIC_PRIMESTYLE_API_URL env or production |
showPoweredBy | boolean | Show "Powered by PrimeStyle AI" in modal footer (default: true) |
showIcon | boolean | Show the default camera icon in the trigger button (default: true). Set to false to hide it. |
buttonIcon | React.ReactNode | Custom icon element to replace the default camera icon. Pass any React node (e.g. an <svg> or <img>). |
buttonStyles | ButtonStyles | Customize button appearance (see Customization below) |
modalStyles | ModalStyles | Customize modal appearance (see Customization below) |
classNames | PrimeStyleClassNames | Override element classes with Tailwind or custom CSS (see Customization below) |
className | string | Additional CSS class on the root wrapper |
style | CSSProperties | Inline styles on the root wrapper |
onOpen | () => void | Called when modal opens |
onClose | () => void | Called when modal closes |
onUpload | (file: File) => void | Called when user uploads a photo |
onProcessing | (jobId: string) => void | Called when try-on generation starts |
onComplete | (result) => void | Called when result is ready. result: { jobId, imageUrl } |
onError | (error) => void | Called on error. error: { message, code? } |
sizeGuideData | Record<string, Record<string, string>> | Size guide data keyed by size. e.g. { "M": { chest: "94cm", waist: "78cm" } }. Enables AI size recommendations in the modal. |
locale | string | BCP-47 locale tag for UI translations (e.g. "en", "ja", "pt-BR"). Auto-detects from browser if omitted. Supports 20 languages: English, Spanish, French, German, Italian, Swedish, Japanese, Czech, Danish, Dutch, Norwegian, Polish, Portuguese (BR & PT), Finnish, Turkish, Thai, Chinese (Simplified & Traditional), and Korean. |
No API key prop needed. The component reads NEXT_PUBLIC_PRIMESTYLE_API_KEY from your environment automatically.
Pass productImage explicitly. While the SDK can auto-detect the product image from your page (using og:image, Schema.org JSON-LD, or common CSS selectors), we recommend passing the productImage prop directly for the most reliable results.
Customization
Button Styles
Pass a buttonStyles object to customize the trigger button:
<PrimeStyleTryon productImage={product.image} buttonStyles={{ backgroundColor: '#000000', textColor: '#ffffff', borderRadius: '50px', padding: '16px 32px', fontSize: '16px', fontWeight: '700', width: '100%', border: '2px solid #333', hoverBackgroundColor: '#222', iconSize: '20px', iconColor: '#fff', boxShadow: '0 4px 12px rgba(0,0,0,0.3)', }}/>Modal Styles
Pass a modalStyles object to customize the try-on modal:
<PrimeStyleTryon productImage={product.image} modalStyles={{ backgroundColor: '#ffffff', textColor: '#111111', overlayColor: 'rgba(0,0,0,0.7)', borderRadius: '16px', maxWidth: '520px', fontFamily: '"Inter", sans-serif', headerBackgroundColor: '#f5f5f5', headerTextColor: '#111111', closeButtonColor: '#666', uploadBorderColor: '#dddddd', uploadBackgroundColor: '#fafafa', primaryButtonBackgroundColor: '#000000', primaryButtonTextColor: '#ffffff', primaryButtonBorderRadius: '50px', loaderColor: '#000000', resultBorderRadius: '16px', }}/>| ButtonStyles | ModalStyles |
|---|---|
backgroundColor | overlayColor |
textColor | backgroundColor |
borderRadius | textColor |
fontSize | borderRadius / width / maxWidth |
fontFamily / fontWeight | fontFamily |
padding | headerBackgroundColor / headerTextColor |
border | closeButtonColor |
width / height | uploadBorderColor / uploadBackgroundColor |
hoverBackgroundColor / hoverTextColor | uploadTextColor / uploadIconColor |
iconSize / iconColor | primaryButtonBackgroundColor / TextColor |
boxShadow | loaderColor / resultBorderRadius |
Button Icon
The trigger button shows a camera icon by default. You can hide it, or replace it with your own icon:
{/* Hide the icon — text only */}<PrimeStyleTryon productImage={product.image} showIcon={false} buttonText="Try It On"/>{/* Custom icon */}<PrimeStyleTryon productImage={product.image} buttonIcon={<img src="/my-icon.svg" alt="" style={{ width: 20, height: 20 }} />}/>{/* Custom SVG icon */}<PrimeStyleTryon productImage={product.image} buttonIcon={ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={2}> <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78L12 21.23l8.84-8.84a5.5 5.5 0 0 0 0-7.78z" /> </svg> }/>Tailwind CSS / Custom Classes
Use the classNames prop to style any element with Tailwind utilities or your own CSS classes. Classes are appended to the default ps-tryon-* classes:
<PrimeStyleTryon productImage={product.image} classNames={{ button: "bg-black text-white rounded-full px-8 py-4 hover:bg-gray-800", modal: "bg-white rounded-2xl shadow-2xl", header: "bg-gray-50 border-b border-gray-200", title: "text-gray-900 text-lg", submitButton: "bg-blue-600 text-white rounded-lg hover:bg-blue-700", uploadZone: "border-dashed border-gray-300 rounded-xl p-10", downloadButton: "bg-green-600 text-white rounded-lg", retryButton: "bg-gray-100 text-gray-700 border border-gray-300", }}/>Available classNames keys:
| Key | Element |
|---|---|
root | Root wrapper |
button | Trigger button |
overlay | Modal backdrop |
modal | Modal container |
header | Modal header |
title | Modal title |
closeButton | Close button |
body | Modal body |
uploadZone | Upload drop zone |
uploadText / uploadHint | Upload text & hint |
submitButton | Submit & retry button |
spinner | Loading spinner |
downloadButton / retryButton | Result action buttons |
error / errorText | Error container & text |
poweredBy | Footer attribution |
Normal CSS
All elements use ps-tryon-* class names that you can target directly in your stylesheet:
/* Override the trigger button */.ps-tryon-btn { background: #000; color: #fff; border-radius: 50px; padding: 16px 32px;}/* Override the modal */.ps-tryon-modal { background: #fff; color: #111;}/* Override the submit button */.ps-tryon-submit { background: #2563eb; color: #fff;}All three approaches can be combined. Priority: Tailwind/classNames > CSS variables (buttonStyles/modalStyles) > default styles.
Callbacks
Use typed callback props for analytics, custom behavior, or integration with your app:
<PrimeStyleTryon productImage={product.image} onOpen={() => { analytics.track('tryon_opened'); }} onUpload={(file) => { console.log('Photo uploaded:', file.name); }} onProcessing={(jobId) => { console.log('Processing:', jobId); }} onComplete={(result) => { console.log('Result:', result.imageUrl); analytics.track('tryon_completed', { jobId: result.jobId }); // Show success toast, trigger upsell, etc. }} onError={(error) => { console.error('Try-on failed:', error.message); // error.code: 'INSUFFICIENT_BALANCE' | 'API_ERROR' | etc. Sentry.captureMessage(error.message); }} onClose={() => { console.log('Modal closed'); }}/>| Callback | Arguments | Description |
|---|---|---|
onOpen | — | Modal opened |
onClose | — | Modal closed |
onUpload | file: File | Customer uploaded a photo |
onProcessing | jobId: string | Try-on generation started |
onComplete | { jobId, imageUrl } | Result image ready |
onError | { message, code? } | An error occurred |
Environment Variables
The component reads these environment variables automatically — no need to pass them as props:
| Variable | Required | Description |
|---|---|---|
NEXT_PUBLIC_PRIMESTYLE_API_KEY | Yes | Your PrimeStyle API key (starts with ps_live_) |
NEXT_PUBLIC_PRIMESTYLE_API_URL | No | Custom API URL (defaults to https://myaifitting.com/api) |
# .env.localNEXT_PUBLIC_PRIMESTYLE_API_KEY=ps_live_your_key_here# Optional: custom API URL# NEXT_PUBLIC_PRIMESTYLE_API_URL=https://myaifitting.com/apiInternationalization (i18n)
The SDK ships built-in translations for 20 languages. Set the locale prop to control the language, or omit it to auto-detect from the browser.
// Auto-detect from browser language<PrimeStyleTryon productImage="..." />// Explicit locale<PrimeStyleTryon productImage="..." locale="ja" />// Web Component<prime-style-tryon product-image="..." locale="fr"></prime-style-tryon>Supported Locale Codes
| Code | Language |
|---|---|
en | English |
es | Spanish |
fr | French |
de | German |
it | Italian |
sv | Swedish |
ja | Japanese |
cs | Czech |
da | Danish |
nl | Dutch |
no | Norwegian |
pl | Polish |
pt-BR | Portuguese (Brazil) |
pt-PT | Portuguese (Portugal) |
fi | Finnish |
tr | Turkish |
th | Thai |
zh-CN | Chinese (Simplified) |
zh-TW | Chinese (Traditional) |
ko | Korean |
Guides
Shopify App (No Code)
Install the PrimeStyle app from the Shopify App Store to add virtual try-on and AI-powered size recommendations to your product pages — no code or theme editing required.
1. Install the app
Search for "PrimeStyle Virtual Try-On" in the Shopify App Store and click Install. Authorize the app and it will automatically connect to your store — no API keys or configuration needed.
2. Activate on product pages
Once installed, the app automatically adds a "Virtual Try-On" button to all product pages in your store. The button appears next to your "Add to Cart" button. No theme editing needed — the app uses Shopify's app blocks system.
3. What your customers get
Virtual Try-On
Customers upload a photo and see themselves wearing the product. Results are generated in ~15 seconds with a progress bar and scanning animation.
AI Size Recommendation
Customers enter their measurements or height/weight for a quick estimate. The AI cross-references with the product's size guide to recommend the best fit, with confidence level and measurement-by-measurement breakdown.
4. Size guide auto-detection
The app automatically scans each product page for size guide data — in the product description, metafields, third-party size guide apps, and even size chart images. When a size guide is found, the AI uses it for precise sizing recommendations mapped directly to your chart.
5. Measurement profiles
Customers can save their body measurements as profiles for instant sizing on any product. Profiles are stored locally in the browser — no account required. Each profile saves measurements, unit preferences (cm/in), gender, and country.
Zero setup required. The Shopify app handles everything — product image detection, size guide extraction, try-on processing, and result display. No API keys needed. Usage and billing are managed automatically through the app.
Image Best Practices
Better input images = better try-on results. These apply to both the customer's photo (modelImage) and the garment images:
Do
- Use product-only images (white/clean background)
- Minimum 512px on shortest side
- Front-facing, flat-lay, or mannequin shots
- Well-lit, sharp, no watermarks
- JPEG or PNG format, any size up to 50MB
Don't
- Use images with models already wearing the garment
- Use images smaller than 256px
- Use heavily styled/filtered photos
- Use images with multiple products
- Use SVG or animated GIF format
One garment per request
Send a single garment image per request via the garmentImage field. The AI generates a photorealistic result of the customer wearing that product.
Handling Loading States
Virtual try-on typically takes 15-20 seconds. Here are patterns to keep users engaged:
Use SSE, not polling
The SSE stream delivers the result the instant it's ready — first as a base64 image for immediate display, then as a CDN URL for permanence. No wasted time between polls.
Progress indication
Show a shimmer skeleton of the result image while processing. The SDK handles this automatically. For API users, display a progress indicator with "~15 seconds remaining".
Keep them browsing
Let users continue shopping while the try-on processes. Use the SSE stream or SDK events to show a toast notification when the result is ready.
Retry gracefully
If a job fails (safety filter, timeout), the try-on is not counted against your balance. Show a friendly message with a retry button. The SDK handles this automatically.
Pricing
Simple pricing based on try-on generations. Subscribe for volume discounts. You are only charged for successful try-ons.
| Plan | Price | Try-Ons |
|---|---|---|
| Tier I | $299/mo | 600 |
| Tier IIPopular | $999/mo | 2,500 |
| Tier III | $2,999/mo | 10,000 |
~15s
Average processing time
$0
Failed jobs are free
Auto
Refund on failed jobs
Support
We're here to help you integrate. Reach out through any of these channels:
Email Support
support@primestyleai.com
Response within 24 hours
Enterprise
Custom integrations, SLA, dedicated support
Contact us for a demo
Frequently Asked
What image formats are supported?
JPEG, PNG, and WebP. Both URLs and base64 data URIs. Max 50MB per file.
How many garments per request?
One garment per request. Send a single product image via the garmentImage field and get a photorealistic try-on result.
Do I need to send product images with the SDK?
No. The SDK auto-detects and extracts product images from your page using OG tags, Schema.org data, and smart heuristics. You can optionally override with the product-image attribute.
Do you store customer photos or garment images?
No. Customer photos and garment images are processed in memory and never stored. Only the generated result image is returned to you.
What happens if a try-on fails?
Failed try-ons are not counted against your balance. Common causes: safety filter blocks or invalid images. Check the status endpoint or listen for failed events on the SSE stream.
How long does processing take?
Typically 15-20 seconds. Use the SSE stream to receive the result the instant it's ready, or poll the status endpoint every 3 seconds as a fallback.
Legal
These policies govern PrimeStyleAI's business-to-business API/SDK services available at primestyleai.com/developer.
Certain provisions also anticipate future optional end-user features; however, end users are not intended customers of the Services unless explicitly stated in a separate agreement.
Terms of Service
1.1 Definitions
- “Company,” “we,” “us,” “our”
- PrimeStyleAI.
- “Customer”
- The business entity (e.g., retailer/merchant) that creates an account or is issued API credentials.
- “Authorized User”
- Customer’s employees/contractors authorized to access the Services.
- “End User”
- Customer’s customers or site/app visitors interacting with Customer’s properties.
- “Services”
- The PrimeStyleAI API, SDK, developer portal, documentation, and related tools.
- “Output”
- AI-generated images/visualizations or other results produced by the Services.
- “Customer Data”
- Data submitted by Customer or End Users through Customer (including product images and user-uploaded images).
1.2 Eligibility and Authority
The Services are offered strictly for business use. By registering or using the Services, you represent and warrant that you are at least 18 years old and have authority to bind the Customer to these Terms. If you use the Services on behalf of Customer, you do so as Customer's agent, and Customer is responsible for your acts and omissions.
1.3 Account Registration; Credentials; Security
- •Customer is responsible for all activity under its account and credentials, including API keys.
- •Customer must protect credentials using industry-standard practices, including access controls, secret management, and rotation.
- •Customer must promptly notify us of any suspected unauthorized access or security incident.
1.4 License and Use of the Services
Subject to these Terms and any applicable order form or pilot agreement, PrimeStyleAI grants Customer a limited, non-exclusive, non-transferable, revocable license during the applicable term to access and use the Services solely for Customer's internal business purposes and solely as integrated into Customer's owned/controlled digital properties.
1.5 Acceptable Use and Prohibited Activities
- •No unlawful use; no use that violates privacy, consumer protection, advertising, or intellectual property laws.
- •No reverse engineering, decompiling, scraping, or attempting to extract source code, model weights, prompts, or underlying system design.
- •No circumvention of rate limits, access controls, or safety filters.
- •No submission of content involving minors, explicit sexual content, or illegal/violent/hate content.
- •No use to create deepfakes of real persons without authorization or in a misleading manner.
1.6 AI Output Disclaimer; No Sizing or Fit Guarantee
Outputs are simulated AI-generated representations. Outputs may not accurately reflect real-world garment fit, sizing, drape, color, texture, pattern alignment, lighting, or other attributes. The Services do not provide professional fitting, tailoring, medical, or biometric services. Customer remains solely responsible for product information, sizing charts, advertising claims, and all customer-facing representations.
1.7 No Performance Guarantees; No Reliance
We do not guarantee any business outcome, including conversion lift, revenue impact, return reduction, or customer satisfaction. Any projections, examples, or pilot modeling are illustrative only. Customer agrees not to rely on the Services or Outputs for any purpose other than evaluation and permitted business use and assumes all risk of use.
1.8 Beta Features; Availability; Third-Party Dependencies
Some features may be labeled beta/preview and are provided as-is. Service performance may vary and may be affected by third-party infrastructure and AI providers. We may modify, suspend, or discontinue features at any time.
1.9 Fees; Usage; Taxes
Fees (if any) are governed by an order form, pilot agreement, or separate commercial agreement. Unless otherwise specified, fees are non-refundable. Customer is responsible for applicable taxes, duties, and similar governmental assessments, excluding taxes on our income.
1.10 Intellectual Property; Feedback
- •We retain all right, title, and interest in the Services, including all software, models, algorithms, documentation, and improvements.
- •Customer retains rights in Customer Data. Customer grants us a limited license to process Customer Data to provide the Services.
- •If Customer provides feedback, Customer grants us a perpetual, worldwide, royalty-free license to use and incorporate feedback without obligation.
1.11 Confidentiality
Each party may receive the other's Confidential Information. Each party will protect the other's Confidential Information using reasonable care and will use it only to perform under these Terms or the applicable agreement. Obligations do not apply to information that is public without breach, independently developed, or lawfully obtained from a third party.
1.12 Suspension and Termination
- •We may suspend or terminate access immediately for violation of these Terms, suspected abuse, security risk, or legal compliance reasons.
- •Upon termination, Customer must stop using the Services and delete stored credentials and any non-public documentation we provided (except as required for records).
1.13 Disclaimer of Warranties
TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SERVICES AND OUTPUTS ARE PROVIDED “AS IS” AND “AS AVAILABLE,” WITHOUT WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE, NON-INFRINGEMENT, AND ACCURACY OR RELIABILITY OF OUTPUTS.
1.14 Limitation of Liability
TO THE MAXIMUM EXTENT PERMITTED BY LAW: (A) IN NO EVENT WILL PRIMESTYLEAI BE LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL, EXEMPLARY, OR PUNITIVE DAMAGES, OR FOR LOST PROFITS, LOST REVENUE, BUSINESS INTERRUPTION, OR LOSS OF GOODWILL; AND (B) PRIMESTYLEAI'S TOTAL AGGREGATE LIABILITY ARISING OUT OF OR RELATED TO THE SERVICES OR THESE TERMS WILL NOT EXCEED THE GREATER OF (I) USD $100 OR (II) THE FEES PAID BY CUSTOMER TO PRIMESTYLEAI FOR THE SERVICES IN THE TWELVE (12) MONTHS PRECEDING THE EVENT GIVING RISE TO THE CLAIM.
1.15 Indemnification by Customer
Customer will defend, indemnify, and hold harmless PrimeStyleAI and its officers, directors, employees, and agents from and against any third-party claims, damages, liabilities, and expenses (including reasonable attorneys' fees) arising from: (a) Customer Data; (b) Customer's products, sizing, descriptions, marketing claims, or sales practices; (c) Customer's relationship with End Users (including returns/refunds); (d) Customer's violation of applicable law; or (e) Customer's misuse of the Services.
1.16 Compliance; Export; Sanctions
Customer will comply with all applicable laws. Customer represents it is not subject to sanctions and will not use or permit use of the Services in violation of U.S. export controls or sanctions laws, including by providing access to restricted parties or jurisdictions.
1.17 Governing Law; Arbitration; Class Action Waiver
These Terms are governed by the laws of the State of California, USA, without regard to conflict-of-law rules. Any dispute arising out of or relating to these Terms or the Services shall be resolved by binding arbitration administered by the American Arbitration Association (AAA) in Orange County, California, in English, before a single arbitrator.
EACH PARTY WAIVES THE RIGHT TO A JURY TRIAL AND AGREES THAT CLAIMS MAY BE BROUGHT ONLY IN AN INDIVIDUAL CAPACITY AND NOT AS A PLAINTIFF OR CLASS MEMBER IN ANY PURPORTED CLASS, COLLECTIVE, OR REPRESENTATIVE PROCEEDING.
Notwithstanding the foregoing, either party may seek injunctive relief to protect its Confidential Information or intellectual property.
1.18 Changes to the Terms
We may update these Terms from time to time. If changes are material, we will post the updated Terms with a new “Last Updated” date. Continued use of the Services after changes become effective constitutes acceptance.
Contact
Privacy Policy
This Privacy Policy describes how PrimeStyleAI processes information in connection with the Services. In most cases, Customer is the data controller for End User data collected on Customer's properties, and PrimeStyleAI acts as a data processor solely to generate Outputs and operate the Services.
2.1 Data We Process
- •Product images and product metadata provided by Customer.
- •User-uploaded images and associated request metadata submitted through Customer's integration (processed transiently).
- •Technical logs and usage data (e.g., API calls, timestamps, error logs, IP address, device/browser information) for security and performance.
- •Account and billing data for Authorized Users (name, business email, role) as needed to operate the developer portal.
2.2 How We Use Data
- •Provide and operate the Services (render Outputs, authenticate sessions, prevent abuse).
- •Maintain security, rate limiting, and fraud prevention.
- •Monitor reliability and improve performance (aggregated analytics).
- •Comply with legal obligations and enforce our Terms.
2.3 Legal Bases (GDPR/UK GDPR)
Art. 6(1)(b)
Contractual Necessity
Customer account administration and providing the Services.
Art. 6(1)(f)
Legitimate Interests
Security, abuse prevention, and service improvement.
Art. 6(1)(c)
Legal Obligation
Where applicable by law.
2.4 Data Retention
User-uploaded images are intended to be processed transiently for rendering and are not stored persistently by default. We retain technical logs for a limited period necessary for security, troubleshooting, and compliance (typical range: 30–180 days), unless a longer period is required by law or agreed in writing. Customer may request details of current retention settings.
2.5 Sharing and Subprocessors
We may share data with service providers (subprocessors) that help us provide the Services, such as cloud hosting providers and AI infrastructure providers. We require subprocessors to protect data through contractual obligations. A current list of subprocessors may be provided upon request or via a DPA exhibit.
2.6 International Transfers
We are based in the United States and may process data in the U.S. and other jurisdictions where we or our subprocessors operate. Where required for transfers from the EEA/UK/Switzerland, we will use appropriate safeguards such as Standard Contractual Clauses (SCCs) and supplementary measures, typically through a Data Processing Addendum (DPA).
2.7 Security
We implement reasonable administrative, technical, and organizational measures designed to protect data, including encryption in transit (HTTPS), access controls, and monitoring. No security measure is perfect; therefore, we cannot guarantee absolute security.
2.8 End User Rights
Because Customer is typically the controller, End Users should direct privacy requests to the Customer. Where PrimeStyleAI is directly responsible under applicable law, data subjects may request access, correction, deletion, restriction, or portability.
2.9 California Privacy (CCPA/CPRA)
PrimeStyleAI does not sell personal information as defined under CCPA/CPRA. California residents may have rights to know, delete, and correct personal information. Because PrimeStyleAI generally acts as a service provider/processor for Customer, requests should be submitted to the Customer first. Authorized Users may contact us for account-related data requests.
2.10 Children's Data
The Services are intended for business use and are not directed to children. Customer must not knowingly submit personal data of children to the Services.
Contact
GDPR Compliance
PrimeStyleAI is designed with privacy-by-design principles. In most cases, Customer is the data controller and PrimeStyleAI acts as a processor. We support execution of a Data Processing Addendum (DPA), including Standard Contractual Clauses where appropriate.
4.1 Processor Commitments
- •Process personal data only on Customer's documented instructions.
- •Implement reasonable security measures.
- •Assist Customer with data subject rights requests as applicable.
- •Notify Customer without undue delay upon becoming aware of a confirmed personal data breach.
Data Processing Addendum
This Data Processing Addendum (“DPA”) forms part of the agreement between PrimeStyleAI (“Processor”) and the Customer (“Controller”) for the provision of the Services.
If there is a conflict between the DPA and the main agreement, the DPA controls for data protection matters.
1. Roles & Scope
1.1 Controller and Processor. Customer is the Controller of personal data processed via the Services. PrimeStyleAI acts as the Processor.
1.2 Purpose. Processor will process personal data only to provide the Services (render Outputs, secure the platform, and operate the developer portal).
1.3 Instructions. Customer instructs Processor to process personal data as necessary to provide the Services and as documented in the API/SDK documentation and this DPA.
2. Details of Processing
Annex 1 describes the subject matter, duration, nature and purpose of processing, types of personal data, and categories of data subjects.
Annex 1
- Subject matter
- AI-powered image rendering for virtual try-on outputs.
- Duration
- For the term of the agreement and as needed for transient processing.
- Nature of processing
- Receiving, transforming, and generating image outputs; logging for security and performance.
- Purpose
- Provide the Services; prevent abuse; ensure reliability.
- Data subjects
- Customer’s end users and Customer’s authorized users.
- Types of data
- User-uploaded images; product images; technical identifiers; account emails; logs.
3. Processor Obligations
- •Process personal data only on documented instructions from Customer, unless required by law.
- •Ensure persons authorized to process personal data are bound by confidentiality obligations.
- •Implement appropriate technical and organizational measures to protect personal data.
- •Assist Customer with responding to data subject requests, taking into account the nature of processing.
- •Assist Customer with DPIAs and consultations with regulators to the extent required and reasonably available.
4. Security Measures
Processor maintains reasonable measures appropriate to the risk. Annex 2 lists baseline controls.
Annex 2 — Baseline Security Controls
- •Encryption in transit (HTTPS/TLS).
- •Access controls and least-privilege administrative access.
- •Credential and key management practices (rotation recommended).
- •Monitoring, logging, and abuse prevention controls.
- •Separation of environments where feasible (e.g., dev/prod).
5. Subprocessors
Customer authorizes Processor to engage subprocessors to provide the Services (e.g., cloud hosting and AI infrastructure providers). Processor will impose data protection obligations on subprocessors consistent with this DPA and remains responsible for subprocessors' performance.
Processor will provide an up-to-date list of subprocessors upon request or via an attached schedule. Customer may object to a new subprocessor on reasonable data protection grounds by providing written notice within ten (10) days of notice.
6. International Transfers
Where personal data originating in the EEA/UK/Switzerland is transferred to a country without an adequacy decision, the Parties will implement appropriate safeguards, such as the EU Standard Contractual Clauses (SCCs) and/or the UK Addendum, typically incorporated by reference through this DPA or an exhibit.
7. Personal Data Breach
Processor will notify Customer without undue delay after becoming aware of a confirmed personal data breach affecting the Services. Processor will provide information reasonably necessary for Customer to meet any breach notification obligations.
8. Deletion & Return
Upon termination of the Services, Processor will delete or return personal data as requested by Customer, subject to applicable law and reasonable backups/archival practices. Transient user images are not intended to be stored persistently by default.
9. Audits
Upon reasonable prior notice and no more than once annually, Customer may audit Processor's compliance with this DPA to the extent necessary and proportionate, subject to confidentiality and security constraints. Processor may satisfy audit requests by providing summaries of controls, third-party reports (if available), or other reasonable evidence of compliance.
10. Liability
Each Party's liability under this DPA is subject to the limitations of liability in the main agreement, unless prohibited by applicable law.