Developers
API reference
Base URL https://www.zedaq.ai. JSON in, JSON out. Call the REST API from your server; for a no-code storefront, use the script-tag widget. On Shopify, install the app instead.
Authentication
Create a key under Dashboard → API keys and send it in the x-api-keyheader. Keys are stored as SHA-256 hashes, so copy yours when it’s shown. Keep server keys on your server. You can lock a key to your domains; requests from any other origin are refused.
curl https://www.zedaq.ai/api/v1/size-chart?chest_cm=96 \
-H "x-api-key: zdq_live_..."Endpoints
| Endpoint | Usage | What it does |
|---|---|---|
POST /api/v1/tryon | 1 try-on | Renders your product on the shopper's photo. |
GET /api/v1/tryon/status/{job_id} | Charged on success only | Polls a render that returned 202. |
POST /api/v1/scan | 1 measurement | Body measurements and size from on-device pose data. |
GET /api/v1/size-chart | Free | Size for known measurements. |
GET / POST /api/v1/eyewear/catalog · /api/v1/eyewear/tryon | Catalog free · 1 try-on | Frame catalog and try-on metering. |
POST /api/v1/tryon
Send the shopper’s photo and your product image as base64 (JPEG or PNG; a full-length photo around 800px wide works well). garment_type is optional: upper_body, lower_body or dresses.
POST /api/v1/tryon
x-api-key: zdq_live_...
Content-Type: application/json
{ "person_image_base64": "...", "product_image_base64": "...", "garment_type": "upper_body" }
200 { "image_base64": "...", "mime_type": "image/png", "brand": { "corporate_name": "..." } }
202 { "status": "pending", "job_id": "...", "poll_url": "/api/v1/tryon/status/..." }A 202 means the render is still running: poll poll_url every 2 seconds until it returns 200 with the image. Usage is only charged once a render succeeds.
POST /api/v1/scan
Turns pixel measurements from on-device pose detection into body measurements and a size. The photo itself is never sent. In the browser, load https://www.zedaq.ai/widget/zedaq-scan.js and call ZedaqScan.measure(file, heightCm): it returns the request body for you.
POST /api/v1/scan
{ "height_cm": 170, "person_height_px": 1480,
"front_body_widths_px": { "chest": 270, "waist": 225, "hips": 285 },
"garment_category": "dress" }
200 {
"measurements": { "height_cm": 170, "chest_cm": 94.2, "waist_cm": 76.8, "hips_cm": 100.5 },
"store_size": { "label": "M", "fit": "good", "deciding_measurement": "hips", "garment_category": "dress" },
"size": { "alpha": "M", "UK": "UK 12 · M", "US": "US 8 · M", "EU": "EU 40 · M", "AU": "AU 12 · M" }
}store_size comes from your own size chart (Dashboard → Size charts), one chart per garment category: top, outerwear, dress, bottom. It sizes up to the largest measurement that matters for the garment. fit: "between" means the shopper sits between sizes. Without a chart, store_size is null and size gives standard regional sizes. A two-photo A4-calibrated mode is also accepted (front_a4_corners_px, side_a4_corners_px, front_body_widths_px, side_body_depths_px).
GET /api/v1/size-chart
Free. Query chest_cm (required), optional waist_cm, hips_cm and garment_category. Returns store_size plus standard sizes, as above.
Script-tag widget
Adds a “Try it on” button and “Find my size” to product pages on WooCommerce, Wix, Squarespace, BigCommerce or custom sites. The key is visible in your page source, so it must be locked to your domain; unlocked keys are refused.
<script src="https://www.zedaq.ai/widget/zedaq.js"
data-key="YOUR_WIDGET_KEY"
data-garment-type="upper_body"
defer></script>Optional: data-target (CSS selector for an inline button instead of the floating one), data-product-image (defaults to your product gallery or og:image), data-button-label, data-size="off". Product images are fetched from your own domain or common store CDNs only.
Errors and limits
Errors return { "error": "code", "message": "..." }.
missing_api_key: Missing x-api-key header.invalid_api_key: Invalid or revoked API key.brand_inactive: This account is not active.trial_expired: Your free trial has ended — add billing to keep going.trial_limit_reached: You've used all of your trial's free calls this cycle.demo_limit_reached: Our demo is getting a lot of traffic right now — please try again shortly, or sign up to try it on your own store.domain_not_allowed: This key isn't authorized for the domain this request came from.tryon_cap_reached: You've used all of your plan's try-on renders this month — upgrade for more.measurement_cap_reached: You've used all of your plan's measurements this month — upgrade for more.rate_limited: The platform is at its global request limit right now — please retry shortly.domain_lock_required(widget only): Lock this key to your store’s domain before using it in a script tag.
Monthly try-on and measurement caps depend on your plan; see pricing. Size lookups are free.