Developer Documentation
PrimeStyle VTO API
Add AI-powered virtual try-on to any e-commerce experience. One API call turns a product photo into a try-on result.
Introduction
PrimeStyle gives shoppers photorealistic virtual try-on and AI-powered size recommendations on any product page. Try-on results are generated in 15-20 seconds from a single customer photo plus a garment image. Sizing uses a small user profile (height, weight, and a few body-shape answers) to recommend a size for your product.
There are three ways to integrate, in order of how much work you want to do:
Drop-in React component
<PrimeStyleTryon /> renders a launch button and a modal that handles photo upload, sizing, and try-on end-to-end. Fastest path to ship.
Headless sizing hook
usePrimeStyleSize() and recommendForProduct() return a recommended size for your own UI. No modal.
Raw HTTP API
Call POST /api/v1/tryon and /api/v1/sizing/* from any server or client. Full control over UI and flow.
Profiles live in localStorage on the user's browser. PrimeStyle does not store user profiles or measurements on our servers, and there is no backend account system for end users. You do not need a database to use any of this.
End-to-end flow
Quick Start
Get a working virtual try-on button on your product page in under five minutes.
1. Install the SDK
The package ships both the React component and the plain-JS web component.
npm install @primestyleai/tryon2. Get an API key
Create a key in the developer dashboard. Every authenticated request needs Authorization: Bearer <apiKey>. The React component reads the key from the API URL it calls; keep the raw key out of your client bundle and proxy through your own server when possible.
3. Drop the component on a product page
Pass at minimum a productImage. Everything else is optional.
import { PrimeStyleTryon } from "@primestyleai/tryon/react";export default function ProductPage() { return ( <PrimeStyleTryon productImage="https://cdn.example.com/products/shirt-front.jpg" productTitle="Linen Oxford Shirt" productId="sku-12345" apiUrl="https://myaifitting.com" onComplete={(result) => { console.log("Try-on ready:", result.imageUrl); }} onError={(err) => { console.error("Try-on failed:", err.message); }} /> );}4. What the user sees
- A "Try it on" button renders next to your product.
- Clicking opens a modal that walks the user through profile setup or photo upload.
- The SDK requests a size recommendation and a try-on image from the API.
- Within ~20 seconds the modal shows the try-on photo and recommended size.
Authentication
Every authenticated endpoint requires a PrimeStyle API key. Keys are issued and revoked from the developer dashboard; they carry your try-on token balance and your rate limit.
API Keys
Create a key from your dashboard. Treat keys like any other secret — do not commit them and rotate them periodically.
Passing the key
- •HTTP API: send the header
Authorization: Bearer <apiKey>on every request. - •SSE stream: you may pass the key either in the
Authorizationheader or as?key=on the URL (EventSource does not support custom headers in the browser). - •SDK: the React component calls an
apiUrlyou control. If you do not pass one, the SDK readsNEXT_PUBLIC_PRIMESTYLE_API_URLat build time. Proxy the real key through your backend so it never ships to the browser.
curl -X POST https://myaifitting.com/api/v1/tryon \ -H "Authorization: Bearer psk_live_your_key_here" \ -H "Content-Type: application/json" \ -d '{ "modelImage": "https://example.com/user.jpg", "garmentImage": "https://example.com/shirt.jpg" }'const es = new EventSource( "https://myaifitting.com/api/v1/tryon/stream?key=psk_live_your_key_here");es.addEventListener("completed", (e) => { const payload = JSON.parse(e.data); console.log("image ready:", payload.imageUrl);});Try-On Balance & Rate Limits
Each successful try-on deducts one token from your account. Sizing endpoints are currently free and metered only by rate limits. Every POST /api/v1/tryon response includes tryOnsUsed and newBalance so your dashboard can show the running total.
402 Insufficient tokens
If your balance is 0 we return HTTP 402 with a body of { error, currentBalance, required }. Top up from the billing page or fall back to showing the size recommendation without the visual try-on.
401 Unauthorized
Returned when the key is missing, malformed, expired, or revoked. Rotate and try again.
API Reference
The PrimeStyle HTTP API lives at https://myaifitting.com. All authenticated endpoints accept JSON and require a bearer token.
There is no HTTP surface for managing user profiles — profiles are kept in localStorage by the SDK. Your backend never needs to store them.
Create a Try-On Job
/api/v1/tryonAuthSubmit a new try-on job. Returns immediately with a galleryId you can stream or poll. One try-on token is deducted per successful job (failed jobs are refunded).
Request Body
modelImagestring (URL or data URI)requiredImage of the person. Public HTTPS URL, signed URL, or base64 data URI. JPEG, PNG or WebP up to 50MB.
garmentImagestring (URL or data URI)requiredImage of the product. A clean product shot works best.
fitInfoFitAreaInfo[]Optional per-area fit hints. Each entry has { area, fit, userValue?, garmentRange? } where fit is one of good, tight, loose, a-bit-tight, a-bit-loose, too-tight, too-loose. When any fit is imperfect the backend does a two-pass render to adjust that area. Not stored server-side.
Example Request
curl -X POST https://myaifitting.com/api/v1/tryon \ -H "Authorization: Bearer $PRIMESTYLE_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "modelImage": "https://cdn.example.com/user.jpg", "garmentImage": "https://cdn.example.com/shirt.jpg", "fitInfo": [ { "area": "Chest", "fit": "a-bit-tight", "userValue": 102, "garmentRange": "96-100" } ] }'Response 202
{ "galleryId": "65c8d1a4e2b4f5d3c8a91234", "status": "processing", "message": "VTO job started. Poll /api/v1/tryon/status/:galleryId to check progress", "tokensDeducted": 1, "newBalance": 958}Poll Try-On Status
/api/v1/tryon/status/:galleryIdAuthReturns the current state of a try-on job. Poll every ~3 seconds as a fallback to the SSE stream. Note: the URL param is the galleryId returned from POST /api/v1/tryon — some SDK code still calls this value 'jobId' for backwards compatibility.
Path Parameters
galleryIdstring (24-char MongoDB ObjectId)requiredThe galleryId returned from POST /api/v1/tryon. Example: 65c8d1a4e2b4f5d3c8a91234.
Example Request
curl https://myaifitting.com/api/v1/tryon/status/65c8d1a4e2b4f5d3c8a91234 \ -H "Authorization: Bearer $PRIMESTYLE_API_KEY"Response 200
{ "galleryId": "65c8d1a4e2b4f5d3c8a91234", "status": "completed", "imageUrl": "https://res.cloudinary.com/.../result.jpg", "message": "Try-on ready"}status is one of processing, completed, or failed. The imageUrl is populated only when the job completes successfully.
Server-Sent Events Stream
/api/v1/tryon/streamAuthSubscribe to real-time job events. You receive 'completed' and 'failed' events for any job submitted by your API key while the connection is open. Use this instead of polling when you can keep a connection open.
Query Parameters
keystringAPI key, passed on the URL because browser EventSource does not support custom headers. You may use the Authorization header from server-side clients instead.
Example Request
curl -N "https://myaifitting.com/api/v1/tryon/stream?key=$PRIMESTYLE_API_KEY"Uploading Images
The try-on endpoint does not require a separate upload step. Pass images either as a public URL that PrimeStyle can fetch, or as a data:image/jpeg;base64,… URI. The SDK helpers compressImage and isValidImageFile can prepare a user file before posting.
- •Accepted formats: JPEG, PNG, WebP.
- •Max payload: 50MB per image.
- •Input images (your photo + the garment) are forwarded to the rendering backend in memory for the duration of the request.
- •The generated result is delivered back to your application; we do not maintain a long-term copy on your behalf.
Recommend a Size
/api/v1/sizing/recommendAuthGiven a user profile and a product (optionally with its size guide), returns a recommended size, a confidence level, and human-readable reasoning.
Request Body
method"exact" | "quick" | "photo"requiredHow the user's measurements were obtained. 'exact' means the user entered them directly, 'quick' means they came from height + weight + body-shape answers, 'photo' means they were derived from BlazePose landmarks on a body photo.
product{ title, description?, variants? }requiredProduct context used to match the right size chart. Title is required; description and variants improve accuracy.
measurementsobjectKeyed by body part. Common keys: gender, heightCm, chest, bust, waist, hips, shoulderWidth, sleeveLength, inseam, neckCircumference. For footwear: shoeEU, shoeUS, shoeUK. Required when method is 'exact' or 'photo'. Extra keys are accepted and forwarded.
quickEstimateobjectHeight/weight/gender/age/body-shape inputs used when method is 'quick'.
sizeGuideobjectA normalized size guide, typically the response from /api/v1/sizing/sizeguide.
bodyImagestringBody photo (URL or data URI) used when method is 'photo'.
bodyLandmarksobjectMediaPipe BlazePose landmarks extracted in the browser.
sizingUnit"cm" | "in"Preferred unit in the response. Defaults to cm.
localestringBCP-47 locale used to generate the reasoning text.
Example Request
curl -X POST https://myaifitting.com/api/v1/sizing/recommend \ -H "Authorization: Bearer $PRIMESTYLE_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "method": "exact", "sizingUnit": "cm", "product": { "title": "Linen Oxford Shirt", "description": "Regular fit, 100% linen." }, "measurements": { "chest": 102, "waist": 86, "height": 180, "weight": 78 } }'Response 200
{ "recommendedSize": "M", "tightSize": "S", "looseSize": "L", "confidence": "high", "reasoning": "Chest 102cm falls in the middle of the M band (100-104cm).", "internationalSizes": { "US": "M", "EU": "50", "UK": "M" }, "unit": "cm"}Response Fields
recommendedSizestringrequiredThe size we recommend for this user + product.
tightSizestringThe next size down, if a tighter fit is possible.
looseSizestringThe next size up.
recommendedLengthstringFor multi-length products (e.g. Short / Regular / Long inseam).
confidence"high" | "medium" | "low"requiredHow certain the model is in the recommendation.
reasoningstringrequiredShort explanation suitable to show to the end user.
internationalSizesRecord<string, string>Localized size labels (US, EU, UK, JP, etc.).
sectionsobject[]Per-section recommendations for products with multiple sizing sections (e.g. top + bottom).
unit"cm" | "in"Unit echoed from the request.
Estimate Body Measurements
/api/v1/sizing/estimateAuthEstimate body measurements from either a short text profile (height, weight, gender, body-shape answers) or a body photo with MediaPipe BlazePose landmarks.
Request Body
snapModebooleanSwitches between two request shapes: normal (text profile) or snap (photo-only). When true, only bodyImage and requiredFields are used; gender/demographics are inferred from the photo.
bodyImagestringBody photo as URL or data URI. Required when snapMode is true; optional in normal mode to enhance accuracy.
bodyLandmarksobjectMediaPipe BlazePose landmarks extracted in the browser. Improves accuracy when bodyImage is used.
requiredFieldsstring[]required1–20 measurement names you want back (e.g. ['chest', 'waist', 'hips']). Required in normal mode; optional in snap mode.
heightnumberHeight in heightUnit. 20–300. Used in normal mode.
weightnumberWeight in weightUnit. 20–700. Used in normal mode.
heightCmnumberAlternative to height+heightUnit — explicit centimeters, 36–250.
weightKgnumberAlternative to weight+weightUnit — explicit kilograms, 30–660.
heightUnit"cm" | "in" | "ft"Unit of the supplied height. Default 'cm'. 'ft' is a legacy alias for 'in'.
weightUnit"kg" | "lbs"Unit of the supplied weight. Default 'kg'.
gender"male" | "female" | "unisex"requiredRequired in normal mode. Inferred from the photo in snap mode.
agenumber13–100. Improves accuracy slightly.
bodyType"slim" | "athletic" | "average" | "stocky" | "plus"Self-assessed overall build.
chestProfile"narrow" | "average" | "broad"Shape hint for the chest/bust.
midsectionProfile"flat" | "average" | "round"Shape hint for the midsection.
hipProfile"narrow" | "average" | "full"Shape hint for the hips.
unit"cm" | "in"Preferred unit for the returned estimates.
Example Request
# Normal mode — estimate from height/weight/gender + optional shape answerscurl -X POST https://myaifitting.com/api/v1/sizing/estimate \ -H "Authorization: Bearer $PRIMESTYLE_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "height": 180, "weight": 78, "heightUnit": "cm", "weightUnit": "kg", "gender": "male", "age": 32, "bodyType": "average", "chestProfile": "average", "midsectionProfile": "flat", "hipProfile": "average", "requiredFields": ["chest", "waist", "hips", "shoulderWidth"] }'# Snap mode — estimate from a body photo alonecurl -X POST https://myaifitting.com/api/v1/sizing/estimate \ -H "Authorization: Bearer $PRIMESTYLE_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "snapMode": true, "bodyImage": "https://cdn.example.com/body.jpg", "requiredFields": ["chest", "waist", "hips"] }'Response 200
{ "estimates": { "chest": 102, "waist": 86, "hips": 98, "shoulderWidth": 46 }, "method": "llm", "unit": "cm", "detectedGender": "male"}Parse a Size Guide
/api/v1/sizing/sizeguideAuthNormalize a raw size guide (HTML, JSON, or chart images) into a structured table of sizes that /api/v1/sizing/recommend can consume. Useful once per product page load; cache the result alongside your product.
Request Body
product{ title?, description?, category?, subcategory?, gender? }Product context used to disambiguate the chart. Category/subcategory/gender help pick the right chart when the merchant serves multiple.
sizeGuideDataunknownA pre-structured guide (headers + rows, or your own shape). Skips parsing on the backend.
sizeGuideRawstringRaw HTML or plain text (for instance the innerHTML of a size-guide panel). The backend will normalize it with an LLM.
sizeChartImagesstring[]Array of image URLs of size charts. Used when the merchant only has screenshots or PDFs — the backend uses vision to extract the table.
Example Request
# 1. Raw HTML — backend parses it with an LLMcurl -X POST https://myaifitting.com/api/v1/sizing/sizeguide \ -H "Authorization: Bearer $PRIMESTYLE_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "product": { "title": "Linen Oxford Shirt" }, "sizeGuideRaw": "<table>...</table>" }'# 2. Pre-structured JSON — no parsing neededcurl -X POST https://myaifitting.com/api/v1/sizing/sizeguide \ -H "Authorization: Bearer $PRIMESTYLE_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "product": { "title": "Linen Oxford Shirt" }, "sizeGuideData": { "headers": ["Size", "Chest (cm)", "Waist (cm)"], "rows": [["S","92-96","76-80"], ["M","100-104","84-88"]] } }'# 3. Image URLs only — backend uses vision to extract the tablecurl -X POST https://myaifitting.com/api/v1/sizing/sizeguide \ -H "Authorization: Bearer $PRIMESTYLE_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "product": { "title": "Linen Oxford Shirt" }, "sizeChartImages": [ "https://cdn.example.com/size-chart-men.jpg" ] }'Response 200
{ "found": true, "title": "Men's Shirt Size Guide", "headers": ["Size", "Chest (cm)", "Waist (cm)"], "rows": [ ["S", "92-96", "76-80"], ["M", "100-104","84-88"], ["L", "108-112","92-96"] ], "sections": []}Error Codes
| HTTP | Meaning |
|---|---|
400 | Malformed JSON, missing required fields, or an image the renderer could not decode. |
401 | Missing, malformed, expired, or revoked API key. |
402 | Try-on balance is 0. Body includes currentBalance and required. |
404 | Gallery id not found (for /status/:galleryId). |
422 | Input passed validation but cannot be sized (e.g. no pose detected in the photo). |
429 | Rate limit exceeded. Retry with exponential backoff. |
500 | Unexpected server error. Failed jobs are automatically refunded. |
Guest Try-On (no auth)
For marketing demos and landing pages, a public endpoint accepts one free try-on per IP address without an API key. It is otherwise identical to the authenticated version. There is a matching GET /api/public/tryon/status/:jobId.
/api/public/tryonSubmit one free guest try-on. Rate-limited per IP. Not intended for production integrations.
Example Request
curl -X POST https://myaifitting.com/api/public/tryon \ -H "Content-Type: application/json" \ -d '{ "modelImage": "https://cdn.example.com/user.jpg", "garmentImage": "https://cdn.example.com/shirt.jpg" }'SDK
The @primestyleai/tryon package exposes four surfaces: a React component, a set of headless functions and a React hook for sizing, a browser web component, and a handful of localStorage helpers for managing user profiles client-side.
Installation
npm install @primestyleai/tryonThe package has no peer dependencies beyond React 18+ (React 19 supported). The web component is registered automatically by importing the top-level package (import "@primestyleai/tryon").
React Component: <PrimeStyleTryon />
The React component renders a launch button and, when clicked, a full-screen modal that walks the user through profile creation, sizing, and try-on. A single prop — productImage — is enough to ship.
import { PrimeStyleTryon } from "@primestyleai/tryon/react";Props
productImagestringrequiredPublic URL of the product image to try on.
productTitlestringShown in the modal header and used to improve sizing accuracy.
productIdstringYour SKU. Used as the cache key for size recommendations and try-on results per profile.
buttonTextstringButton label. Defaults to the localized 'Try it on'.
apiUrlstringPrimeStyle API base URL. Defaults to NEXT_PUBLIC_PRIMESTYLE_API_URL or https://myaifitting.com.
showPoweredBybooleanShow the 'Powered by PrimeStyle' badge in the modal footer.
showIconbooleanShow the sparkle icon on the button.
buttonIconReact.ReactNodeCustom icon replacing the default sparkle.
localestringBCP-47 locale code (e.g. 'en', 'fr', 'es-MX'). See the i18n section.
buttonStylesButtonStylesOverride colors, padding, border, radius, font, and hover state.
modalStylesModalStylesOverride modal colors, shadow, and accent.
classNamesPrimeStyleClassNamesMap of className overrides for internal modal slots.
classNamestringClass applied to the root launch button.
styleCSSPropertiesInline styles on the launch button.
sizeGuideDataunknownPre-parsed size guide to skip the /sizing/sizeguide call. See 'Using your own size guide' in Guides.
onOpen() => voidFires when the modal opens.
onClose() => voidFires when the modal closes.
onUpload(file: File) => voidFires when the user selects a photo.
onProcessing(jobId: string) => voidFires once we have a jobId from the API.
onComplete(r: { jobId, imageUrl }) => voidFires when the try-on image is ready.
onError(e: { message, code? }) => voidFires on any error surfaced to the user.
import { PrimeStyleTryon } from "@primestyleai/tryon/react";export function ProductTryOnButton({ product }) { return ( <PrimeStyleTryon productImage={product.image} productTitle={product.title} productId={product.sku} buttonText="See it on you" apiUrl={process.env.NEXT_PUBLIC_PRIMESTYLE_API_URL} locale="en" showPoweredBy onOpen={() => track("tryon_open", { sku: product.sku })} onUpload={(file) => track("tryon_upload", { size: file.size })} onProcessing={(jobId) => track("tryon_processing", { jobId })} onComplete={({ jobId, imageUrl }) => { track("tryon_complete", { jobId }); analytics.setResult(imageUrl); }} onError={(err) => track("tryon_error", err)} /> );}Customization
Three layers, in order of precedence (top wins):
- •
classNames— map of Tailwind/CSS classes for specific slots (button, modal, footer, etc.). - •
buttonStylesandmodalStyles— typed objects for the common tweaks (colors, border, radius, hover). - •
className+style— last-resort overrides on the launch button.
<PrimeStyleTryon productImage={product.image} buttonStyles={{ background: "#111", color: "#fff", borderRadius: 0, hoverBackground: "#2154EF", }} modalStyles={{ accent: "#2154EF" }} classNames={{ launchButton: "font-serif uppercase tracking-widest" }}/>Callbacks
All callbacks are optional and fire in this order during a successful flow:
jobId. The raw HTTP API calls the same value galleryId. They are interchangeable; the SDK translates at the boundary.onOpen()— user clicks the launch button.onUpload(file)— user selects a body photo.onProcessing(jobId)— the API has accepted the job.onComplete({ jobId, imageUrl })— the try-on image is ready.onClose()— user dismisses the modal.
onError({ message, code? }) fires whenever a recoverable error surfaces to the user (bad image, safety filter block, 402 insufficient balance, etc.).
Headless Sizing
If you don't want the bundled modal, three primitives let you build your own UI on top of the same sizing engine. All of them are pure client-side calls against the PrimeStyle API and use whatever profile is currently active in localStorage.
recommendForProduct()One-shot async function. Returns RecommendForProductResult | null.
estimateFullMeasurements()One-shot async function. Returns estimates + unit + detected gender.
usePrimeStyleSize()React hook wrapper around recommendForProduct. Returns { data, loading, error }.
import { recommendForProduct } from "@primestyleai/tryon";const rec = await recommendForProduct({ apiUrl: "https://myaifitting.com", product: { title: "Linen Oxford Shirt", description: "Regular fit, 100% linen.", }, sizingUnit: "cm",});if (rec) { console.log(rec.recommendedSize, rec.confidence, rec.reasoning);}import { estimateFullMeasurements } from "@primestyleai/tryon";const result = await estimateFullMeasurements({ apiUrl: "https://myaifitting.com", height: 180, weight: 78, heightUnit: "cm", weightUnit: "kg", gender: "male", requiredFields: ["chest", "waist", "hips"],});console.log(result?.estimates, result?.unit);import { usePrimeStyleSize } from "@primestyleai/tryon/react";function SizeRecommendation({ product }) { const { data, loading, error } = usePrimeStyleSize({ product: { title: product.title, description: product.description }, sizingUnit: "cm", }); if (loading) return <p>Measuring…</p>; if (error) return <p>Couldn't compute a size.</p>; if (!data) return <p>Set up your profile to see a size.</p>; return ( <div> <strong>Recommended: {data.recommendedSize}</strong> <p>{data.reasoning}</p> </div> );}Web Component (Coming Soon)
Drop-in <primestyle-tryon> tag and CDN script coming soon
A framework-agnostic custom element you can drop into any HTML page with a single script tag is in development. For now, use the React component or the raw HTTP API directly.
Profile Storage (localStorage)
These helpers read and write localStorage directly. There is no network I/O and no server-side profile store. Safe to call client-side on any render.
Exports
getProfiles()() => Profile[]All stored profiles on this browser.
saveProfiles(profiles)(profiles: Profile[]) => voidReplace the entire profile list.
getActiveProfile()() => Profile | nullThe currently active profile, or null.
getActiveProfileId()() => string | nullId of the currently active profile.
setActiveProfileId(id)(id: string) => voidSwitch the active profile.
updateProfile(id, patch)(id, patch) => voidMerge-update a profile by id.
updateProfileMeasurements(id, m, unit?)functionUpdate only the measurements object for a profile.
addSizeToHistory(profileId, entry)functionRemember a recommended size for later lookups.
getCachedSize(profile, productId)(profile, productId) => string | nullReturn a previously cached recommendation for (profile, product), or null.
import { getProfiles, getActiveProfile, getActiveProfileId, setActiveProfileId, saveProfiles, updateProfile, updateProfileMeasurements, addSizeToHistory, getCachedSize,} from "@primestyleai/tryon";// Read the current active profile (or null).const profile = getActiveProfile();// Switch profiles.setActiveProfileId("profile-2");// Update measurements after the user edits them.updateProfileMeasurements(profile.id, { chest: 104, waist: 88,}, "cm");// Look up a cached size recommendation for a product.const cached = getCachedSize(profile, "sku-12345");Environment Variables
Build-time variables
NEXT_PUBLIC_PRIMESTYLE_API_URLstringBase URL the SDK calls when no apiUrl prop is passed. Defaults to https://myaifitting.com. Exposed to the browser at build time by Next.js.
The SDK itself does not read the API key from any env var; it hits whatever URL you point it at. Proxy the key through your backend so end users never see it.
Internationalization (i18n)
Pass a locale via the locale prop (or locale attribute on the web component). The SDK ships with a set of built-in translations and will fall back to English for missing keys.
i18n utilities
SUPPORTED_LOCALESreadonly string[]Locale codes that ship out of the box.
TRANSLATION_KEYSreadonly string[]All keys used inside the modal. Useful for validation in custom translations.
registerLocale(locale, dict)functionRegister or override a locale at runtime.
createT(locale)(locale: string) => (key: string) => stringBuild a translation function for a specific locale. Useful for your own UI built around the headless hook.
detectLanguage()() => stringDetect the user's language from the browser (navigator.language).
Guides
Short, copy-and-paste guides for the integrations our partners ask about the most.
Shopify (Coming Soon)
Official Shopify app coming soon
A first-class Shopify integration with product detection, size-guide parsing, per-variant recommendations, and zero-code install is on the roadmap. Until then, you can integrate via the React component or the raw HTTP API.
Using Your Own Size Guide
If you already have structured size data, pass it directly to sizeGuideData. The SDK will skip the call to /api/v1/sizing/sizeguide and feed your table straight into the recommender.
import { PrimeStyleTryon } from "@primestyleai/tryon/react";export function ProductButton({ product }) { return ( <PrimeStyleTryon productImage={product.image} productTitle={product.title} productId={product.sku} sizeGuideData={{ headers: ["Size", "Chest (cm)", "Waist (cm)"], rows: [ ["S", "92-96", "76-80"], ["M", "100-104", "84-88"], ["L", "108-112", "92-96"], ], }} /> );}If all you have is raw HTML (for example, the innerHTML of a merchant's existing size-guide panel), call the parser endpoint once at build time and cache the normalized structure with your product:
// 1. Normalize raw HTML once, cache the result on your product.const guide = await fetch( "https://myaifitting.com/api/v1/sizing/sizeguide", { method: "POST", headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json" }, body: JSON.stringify({ product: { title: product.title }, sizeGuideRaw: product.sizeGuideHtml, }), },).then((r) => r.json());// 2. Pass the normalized guide back to PrimeStyleTryon:<PrimeStyleTryon productImage={product.image} productTitle={product.title} sizeGuideData={guide}/>Listening to Try-On Events
Wire the component's callbacks into your analytics to understand the funnel (opens → uploads → completes) and to react to the final image (cache it, show a "looks great" prompt, etc.).
<PrimeStyleTryon productImage={product.image} productTitle={product.title} productId={product.sku} onOpen={() => analytics.track("tryon_open")} onUpload={(file) => analytics.track("tryon_upload", { size: file.size, type: file.type }) } onProcessing={(jobId) => analytics.track("tryon_processing", { jobId })} onComplete={({ jobId, imageUrl }) => { analytics.track("tryon_complete", { jobId }); setResultImage(imageUrl); }} onError={({ message, code }) => analytics.track("tryon_error", { message, code }) }/>Image Best Practices
- •Product images: clean, well-lit, front-facing, preferably on a plain background.
- •Body photos: one person, full torso visible, arms slightly away from the body.
- •Max 50MB per image; compress to ~1600px on the longest side before posting.
- •Use JPEG for photos and PNG only when you need alpha.
// Accepted image sources for modelImage / garmentImage:// - Public HTTPS URL:"https://cdn.example.com/products/shirt.jpg"// - Data URI (base64):"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQ..."// - Helpers for browser-side files:import { compressImage, isValidImageFile } from "@primestyleai/tryon";if (!isValidImageFile(file)) throw new Error("Unsupported image");const compressed = await compressImage(file, { maxDimension: 1600 });Loading States
Try-ons typically complete in 15-20 seconds. To keep the UI responsive:
- •Show an optimistic state as soon as
onProcessing(jobId)fires. - •Prefer
/api/v1/tryon/stream(SSE) over polling; it typically shaves 1-3 seconds off the perceived latency. - •Fall back to polling
/status/:jobIdevery 3 seconds if SSE is blocked (some corporate proxies strip it). - •On
failed, show a short retry affordance — failed jobs are refunded automatically.
Pricing
Simple pricing based on try-on generations. Subscribe for volume discounts. You are only charged for successful try-ons — failed jobs are refunded automatically. Sizing endpoints are currently free and metered only by rate limits.
| 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.
Where are user profiles stored?
Profiles live in the user's browser localStorage. PrimeStyle does not offer a server-side profile store and no endpoint for profile CRUD. If you need profiles to follow a user across devices, you are free to mirror them into your own backend.
Do you store customer photos or try-on results?
Input photos are forwarded in memory to the rendering backend and dropped after the request completes. Generated results are returned to your application. See the Privacy Policy for retention details.
What happens if a try-on fails?
Failed try-ons are not counted against your balance. Common causes: safety filter blocks or invalid images. Listen for failed on the SSE stream or check /status/:jobId.
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.
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.