Skip to content

Images

Images are what trigger try-on processing (see Product lifecycle), so getting them attached successfully matters more than any other step.

There are two ways to attach an image to a product, both on the same endpoint, POST /v1/products/{id}/images.

By URL — send JSON with a public url and we download it:

Request — by URL
curl -X POST https://api.integration.tryonvirtual.com/v1/products/{id}/images \
-H "Authorization: Bearer tryon_sk_your_key" \
-H "Content-Type: application/json" \
-d '{"url": "https://yourstore.com/images/aviator.jpg"}'

By upload — send a multipart form with an image file field:

Request — by upload
curl -X POST https://api.integration.tryonvirtual.com/v1/products/{id}/images \
-H "Authorization: Bearer tryon_sk_your_key" \

Both paths share the same limits:

  • Max size: 15 MB
  • Allowed types: JPEG, PNG, WebP, GIF
  • URL fetches time out after 10 seconds
  • URLs must be publicly reachable — a URL your servers can fetch but the public internet can’t (localhost, an internal/private network address, anything behind auth) will fail as unreachable_url

You can also pass up to 10 image URLs directly in the images array on POST /v1/products at create time — same limits, same failure behavior.

The first image you add becomes the product’s primary image — this is the one used as image_url on the product and, generally, in the try-on preview. If you’re adding images one at a time, add the one you want as primary first.

When you pass images on POST /v1/products, the product is still created even if some (or all) of the image URLs fail — the request never fails just because an image did. Failures are reported per-URL in images_failed, alongside the created product:

Response — partial success
{
"product": { "...": "..." },
"images_failed": [
{
"url": "https://yourstore.com/images/missing.jpg",
"code": "unreachable_url",
"message": "Could not fetch image: connection timed out"
}
]
}

Check images_failed on every create call that includes images — a product can come back with images: [] if every URL in the batch failed, and it will never reach swap_ready: true until you add one that succeeds.

When you add a single image via POST /v1/products/{id}/images instead, a failure returns a 400 with the same error code directly in the response body (see Errors and limits for the envelope shape), rather than in an images_failed array — there’s only one image to report on.

Code Meaning
invalid_url The url field isn’t a well-formed URL
unreachable_url We couldn’t fetch it — timed out, DNS failure, non-2xx response, or the host isn’t publicly reachable
not_an_image The URL resolved, but the content isn’t JPEG, PNG, WebP, or GIF
too_large The file is over 15 MB
Request
curl -X DELETE https://api.integration.tryonvirtual.com/v1/products/{id}/images/{image_id} \
-H "Authorization: Bearer tryon_sk_your_key"

Returns {"deleted": true}, or a 404 if the image (or the product) doesn’t belong to your shop. Re-fetch the product afterward to see the current images array, primary image, and swap_ready state — a product with no remaining images can’t stay try-on-ready.

Errors and limits — the full error envelope, rate limits, and pagination.