Tutorial
Google Virtual Try-On API Guide
Submit person and garment images through HiAPI, query the task result, and use the API without a prompt.
- Per image
- $0.1075
Keep the two image roles separate: the person photo belongs in person_image_url, and the garment photo belongs in product_image_url. Putting a person photo in the garment field changes what the request supplies.
TL;DR
Google Virtual Try-On costs $0.1075 per image; see pricing and budgets. Use HiAPI /v1/tasks: submit a task to obtain a taskId, then query its result. No prompt is required.
Prepare the input and fields
Choose a single front-facing person with the body clearly visible. For the garment, use a clean flat lay or hanging photo with complete edges. The two permanent image URLs below identify person A and the red-and-white striped T-shirt; replace them with your own public image URLs.
| Field | What to send |
|---|---|
person_image_url |
Required public HTTP(S) URL for the person photo |
product_image_url |
Required public HTTP(S) URL for the garment photo |
num_images |
Integer; explicitly set 1, the only supported count |
Map outfit combinations to requests
For one person trying different garments, keep person_image_url fixed and replace product_image_url for each item. For one garment on different people, keep the product image and replace the person image. For candidates from the same pairing, keep both images and submit separately with num_images: 1 each time. Record the product identifier and person-image version rather than guessing the pairing from an output filename.
Both inputs require publicly readable HTTP(S) image addresses. A local disk path or data URI is not an image URL. Visibility in a logged-in browser does not establish access by another service; check links without depending on a login session. Confirm that the response is the image itself rather than an album or permission page, and keep it accessible while the task reads it.
If the person photo hides the hem or has extensive overlap between hands and clothing, consider a photo with clearer boundaries. Prefer a complete flat lay or hanging photo of an individual garment. Avoid mistaking an on-body result for the independent product input. The public fields provide no region protection, cuff adjustment or shoe-lock setting; adding custom fields cannot express those requirements.
Clear inputs are a working recommendation. Whether the interface accepts an image and whether the result describes the product accurately are separate checks. This guide adds no unsupported file-size, pixel or output-size promises for Try-On. Limits from other image models cannot be applied to it automatically.
Submit a task with cURL
This is a Bash/cURL example. Configure HIAPI_API_KEY in the runtime environment first. You can replace the image URLs; keep the key in the server environment.
curl -X POST "https://api.hiapi.ai/v1/tasks" \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "google-virtual-try-on",
"input": {
"person_image_url": "https://static.hiapi.ai/gallery/2026/10/9f656c8b6ecf94d5.webp",
"product_image_url": "https://static.hiapi.ai/model-covers/2026/10/22/1792660602486-b5b70d2cfdd8dc95-1792152569828-b5b70d2cfdd8dc95-t-g1-0.webp",
"num_images": 1
}
}'
A successful submission returns data.taskId. Save that value for later queries.
Query the task and save the result
Put the task identifier in TASK_ID, then query it:
curl "https://api.hiapi.ai/v1/tasks/$TASK_ID" \
-H "Authorization: Bearer $HIAPI_API_KEY"
When the task reaches data.status=success, get the image from data.output[0].url and save it. For ongoing workloads, set top-level callback.url and callback.when: "final" in the submission to receive terminal notifications, and deduplicate by taskId. Both success and failure can trigger a notification. Querying is useful for debugging and reconciliation.
Polling, callbacks and timeouts
Submission and querying are separate actions. Once you have data.taskId, record it with the input and query GET /v1/tasks/:id. If the task has not reached a terminal state, keep waiting rather than replacing a query with another POST. Your application chooses its polling interval and business waiting limit. There is no established average duration or completion deadline to promise here, and the example's network timeout is not a service-duration guarantee.
A query timeout means that particular read did not finish in time. Retain the identifier and query the same task later. If submission itself times out without an identifier, whether the server accepted it is uncertain. Keep the submission time and request content, reconcile the task records, then decide whether to submit again. Do not interpret a client exception as task failure or promise that duplicate requests will merge automatically.
Put callback configuration at the top level, alongside model and input, rather than inside the model input. Use callback.when: "final" with callback.url. A terminal notification can indicate success or failure, so inspect its status. A query and a callback may reach the same task; deduplicate by taskId in your application to avoid repeated downloads or downstream work. This is an application handling recommendation, not a promise of callback delivery within a particular period.
After data.status=success, check that data.output contains a readable result URL before downloading. If the status is fail, retain the error information and correct the request accordingly. A status alone cannot establish whether the cause was file size, networking or another issue. Preserve unexpected responses or missing output for reconciliation rather than treating an empty result as delivered work.
Distinguish a download failure from a generation failure. If the task succeeded but the file was not saved, try reading or downloading the existing result before generating another image. Archive the task identifier, input mapping and final file location so each image can be traced to its request. A user-facing waiting timeout should mean the interface stopped waiting, rather than declaring that the server cancelled the task.
Python submission example
Install requests in the environment. The timeout=60 value is a client network timeout, not the image generation time.
import os
import requests
payload = {'model': 'google-virtual-try-on', 'input': {'person_image_url': 'https://static.hiapi.ai/gallery/2026/10/9f656c8b6ecf94d5.webp', 'product_image_url': 'https://static.hiapi.ai/model-covers/2026/10/22/1792660602486-b5b70d2cfdd8dc95-1792152569828-b5b70d2cfdd8dc95-t-g1-0.webp', 'num_images': 1}}
response = requests.post(
"https://api.hiapi.ai/v1/tasks",
headers={"Authorization": f"Bearer {os.environ['HIAPI_API_KEY']}"},
json=payload,
timeout=60,
)
response.raise_for_status()
result = response.json()
task_id = result["data"]["taskId"]
print(task_id)
Check inputs and results
No prompt is needed. Do not set num_images to 2 or 4; submit separate requests for candidates. Before submission, check that both URLs are publicly readable and assigned to the correct fields. If a task fails, inspect its returned information and fix the input before submitting again.
Accept results against the product brief
Compare the result with the person photo for the face, hair, pose, background and any trousers or shoes that must stay unchanged. Then compare it with the garment photo for color, neckline, sleeve length, pattern and hem. Inspect stripe transitions across the chest and sleeves of the T-shirt; straps, the draped neckline and folds around the hand in the dress; and rolled cuffs and a tucked hem in the shirt. These checks follow visible changes in the examples without limiting what other inputs may change.
Record “file downloaded” separately from “approved for the product page.” A successful task can still alter areas outside the garment, so its status cannot replace visual acceptance. If occlusion in the input caused the problem, change the input before another attempt. Where a product must show a specific sleeve length or fixed accessories, assess that requirement even if the overall outfit looks natural.
Keep earlier results when adding candidates rather than overwriting them. Record why each candidate was accepted or rejected so similar products can use the same review approach. The images show appearance; physical sizing and comfort still require garment measurements and real fit information.
FAQ
Can both images use the same field?
No. Use person_image_url for the person and product_image_url for the garment.
Should I add a prompt parameter?
No. The input has no prompt field; the two images define the try-on.
Why explicitly set num_images to 1?
One result is currently supported. An explicit count keeps the request aligned with the $0.1075 per-image budget.
Does a taskId mean the image is ready?
You still need to query the task or receive a notification. Read the image from data.output[0].url after data.status=success.
Further reading
Pricing and budgets · API integration · Examples and input selection · Google Virtual Try-On
To choose a try-on or general editing approach, see Google Virtual Try-On versus Seedream 5.0 Lite, checking garments, footwear, and the person’s appearance.
Related articles
View all articles →-
Tutorial
Recraft Creative Upscale: Landscape Examples
Inspect cabin, lake and watercolor examples, identify redrawn detail, and distinguish previews from full-size results.
8 -
Tutorial
OpenAI Invalid API Key: Authentication Checks
Separate OpenAI 401, 403, and 429 errors. Check runtime variables, account context, and credentials with a read-only request.
3 -
Tutorial
Kling 4.0 Prompts: 6 Ready-to-Use Templates with Real Outputs
Product, food, travel, everyday moments, ambient shots with sound and image-to-video, each with a real clip, the full prompt and a one-click prefill link.
6