Guide
Errors & limits
Every error is JSON with a human-readable error and a stable code. Write your logic against code — the wording of error may improve over time.
{
"error": "Please use a clear photo of one adult person.",
"code": "PERSON_PHOTO_REJECTED"
}Error codes
| Status | Code | Meaning | What to do |
|---|---|---|---|
| 400 | MISSING_IDEMPOTENCY_KEY | No valid Idempotency-Key header. | Send 8–128 letters, digits, _ or -. |
| 400 | INVALID_IMAGE_URL | An image URL isn't HTTPS, uses a custom port, or points at a private address. | Use a public HTTPS URL. |
| 400 | IMAGE_DOWNLOAD_FAILED | An image URL couldn't be downloaded: not HTTP 200, a redirect, or too slow. | Check the URL loads the image directly; for signed URLs, check it hasn't expired. |
| 400 | UNSUPPORTED_IMAGE | An image isn't JPEG or PNG. | Convert it to JPEG. |
| 400 | INVALID_IMAGE_ID | An image id is unknown, has expired (older than 24 hours), or was uploaded by another account. | Upload the image again and use the new id. |
| 401 | INVALID_API_KEY | The key is missing, malformed or revoked. | Check the Authorization header. |
| 402 | INSUFFICIENT_CREDITS | The account has no credits left. | Top up; hide the try-on button until then. |
| 403 | CONSENT_REQUIRED | consent wasn't true. | Collect the shopper's agreement, then send consent: true. |
| 404 | NOT_FOUND | No try-on with that id on this account, or no endpoint at that path. | Check the id and the URL against the endpoint pages. |
| 405 | METHOD_NOT_ALLOWED | The endpoint doesn't accept that HTTP method. | Check the method, e.g. POST to /tryons, GET to /tryons/{id}. |
| 413 | IMAGE_TOO_LARGE | An image is larger than 4 MB. | Resize to about 1600 px before uploading. |
| 422 | PERSON_PHOTO_REJECTED | The photo needs to show exactly one adult, clearly. | Ask for a clear photo of just the shopper. |
| 422 | IMAGE_REJECTED | An image can't be used for a try-on. | Ask for a different photo. |
| 422 | GARMENT_REJECTED | This item isn't available for virtual try-on. | Hide the button for this product. |
| 429 | RATE_LIMITED | Too many requests. | Wait the number of seconds in the Retry-After header, then retry. |
| 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. No credit was used. | Retry with the same Idempotency-Key. |
| 503 | UNAVAILABLE | Try-on is temporarily unavailable. | Retry after a short wait. |
A try-on can also end with status: "failed" when you poll it — for example if the result doesn't pass our safety checks. That isn't an HTTP error: the response is 200, message says what happened, and the credit has already been returned.
Using the TypeScript SDK? Errors are thrown as typed classes that carry the same status and code.
Rate limits
| What | Limit |
|---|---|
| Starting try-ons | 12 a minute per account, shared by POST /tryons and POST /tryons/sync |
| Polling | 60 a minute per account — poll every 2–3 seconds |
| Uploading images | 30 a minute per account |
| Image size | 4 MB per image, JPEG or PNG |
| Uploaded image lifetime | 24 hours from upload; the id can't be used after that |
| Image URL fetch | HTTPS, default port, HTTP 200 without redirects, within 12 seconds |
| Sync wait | About 55 seconds, then /tryons/sync returns 202 and you poll |
| Result URL lifetime | 24 hours |
| API keys | One active key per account |
Over a limit, you get 429 RATE_LIMITED with a Retry-After header in seconds. Expecting more than 12 try-ons a minute at peak? Email us and we'll raise your limit.
Retrying safely
- Retry
429,500,502and503, and network timeouts, with the sameIdempotency-Key. You can never be charged twice for one key. - Don't retry
400,401,402,403,413or422unchanged — fix the request or ask the shopper for another photo first. - Back off between retries: wait 1 second, then 2, then 4, and give up after a few attempts.
- For
/tryons/sync, set your client timeout to at least 70 seconds. If the connection drops anyway, repeat the request with the sameIdempotency-Keyto pick the try-on back up. - The SDK does all of this for you: it retries network errors, 429, 500, 502 and 503 with backoff, honours
Retry-After, and keeps the same key.
Credits
- One credit per finished try-on. Failed try-ons are refunded automatically.
- Your first API key adds 20 free credits to the account, once.
- API try-ons use your account's credits. They don't use the monthly allowance of any Shopify or WooCommerce store you have connected.
- Need more? Email us to buy credits.

