Endpoints
Create try-on
Start a try-on from a photo of a person and an image of a garment. The call returns straight away with an id; the image is made in the background and you poll for it.
POSThttps://fabricvton-api.onrender.com/api/v1/tryons
This is the endpoint to use behind a storefront: your server answers the shopper's browser immediately and can show progress while it polls. If you'd rather make one blocking call, see Create try-on (sync).
Headers
| Header | Type | Description |
|---|---|---|
Authorization | required | Bearer followed by your API key. |
Idempotency-Key | required | 8–128 characters: letters, digits, _ or -. Use a new one for each try-on (a UUID is ideal) and the same one when you retry. A key you've already used gives you back that earlier try-on instead of starting — and charging for — another. |
Content-Type | required | application/json |
Body
Give each image either as a URL or as the id of an image you uploaded — exactly one of the two for the person, and exactly one for the garment. You can mix them: an uploaded shopper photo with a garment URL from your CDN is the most common pairing.
| Field | Type | Description |
|---|---|---|
personImageUrl | string | HTTPS URL of a photo of one adult, ideally full-length and facing the camera. |
personImageId | string | Instead of personImageUrl: an img_… id from POST /images, uploaded by this account in the last 24 hours. |
garmentImageUrl | string | HTTPS URL of the product photo. One garment per image works best. |
garmentImageId | string | Instead of garmentImageUrl: an uploaded image id. |
title | string, optional | The product's name, such as “Linen summer dress”, up to 120 characters. It tells the engine what kind of garment it is placing, which improves the fit and placement. |
consent | boolean, required | Must be true. By sending it you confirm the person in the photo is an adult who agreed to the photo being used for a try-on, and that you have the rights to use both images. |
Rules for image URLs
- HTTPS on the default port.
- The URL returns the image itself with HTTP 200. Redirects are not followed.
- It responds within 12 seconds.
- The file is a JPEG or PNG, no larger than 4 MB.
Signed URLs are fine as long as they're still valid when the request arrives. Uploaded images skip these rules entirely, which is one reason to prefer them for shopper photos.
Example
curl -X POST https://fabricvton-api.onrender.com/api/v1/tryons \
-H "Authorization: Bearer $CLOTHSY_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"personImageId": "img_5Hq2mV8xKc3TnR7w",
"garmentImageUrl": "https://your-cdn.example.com/denim-jacket.jpg",
"title": "Cropped denim jacket",
"consent": true
}'The SDK creates an Idempotency-Key for you and reuses it if it has to retry. Pass idempotencyKey yourself when your own code might repeat the call — for example, one key per shopper click.
Response
{
"id": "7f3c2a9e-1d4b-4c1e-9a55-2b8f0c6d4e10",
"status": "pending",
"pollUrl": "/api/v1/tryons/7f3c2a9e-1d4b-4c1e-9a55-2b8f0c6d4e10"
}| Field | Type | Description |
|---|---|---|
id | string | The try-on's id. Keep it to poll. |
status | string | Always pending here. |
pollUrl | string | Where to poll, relative to https://fabricvton-api.onrender.com. It's the same as GET /tryons/{id}. |
Credits
A finished try-on costs 1 credit. If it fails, or can't be started, the credit comes back automatically — you only pay for results. Sending the same Idempotency-Key again returns the original try-on and never charges twice.
Rate limit
Each account can start 12 try-ons a minute. Need more at peak times? Email us and we'll raise it.
Errors
| Status | Code | When |
|---|---|---|
| 400 | MISSING_IDEMPOTENCY_KEY | The Idempotency-Key header is missing or not 8–128 allowed characters. |
| 400 | INVALID_IMAGE_URL | An image URL isn't HTTPS, uses a non-default port, or points at a private address. |
| 400 | IMAGE_DOWNLOAD_FAILED | An image URL didn't return the image with HTTP 200 within 12 seconds (redirects count as failures). |
| 400 | UNSUPPORTED_IMAGE | An image isn't a JPEG or PNG. |
| 400 | INVALID_IMAGE_ID | An image id is unknown, older than 24 hours, or was uploaded by another account. |
| 401 | INVALID_API_KEY | The key is missing, malformed or revoked. |
| 402 | INSUFFICIENT_CREDITS | The account has no credits left. |
| 403 | CONSENT_REQUIRED | consent wasn't true. |
| 413 | IMAGE_TOO_LARGE | An image is larger than 4 MB. |
| 422 | PERSON_PHOTO_REJECTED | The person photo doesn't clearly show exactly one adult. |
| 422 | IMAGE_REJECTED | An image can't be used for a try-on. |
| 422 | GARMENT_REJECTED | This item isn't available for virtual try-on. |
| 429 | RATE_LIMITED | More than 12 try-ons started in a minute. Wait for the Retry-After header. |
| 500 | INTERNAL_ERROR | Something went wrong on our side. Retry with the same Idempotency-Key. |
| 502 | START_FAILED | The try-on couldn't be started and no credit was used. Retry with the same Idempotency-Key. |
| 503 | UNAVAILABLE | Try-on is briefly unavailable. Retry after a short wait. |
Some problems only show up once the image is being made. Those don't arrive as HTTP errors here: the try-on ends with status: "failed" when you poll it, and the credit is returned. See Errors & limits for retry advice.

