Skip to content

Ziex Try-On for developers

Ziex Try-On lets a shopper see a garment on their own photo. You add it to a shop in one of two ways:

  • The widget on a product page. One script tag and one TryOn.init(...) call. The shopper's browser talks to the Ziex Try-On API directly; your server is not involved. This is what the WooCommerce plugin and the 1C-Bitrix module do for you.
  • The API from your own server. You send the shopper's photo and the garment, get a job id, and read the result by polling or from a webhook. Use it when the photos come from your backend, from an app, or from a flow that is not a product page.

The two ways can be combined: the widget on the page, your server reading the same account's jobs.

The API reference is generated from the published OpenAPI document, /api/v1/openapi.json. Base URL: https://api.ziex-tryon.com. All API paths start with /api/v1/tryon.

Keys

Every request carries a key in the X-API-Key header. There are three kinds, and the difference matters.

Secret key Publishable key Test keys
Looks like tryon_… pk_… tryon_test_… and pk_test_…
Where it may live Your server only A public page Your server / a dev stand
Works on Every endpoint POST /tryon, GET /tryon/status/{job_id}, GET /tryon/attempts/{key}, GET /tryon/result/{job_id}, GET /tryon/domain-check Same as the live key it mirrors
Needs Origin / Referer No Yes, and a bound domain Yes for pk_test_…; see Local development
webhook_url in the request Allowed Refused (403 WEBHOOK_NOT_ALLOWED) Allowed for tryon_test_… only
Shopper's photo URL or upload Upload only (422 PHOTO_UPLOAD_REQUIRED for a URL) Upload only, both kinds
Spends the plan Yes Yes Never

Secret key (tryon_…)

Use it from a server. Never put it in page source, in a mobile app, or in a repository that others can read: the same key also signs you in to the client portal at https://app.ziex-tryon.com, where your shoppers' photos and results are visible. A secret key that arrives with a browser Origin header is not refused, but your account marks it with a warning.

A secret key sees the jobs of your whole account (live jobs only).

Publishable key (pk_…)

The only key a public page may carry. It is the same key as your secret key with fewer rights, and it is public by design: anyone can copy it from the page source. So it is fenced in:

  • It works only from a browser page: every request must carry Origin or Referer, and the key must be bound to your shop's domain. The domain, www. and any subdomain are accepted; another website gets 403 DOMAIN_NOT_ALLOWED. A key with no bound domain gets 403 KEY_NOT_BOUND.
  • It accepts only the five endpoints listed above, and reads only the jobs that this key created.
  • It cannot ask for a webhook: webhook_url in the request is 403 WEBHOOK_NOT_ALLOWED.
  • The shopper's photo must be sent as an upload (a data URI), never as a URL. The garment may stay a URL.
  • It is limited per (key, client IP): 10 created jobs per 10 minutes.
  • It cannot sign in to the portal.

Live and test keys

A test key (tryon_test_… secret, pk_test_… publishable) goes through the real API path - the same validation, image checks, idempotency and answers - but spends no money and no plan: the "try-on" ends in a simulated result after a few seconds. Test keys have their own isolation: a test key sees only its own test jobs, a live key never sees them, and a test key cannot sign in to the portal. They are issued by you, in the client portal, up to 3 per account. See Local development.

The life of a job

  1. POST /api/v1/tryon with the shopper's photo (model_image) and the garment (garment_image). The answer is 201 with a job_id, the header X-Job-Id and the Location of the status URL. Send an Idempotency-Key so that a repeated request can never create a second job.
  2. The job is pending while it waits for a worker, then processing.
  3. It ends as completed (with a result_url), or failed / interrupted (with an error_code and a safe error_message).
  4. You learn the outcome by polling GET /api/v1/tryon/status/{job_id}, or from a webhook if you gave a webhook_url (secret key only). The widget polls for you.

Every job reaches a final state within 45 minutes, whatever happens. Webhooks are best effort: if yours is down, the status endpoint still tells the truth, so keep polling as the fallback.

If the answer to the POST is lost (a dropped connection, a timeout), do not submit again under a new key: ask GET /api/v1/tryon/attempts/{idempotency_key} for the job instead. Both pages of the quickstart show the details.

Plan, limits and refunds as you see them

  • Plan. Your plan gives a number of generations per period. A created job takes one; when the plan is used up, POST /tryon answers 429 LIMIT_EXCEEDED with a Retry-After until the period resets. The plan figure is enforced with a small tolerance of 10 %.
  • Rate limits. There are per-IP limits (30 submits a minute, plus nginx's own request rates), a per-key hourly limit and daily caps (no single key may use more than half of the platform's daily cap). Every 429, 409 and 503 carries Retry-After in seconds: wait that long. A server that sends all its shoppers' requests from one address shares one per-IP budget.
  • Refunds. A job that ends failed or interrupted gives its generation back to your plan automatically, shortly after, once, and only in the period it was charged in. A completed job is never refunded. A request that is refused before a job exists (a bad photo, a limit) takes nothing.
  • Cost. Ziex Try-On never shows what a generation costs us; cost_credits in the status is always null.
  • Photos. Uploaded photos and results are kept for 180 days and then deleted. Test uploads are kept for 72 hours.

Where to go next

You want to… Read
Put the widget on a page with plain HTML Quickstart A - bare HTML
Submit try-ons from your server Quickstart B - server-side
Develop on localhost or a staging host with no cost Local development
Look up widget options, events and update() Widget reference
Load the widget lazily without losing a try-on in progress Lazy loading and pickup
Allow the widget under a Content Security Policy Content Security Policy
Find every endpoint, field and error API reference
Ask a question Contact

More pages cover webhooks, the full error and limit tables, test keys, identifying your integration, compatibility and the changelog, building a plugin, and the privacy text for shops.