AI virtual try-on and sizing for any storefront — Shopify, BigCommerce, Magento, headless, or custom. One engine, many stores: a shopper's digital twin is network-wide, so an avatar built on one store works on all of them.
In your Virtue Mirage dashboard, open Settings → API Key. There are two key types:
| Key | Use | Where |
|---|---|---|
vm_live_… secret | Full access. Server-side only — never put it in a browser. | Backend / server-side REST calls |
vm_pub_… publishable | Browser-safe. Only works from the storefront origins you register. | The drop-in <script>, browser bundles |
Send the key as Authorization: Bearer <key> or X-VM-Api-Key: <key>.
Best for BigCommerce, Magento, or any themed store. Paste one tag, then call the helpers. Add your storefront origin under Settings → API Key first, or the publishable key won't be authorised.
<script src="https://virtue-brain-534746878054.us-central1.run.app/sdk/virtue-mirage.js"
data-vm-key="vm_pub_xxx"></script>
<script>
VirtueMirage.setCustomer('shopper@example.com');
// Show "Your size: M" in a container
VirtueMirage.mountSizeBadge('#vm-size', {
gender: 'women', heightCm: 168, weightKg: 64, category: 'tops'
});
// Add a "See it on me" button that renders on the shopper's avatar
VirtueMirage.mountTryOnButton('#vm-tryon', {
productId: '123',
productImage: 'https://cdn.example.com/products/123/front.jpg'
});
</script>
Lower-level calls are available too: VirtueMirage.getSize(), .avatarStatus(), .preRender(), .tryOn() — all return Promises.
Best for headless / React / Next / Vite, or a backend. The API is plain REST — call it with fetch (Node 18+, or any HTTP client) using your secret key on the server. No package to install.
const BASE = 'https://virtue-brain-534746878054.us-central1.run.app';
const headers = { 'Authorization': `Bearer ${process.env.VM_SECRET_KEY}`, 'Content-Type': 'application/json' };
// Size + Fit Advisor
const size = await fetch(`${BASE}/api/v1/public/size`, { method: 'POST', headers,
body: JSON.stringify({ gender:'women', heightCm:168, weightKg:64, category:'tops' }) }).then(r => r.json());
// Does this shopper already have a digital twin? (network-wide)
const twin = await fetch(`${BASE}/api/v1/public/avatar-status?email=shopper%40example.com`, { headers }).then(r => r.json());
// Render a product on the shopper's avatar (cache-first, 1 token per render)
const tryon = await fetch(`${BASE}/api/v1/public/tryon`, { method: 'POST', headers,
body: JSON.stringify({ email:'shopper@example.com', productId:'123', productUrl:'https://cdn.example.com/products/123/front.jpg' }) }).then(r => r.json());
A typed npm package (@virtuemirage/sdk) wrapping these calls ships with our marketplace release — until then, the drop-in script and the REST endpoints above are the supported paths.
| Method · Path | Purpose | Tokens |
|---|---|---|
POST /api/v1/public/size | Size + Fit Advisor from measurements or height/weight/frame | none |
GET /api/v1/public/avatar-status | Does this shopper have a digital twin? (network-wide) | none |
GET /api/v1/public/pre-render | Fetch a stored try-on for a product + shopper | none |
POST /api/v1/public/tryon | Render a product on the shopper's avatar (cache-first) | 1 per render |
curl -X POST https://virtue-brain-534746878054.us-central1.run.app/api/v1/public/size \
-H "Authorization: Bearer vm_live_xxx" -H "Content-Type: application/json" \
-d '{"gender":"women","heightCm":168,"weightKg":64,"category":"tops"}'
→ { "success": true, "size": "M", "confidence": "high", "category": "tops", "estimated": true }
Pass exact bust/waist/hips (with optional unit:"in") to override the estimate, or a productId to resolve category and the brand's size chart automatically.
curl "https://virtue-brain-534746878054.us-central1.run.app/api/v1/public/avatar-status?email=shopper@example.com" \
-H "Authorization: Bearer vm_live_xxx"
→ { "success": true, "hasAvatar": true, "avatarUrl": "https://…",
"brandOfRecord": "brand-a", "isNewToThisBrand": true }
curl -X POST https://virtue-brain-534746878054.us-central1.run.app/api/v1/public/tryon \
-H "Authorization: Bearer vm_live_xxx" -H "Content-Type: application/json" \
-d '{"email":"shopper@example.com","productId":"123","productUrl":"https://cdn.example.com/123/front.jpg"}'
→ { "success": true, "imageUrl": "https://…/tryon.jpg", "cached": false }
| Status · code | Meaning |
|---|---|
401 invalid_api_key | Key missing or unrecognised. |
403 origin_not_allowed | Publishable key used from an unregistered origin. Add it under Settings → API Key. |
403 BLOCKED_KIDS | Children's products are never rendered — child-safety, no override. |
409 NO_AVATAR | Shopper has no digital twin yet (create one via onboarding). |
429 TOKEN_LIMIT_EXCEEDED | Brand's monthly token allowance is spent. |
vm_live_…) grants full, token-spending access — keep it on a server and out of source control. The publishable key (vm_pub_…) is the only key safe for the browser, and it only works from the origins you register.