Virtual Try-On API: The Complete Integration Guide
Send a garment photo and a person photo. Get back a photorealistic image of that person wearing that garment. That's the entire virtual try-on API in one sentence. This page covers everything past that sentence: how the generation actually works, the exact request and response shapes, real pricing, how it stacks up against the other try-on APIs developers compare it to, and where teams plug it in.
$0.12
per generation, at volume
No subscription, no seat fee, no charge for a failed or filtered generation. You pay for images you actually receive.
What Is a Virtual Try-On API
A virtual try-on API is a backend service you call over HTTPS. You are not licensing a 3D engine, training a model, or hiring a computer-vision team. You're sending two images to an endpoint and getting a third one back. Everything that makes the output look real, garment texture, drape, lighting, body shape, happens on the provider's infrastructure, not yours.
This is a meaningfully different proposition from the "virtual try-on" most shoppers picture: an AR mirror in a flagship store, or a 3D avatar you rotate with a mouse. Those approaches exist, and they're expensive. AR needs a depth sensor or a phone with ARKit/ARCore support, and 3D garment modeling means someone on your team (or a studio you pay) has to build a rigged 3D asset for every SKU before a shopper can try anything on. A generative virtual try-on API skips both. It works from ordinary 2D photographs, the same product shots already sitting in your catalog, and any photo a shopper uploads from their phone, and produces a photorealistic 2D result. No 3D pipeline, no depth camera, no per-SKU modeling cost.
That distinction is why this category grew as fast as it did. A 3D or AR approach requires a hardware decision and a content pipeline before a single shopper sees a result. An API-based approach requires a product photo you already have and a person photo the shopper supplies in the moment. The barrier to shipping drops from "months of asset production" to "one HTTP request."
This also changes who can realistically ship the feature. A five-person team with a Shopify store and a weekend can integrate the raw API in an afternoon. A 200-person retailer with an in-house mobile app can drop the same endpoint into an existing checkout flow without touching their ML stack, because there isn't an ML stack to touch. The model, the GPUs, and the inference infrastructure live on the provider's side of the call. The API surface is identical whether the caller is a solo developer or an enterprise engineering team: a garment image goes in, a rendered image comes out.
In one line:
garment_image + person_image → rendered PNG. A single POST, authenticated with an API key, returning a usable image or a specific error code.
Virtual try-on API vs. AR try-on vs. 3D fitting
These three terms get used interchangeably in marketing copy, but they solve the problem in genuinely different ways, and the difference decides what you can build with each:
| Approach | Input required | Where it runs |
|---|---|---|
| Generative API (this page) | Two 2D photos: garment + person | Server-side, any device with a camera or upload |
| AR try-on | Depth camera or ARKit/ARCore-capable phone, live feed | On-device, real-time overlay |
| 3D fitting / avatar | A rigged 3D garment asset per SKU, body-scan or avatar | 3D engine, often a dedicated app |
AR try-on is strong for accessories that sit on a fixed point of the body, glasses, watches, some jewelry, where a live camera overlay tracks a face or wrist convincingly. It struggles with clothing, because fabric drapes, folds, and moves in ways a flat overlay can't simulate. 3D fitting can be genuinely accurate for fit and sizing, but the per-garment production cost (modeling, rigging, texturing) makes it impractical for a catalog with hundreds or thousands of SKUs that change every season. A generative API sidesteps both constraints by working directly from photographs you already have.
How the Generation Actually Works
From the caller's side, the API is a black box: two images go in, one comes out. But understanding what happens between the request and the response is worth five minutes, because it explains both why the results look as good as they do and where the edge cases come from. Three stages run in sequence:
- 1.Garment understanding. The garment photo is parsed for shape, fabric, color, and pattern, independent of whatever background or mannequin it was photographed on.
- 2.Person understanding. The person photo is parsed for pose, body proportions, and lighting, so the garment renders at the right scale and angle rather than looking pasted on.
- 3.Photorealistic composition. A generative model produces a new image combining both, matching shadows, fabric fold, and skin tone, rather than a flat overlay.
Why this beats a cutout overlay
The simplest way to fake a try-on is to cut the garment out of its product photo and paste it over the person photo, scaled to roughly the right size. This is cheap to build and looks wrong within a second of looking at it: the lighting on the garment doesn't match the lighting on the person, fabric that should fold at the elbow or waist stays flat, and the edges have the telltale soft halo of a background-removal tool. Shoppers have seen enough bad photo edits on the internet to clock this instantly, and a result that reads as fake does the opposite of what a try-on feature is supposed to do. It erodes trust right at the moment you're trying to build confidence in a purchase.
The generative approach produces a genuinely new image rather than compositing two existing ones. The model has learned what fabric does when a body moves under it, so a t-shirt sleeve creases at the shoulder, a dress hem follows the curve of the hips, and shadows from the person's own lighting fall correctly across the new garment. This is also why the output resolution and lighting quality of your person photo matters more than the garment photo's studio polish. The model is rebuilding the scene around the person, not gluing something onto them.
What makes an input photo work well
Because the model is doing real scene composition rather than a paste, input quality has a real, measurable effect on output quality. A few patterns hold consistently:
- Front-facing, full-body person photos produce the most reliable results. The model has an unobstructed view of where the garment needs to sit.
- Even, natural lighting beats harsh flash or backlighting, since the model has to infer shadow direction from what's already in the photo.
- A garment photographed flat, on a model, or on a mannequin all work. The model doesn't require a studio shot, but a garment that's heavily occluded by folds or props gives it less to work from.
- Reasonable resolution matters more than professional polish. A clear phone photo outperforms a blurry high-resolution one.
None of these are hard requirements. The API accepts ordinary phone photos and produces usable results from them, which is the entire point for a shopper-facing feature where you can't demand a studio shot from every visitor. But if you're building a product-photography pipeline rather than a live shopper flow, controlling for these factors on the input side will noticeably raise your output quality on the first try.
Integration: What the Request Looks Like
There's one endpoint. You authenticate with a header, send two images, and get a result. Here's the actual shape of the call:
curl -X POST https://www.tryoncloud.com/api/v1/generate \
-H "X-API-KEY: tk_dev_v1_yourkey" \
-F "garment_image=@garment.jpg" \
-F "person_image=@person.jpg" \
--output result.pngconst form = new FormData();
form.append("garment_image", garmentFile);
form.append("person_image", personFile);
const res = await fetch("https://www.tryoncloud.com/api/v1/generate", {
method: "POST",
headers: { "X-API-KEY": process.env.TRYONCLOUD_API_KEY },
body: form,
});
if (!res.ok) {
const { error, code } = await res.json();
throw new Error(`${code}: ${error}`);
}
const imageBuffer = await res.arrayBuffer(); // PNG bytesimport requests
res = requests.post(
"https://www.tryoncloud.com/api/v1/generate",
headers={"X-API-KEY": "tk_dev_v1_yourkey"},
files={
"garment_image": open("garment.jpg", "rb"),
"person_image": open("person.jpg", "rb"),
},
)
if res.status_code == 200:
with open("result.png", "wb") as f:
f.write(res.content)
else:
print(res.json()) # {"error": "...", "code": "..."}You can also send a garment as a public image URL instead of uploading the file directly, which is useful when the garment already lives on your CDN or product catalog. The API fetches it server-side, so your app never has to download and re-upload the same file.
What You Get Back
A successful request returns the rendered image directly as image/png. No wrapping JSON to unwrap, no polling a separate results endpoint for the common case. A failed request returns JSON with an error message and a specific code your app can branch on:
| Code | HTTP status | Meaning |
|---|---|---|
NO_KEY | 401 | Missing X-API-KEY header |
NO_CREDITS | 402 | Wallet balance is zero, top up to continue |
CONTENT_FILTERED | 422 | Image blocked by moderation (not charged) |
RATE_LIMITED | 429 | Over 300 requests/min on this key, back off and retry |
Every failure path refunds the credit before the error is returned. You're never billed for an image you didn't get.
Pricing
Pay per generation. No subscription, no monthly minimum, no seat-based pricing.
| Pack | Price per generation | Best for |
|---|---|---|
| Starter (50+ credits) | $0.22 | Testing integration, low-volume launch |
| Growth (300+ credits) | $0.16 | Active storefronts, small apps |
| Pay-as-you-go (1,000+ credits) | $0.12 | Production traffic, kiosks, high volume |
Credits never expire, and a failed generation refunds automatically. The numbers above are what you pay per image you actually receive.
How It Compares to Other Try-On APIs
Most virtual try-on APIs on the market solve the same core problem, garment + person into an image, and differ mainly in integration overhead, pricing shape, and what happens outside the happy path (failures, moderation, rate limits). If you've looked at more than one provider, you've probably noticed the marketing pages read almost identically: fast, photorealistic, developer-friendly. The differences that actually affect your build show up once you get past the landing page and into the docs. Here's what to check on any provider, including this one:
| What to check | Why it matters |
|---|---|
| Calls to get a result | Fewer round-trips means less to build and less that can fail mid-flow |
| Charged for failures? | Some providers bill you even when moderation blocks the image, so check the fine print |
| Rate limit ceiling | A limit tuned for demos will throttle you the day you get real traffic |
| SSRF / URL-fetch safety | If the API accepts a garment URL, it should validate that URL server-side before fetching it |
| Minimum commitment | Monthly minimums punish low-traffic months; pay-per-use doesn't |
| Credit expiry | Some platforms void unused credits after a fixed window, worth confirming before you prepay a large pack |
| Response format | A raw image response is simpler to handle than a JSON envelope you have to decode and re-fetch |
On the first two rows, call count and failure billing, this is where the difference between providers shows up fastest in a real integration. A two-call flow (upload, then generate) means your app has to hold state between the calls and handle the case where the second call fails after the first succeeded. A single-call flow removes that failure mode entirely, because there's nothing to leave half-finished. Similarly, whether a provider refunds a content-filtered or failed generation before you're billed is easy to overlook while reading a pricing page and expensive to discover in a monthly invoice. Moderation rejections aren't rare at meaningful volume, since real shoppers upload real photos with real lighting problems, cropped frames, and the occasional inappropriate image.
TryOnCloud's API is a single POST call. No upload step, no polling loop for the standard case. It never bills a filtered or failed generation, runs a 300 req/min per-key limit (well above what most storefronts need even during a traffic spike), validates any garment URL server-side before fetching it, and has zero minimum commitment at any tier. Credits are purchased once and don't expire on a clock.
Who Actually Uses This API
The same endpoint gets called from very different contexts, because the underlying need (turning a garment photo and a person photo into a rendered image) shows up in more places than just "try-on button on a product page." Five patterns come up repeatedly:
- Custom storefronts. Teams not on Shopify, running a headless commerce build, a bespoke Next.js or Django storefront, or a marketplace, who want a "Try It On" button without adopting an app platform they don't otherwise need. The API is the same regardless of what's rendering the storefront around it.
- In-store kiosks. A touchscreen in a physical store calling the same endpoint a webstore uses, so catalog data, pricing logic, and generation quality stay in one place instead of maintaining two separate integrations for online and in-store.
- Product photography pipelines. Putting an existing garment photo onto a model image for a catalog listing, instead of running a physical photoshoot for every SKU. This use case doesn't involve a live shopper at all. It's a backend job that runs against your product database.
- Mobile apps. Native iOS/Android apps that need try-on as a feature without embedding an ML model on-device, which would bloat the app and still need a server fallback for older phones anyway.
- Agencies and platforms. Building the feature once behind their own branding and reselling it across multiple retail clients on different storefront platforms. The API doesn't care what's calling it, so one integration serves every client.
What these five have in common is that none of them require the caller to know anything about how the generation works internally. A kiosk vendor doesn't need a computer-vision background to integrate this any more than a storefront developer does. The API abstracts the model away entirely, which is the actual value being sold here, more than the specific pixels in the output.
Security & Content Moderation
A try-on API sits in an unusual security position. It's usually one hop away from anonymous, public input, because the whole point is that a shopper, someone your backend has never seen before and has no reason to trust, is uploading a photo of themselves. Any provider you integrate needs to take that seriously on your behalf, because your app is the one that inherits the consequences of a gap.
Content moderation runs on every request and rejects inappropriate garment or person images before a result is generated. This is enforced server-side and cannot be disabled per-key, which matters if you're building a public-facing feature and don't want to build your own moderation layer from scratch. A rejected request returns the CONTENT_FILTERED code rather than a generic failure, so your UI can show a specific, helpful message instead of a dead end.
If a garment is supplied as a URL rather than an uploaded file, that URL is validated against internal and private IP ranges before the server fetches it. This closes off Server-Side Request Forgery (SSRF), a class of attack where a malicious caller supplies a URL pointing at an internal service (a cloud metadata endpoint, an internal admin panel, a database on a private network) hoping the server will fetch it on their behalf and leak the response. Any API that accepts an arbitrary URL and fetches it server-side needs this check; it's one of the more common gaps in image-processing APIs generally, not specific to this category.
Wallet consumption is atomic. A burst of concurrent requests from the same key cannot double-spend a credit balance, which matters under real traffic where dozens of requests can land within the same millisecond window. A failed generation refunds before your app ever sees the error, so a spike in failed requests (bad uploads, a transient model error) never quietly drains your balance.
Handling errors well in your integration
The four error codes documented above aren't just for logging. Each one implies a different response in your UI, and handling them distinctly is the difference between an integration that feels polished and one that just shows a generic "something went wrong" banner:
NO_KEY: a configuration problem on your side, not the user's. Fix before shipping; a real shopper should never see this.NO_CREDITS: surface this to whoever owns the wallet (you, or the merchant if you're building for others), not the end shopper. It means top-up is needed, not that the shopper did anything wrong.CONTENT_FILTERED: show the shopper a specific message ("please use an appropriate photo") rather than a generic error, since this is actionable on their end.RATE_LIMITED: retry with backoff. At 300 requests/minute per key, hitting this in production usually means a retry loop without backoff somewhere upstream, worth checking before assuming you need a higher limit.
Why Teams Choose TryOnCloud's API
TryOnCloud started as a Shopify app before the raw API existed. The API is the same generation engine that already runs live on thousands of fashion storefronts, exposed directly for teams who need to build their own experience instead of installing an app. That ordering matters: the pipeline was hardened against real shopper traffic (inconsistent lighting, cropped photos, unusual poses, adversarial uploads) long before a single developer called the raw endpoint. You're not integrating a model still finding its footing; you're integrating the same one already absorbing production load elsewhere.
One call, real image back
No polling loop required for the standard case. The PNG comes back in the same response.
Never billed for a miss
Content-filtered and failed generations are refunded automatically, before the error reaches you.
No infrastructure to run
No GPUs, no model weights, no uptime pager. That's on us, not your on-call rotation.
Same engine as our Shopify app
This isn't a stripped-down demo model. It's the identical pipeline live on thousands of storefronts today.
Getting started
There's no application, no approval queue, and no sales call between you and a working key. Sign up, open Developer API in the dashboard, and create a key. It's shown to you once, in full, so store it in an environment variable immediately rather than a config file you might commit. From there:
- 1.Create your key in the dashboard under Developer API.
- 2.Send a test request with any garment and person photo using the cURL example above. You'll get a real rendered PNG back, not a placeholder.
- 3.Wire the same call into your app's upload flow, handling the four error codes distinctly as described above.
- 4.Top up credits when you're ready for production traffic. Pay-as-you-go pricing kicks in automatically at volume, no plan change required.
If you're using an AI coding assistant like Cursor or Claude to write the integration, the developer docs include a ready-to-paste prompt containing the full API contract, so the assistant produces a correct integration for your specific stack in one pass instead of guessing at the request shape.
Full endpoint reference, authentication details, and usage-tracking are in the developer docs. If you're building on React or Next.js specifically, the React & Next.js integration guide has a complete drop-in component and a secure server-side proxy pattern. Shopify merchants who want a no-code button instead of a raw API should see the Shopify virtual try-on setup guide, same engine, zero code. Teams evaluating whether to build the feature at all first might find the virtual fitting room guide useful background before touching any code.
Get an API Key
Pay per generation from $0.12. No subscription, no minimum, credits never expire.