ZeDaq.ai
Shopper using virtual try-on for a tailored suit

Calling a Try-On API From Python: A Worked Example

By the ZeDaq.ai team · · 4 min read

On this page
  1. What do you need before you start?
  2. What does the request look like?
  3. How do you write the script?
  4. How do you use it in a Flask route?
  5. How do you test the script?
  6. What should you check before going live?

This worked example is for calling a try-on API from Python: base64-encode the shopper's photo and your product image, send them in a JSON POST to the ZeDaq.ai /api/v1/tryon endpoint with an x-api-key header, and poll if you get a 202. The requests library keeps this short.

This worked example assumes you have read the virtual try-on API overview. The same call in other languages is in calling a try-on API from PHP and from Node.js. The endpoint is also in the API reference.

What do you need before you start?

  • A ZeDaq.ai API key from Dashboard → API keys.
  • Python 3 and the requests library (pip install requests).
  • A full-length photo of a person and an image of the garment, as JPEG or PNG.

The docs say a full-length photo around 800px wide works well. Keep the key in an environment variable, as covered in using an x-api-key header safely.

What does the request look like?

You send a JSON body to POST https://www.zedaq.ai/api/v1/tryon.

Field Required Meaning
person_image_base64 Yes The shopper's photo, base64 encoded
product_image_base64 Yes Your garment image, base64 encoded
garment_type No upper_body, lower_body or dresses

A 200 response returns image_base64 and mime_type. A 202 response means the render is still running and gives a job_id and a poll_url.

How do you write the script?

import base64
import os
import time
import requests

BASE = "https://www.zedaq.ai"
HEADERS = {"x-api-key": os.environ["ZEDAQ_API_KEY"]}


def b64(path):
    with open(path, "rb") as f:
        return base64.b64encode(f.read()).decode("ascii")


def try_on(person_path, product_path, garment_type="upper_body"):
    body = {
        "person_image_base64": b64(person_path),
        "product_image_base64": b64(product_path),
        "garment_type": garment_type,
    }
    r = requests.post(f"{BASE}/api/v1/tryon", json=body, headers=HEADERS, timeout=60)
    data = r.json()

    while r.status_code == 202:
        time.sleep(2)
        r = requests.get(BASE + data["poll_url"], headers=HEADERS, timeout=30)
        data = r.json()

    if r.status_code != 200:
        raise RuntimeError(f'{data.get("error")}: {data.get("message")}')
    return data


result = try_on("person.jpg", "shirt.png")
with open("result.png", "wb") as f:
    f.write(base64.b64decode(result["image_base64"]))

Why poll every 2 seconds?

The API reference says to poll the poll_url every 2 seconds until it returns 200 with the image. Usage is only charged once a render succeeds.

How do you handle errors?

Errors return { "error": "code", "message": "..." }. The script above raises with both fields, so your logs show the cause. Add a retry limit to the loop so a stuck job cannot run forever.

How do you use it in a Flask route?

Keep the key on the server and let your page call your own route. A minimal Flask version looks like this:

from flask import Flask, request, jsonify

app = Flask(__name__)


@app.post("/tryon")
def tryon_route():
    person = request.files["person"].read()
    product = request.files["product"].read()
    # Encode both files, call the ZeDaq.ai API as shown above, return the image
    return jsonify({"status": "ok"})

Fill in the middle with the same requests call. For a store without a custom backend, the WooCommerce route needs no code.

How do you test the script?

  1. Set the key in your shell: export ZEDAQ_API_KEY=....
  2. Put a clear full-length photo named person.jpg and a product image named shirt.png next to the script.
  3. Run python tryon.py and open result.png.
  4. Try a bad key on purpose and confirm that your error message shows the error code.
  5. Try a cropped photo and see how the result and the error handling behave.

How do you return the image from Flask?

Return the base64 string and MIME type as JSON, and let the page build a data: URL from them. This keeps your route simple and avoids storing result files on disk.

What about large batches?

If you render many products for one shopper, send the requests one after another and handle each 202 in turn. Keep the key on the server, and respect the monthly try-on cap on your plan.

What should you check before going live?

  • The key is read from an environment variable.
  • The loop has a retry limit.
  • You show the shopper a loading state while a 202 is pending.
  • You tested a person photo and a garment that differ from your examples.

Make your first try-on request from Python

FAQs

Which Python library should I use?

Any HTTP library works. The example uses requests because it is common and short.

Do I need to resize images first?

The docs say a full-length photo around 800px wide works well. Large files take longer to encode and send.

What does a 202 response mean?

The render is still running. Poll the poll_url until it returns 200 with the finished image.

Can I call this from the browser instead?

Keep the key on your server and call the API from there. Browser code exposes the key to anyone who views the source.

Try ZeDaq.ai free

Virtual try-on and Find my size for your store, plus client, order and invoicing tools for tailors, in one subscription.

Related articles