Skip to content

Quickstart

This walks through the full happy path: create an API key, create a product, wait for it to process, turn on try-on, and drop the button on a product page.

In the panel, go to Settings → API Keys and create a key. It’s shown once — copy it somewhere safe. See Authentication for key format and rotation.

Every product needs a title and a category. Pass images as an array of public URLs and we’ll download them — this also starts the processing that eventually makes the product try-on-ready.

Request
curl -X POST https://api.integration.tryonvirtual.com/v1/products \
-H "Authorization: Bearer tryon_sk_your_key" \
-H "Content-Type: application/json" \
-d '{
"title": "Aviator Sunglasses",
"category": "eyewear",
"images": ["https://yourstore.com/images/aviator.jpg"]
}'

Four fields in the response matter right now — the highlighted ones. Keep id: every call after this one needs it.

Response
{
"product": {
"id": "9c1e2f3a-4b5c-4d6e-8f7a-1234567890ab",
"external_id": null,
"title": "Aviator Sunglasses",
"handle": "aviator-sunglasses",
"category": "eyewear",
"status": "active",
"image_url": "https://cdn.tryonvirtual.com/.../aviator.jpg",
"model_type": null,
"tryon_status": "inactive",
"active_asset_id": null,
"swap_ready": false,
"images": [{ "id": "...", "url": "...", "position": 0, "is_primary": true, "created_at": "..." }],
"created_at": "2026-08-07T12:00:00Z"
},
"images_failed": []
}

Any image URL that fails to download (timeout, unreachable, not an image, too large) is reported in images_failed instead of failing the whole request — see Images for the per-image error codes.

Valid categories: eyewear, watch, shoes, jewelry, clothes, bag, luggage.

Adding images kicks off processing in the background. Poll GET /v1/products/{id} every few seconds; it’s usually done in under a minute.

Request
curl https://api.integration.tryonvirtual.com/v1/products/9c1e2f3a-4b5c-4d6e-8f7a-1234567890ab \
-H "Authorization: Bearer tryon_sk_your_key"

You’re waiting for exactly one field to flip. This is what ready looks like:

Response — ready
{
"product": {
"id": "9c1e2f3a-4b5c-4d6e-8f7a-1234567890ab",
"tryon_status": "inactive",
"swap_ready": true,
"...": "..."
}
}

tryon_status is still inactive at this point, and that’s correct — you turn it on in the next step. swap_ready is about processing, nothing else.

Set the mode and enable it in one call:

Request
curl -X PATCH https://api.integration.tryonvirtual.com/v1/products/9c1e2f3a-4b5c-4d6e-8f7a-1234567890ab \
-H "Authorization: Bearer tryon_sk_your_key" \
-H "Content-Type: application/json" \
-d '{"mode": "swap", "tryon_enabled": true}'

swap is the AI photo-swap experience and the only mode you can drive end-to-end through this API. The other mode, realtime (3D/AR), requires a 3D asset managed in the panel — see Product lifecycle.

Only show the button once the product is both on and ready — check tryon_status == "active" and swap_ready == true when you render the page. Then drop these two snippets on the product page:

Your product page
<!-- 1. The button your customer clicks (style it however you like) -->
<button type="button" data-tryon-product-id="9c1e2f3a-4b5c-4d6e-8f7a-1234567890ab">Try On</button>
<!-- 2. The bootstrap script for THIS product -->
<script async
src="https://api.integration.tryonvirtual.com/api/v1/tryon/scripts/embed/bootstrap.js?shop_slug=YOUR_SHOP_SLUG&productId=9c1e2f3a-4b5c-4d6e-8f7a-1234567890ab">
</script>

Find your shop slug in the panel under Settings → Shop. The script ships with the product’s try-on manifest already inlined, so there’s no extra round-trip when a customer clicks the button. Any element with data-tryon-product-id binds automatically — you can also call window.openTryOn() from your own code.

Authentication — key format, rotation, and revocation.