Handling Try-On API Errors and Retries
By the ZeDaq.ai team · · 5 min read
On this page
Handling try-on API errors starts with sorting every response into one of three groups: retry later, fix the request and resend, or stop and tell someone. Make retries only for errors that can clear on their own, and never retry the ones that need a change on your side.
This guide uses the ZeDaq.ai REST API as the example, because its error codes are documented. It is written for developers who have already read the try-on API overview for ecommerce developers and now need production-ready handling.
What does a try-on API response look like?
Errors from the ZeDaq.ai API come back as JSON with a code and a message: { "error": "code", "message": "..." }. The full list is in the API reference.
A successful try-on can answer in two ways. A 200 response contains the finished image. A 202 response means the render is still running, and it includes a job_id and a poll_url.
Which errors should you retry, and which should you not?
Group them by what you can do about them. The table below uses the codes from ZeDaq.ai's API reference, plus the 500 status the API returns for an internal error. Confirm statuses against the reference before you rely on them.
| Code | HTTP status | Group | What to do |
|---|---|---|---|
missing_api_key |
401 | Fix and resend | Add the x-api-key header |
invalid_api_key |
401 | Fix and resend | Check or replace the key |
domain_not_allowed |
403 | Fix and resend | Use a key authorized for that domain |
brand_inactive |
403 | Stop | Contact the account owner |
trial_expired |
402 | Stop | Add billing |
trial_limit_reached |
402 | Stop | Wait for the next cycle or upgrade |
tryon_cap_reached |
402 | Stop | Upgrade, or wait until next month |
measurement_cap_reached |
402 | Stop | Upgrade, or wait until next month |
rate_limited |
429 | Retry later | Back off, then retry |
demo_limit_reached |
429 | Retry later | Try again shortly, or use your own key |
internal_error |
500 | Retry later | Retry a small number of times |
Retrying a 401, 402 or 403 will not help, because the request fails for the same reason each time. Retrying a 429 or 500 often does, because the cause is temporary.
How do you retry safely?
Use exponential backoff with a limit. That means waiting a little longer after each failure and giving up after a few attempts.
- Wait before the first retry. A short pause is enough.
- Double the wait each time. Add a little random variation (jitter) so many clients do not retry at the same moment.
- Set a maximum number of attempts. Three or four is plenty for a shopper-facing feature.
- Stop and show a message. After the last attempt, tell the shopper something went wrong and let them try again.
Here is a simple pattern in JavaScript:
async function callTryOn(body, apiKey) {
const retryable = new Set([429, 500]);
let delay = 1000;
for (let attempt = 1; attempt <= 3; attempt++) {
const res = await fetch("https://www.zedaq.ai/api/v1/tryon", {
method: "POST",
headers: { "x-api-key": apiKey, "Content-Type": "application/json" },
body: JSON.stringify(body),
});
if (res.status === 200 || res.status === 202) return res.json();
if (!retryable.has(res.status) || attempt === 3) {
throw new Error((await res.json()).error ?? "unknown_error");
}
await new Promise((r) => setTimeout(r, delay + Math.random() * 250));
delay *= 2;
}
}
Call this from your server, not the browser, so the key stays private.
How do you handle a 202 response?
A 202 is not an error. It means the render is pending. The documentation says to poll the poll_url every 2 seconds until it returns 200 with the image.
Set a ceiling on polling so a stuck job does not run forever. When you reach it, stop and show a retry button. Keep the shopper informed with a loading state while you wait.
The API reference also states that usage is only charged once a render succeeds, so a failed render does not use up your allowance.
What counts as a timeout, and what should you do?
Two timeouts matter:
- Your request timeout. How long your server waits for the API to answer. Set one, so a slow network does not hang your page.
- Your polling ceiling. How long you wait for a pending render.
A timeout on your side does not always mean the render failed. The job may still finish. If you have a job_id, check the status endpoint once more before you start a new render, to avoid doing the same work twice.
How do you show errors to shoppers?
Shoppers should never see a raw error code. Map each group to a plain message:
- Temporary problem: "Try-on is busy right now. Please try again in a moment."
- Photo problem: "We could not use that photo. Try a full-length photo with good light."
- Store-side problem (for example a plan limit): "Try-on is not available right now." Log the real code for your team.
Do not tell shoppers that your plan limit is reached. Send that to your own alerting instead. For photo problems, see image preprocessing before sending a photo, which covers size and format.
How do you monitor errors and usage?
Log every non-200 response with its code, status and time. Count errors per code each day. A rise in rate_limited suggests you need better backoff. A cap error (tryon_cap_reached or measurement_cap_reached) tells you that you have used your plan's allowance.
Plan limits are part of forecasting. The guide to forecasting try-on API usage and cost shows how to estimate what you need before you reach a cap.
Good error handling also helps the shopper make better choices. A working size flow ties into clear sizing information, such as the points in writing size guides that actually reduce returns.
Build and test against the API
FAQs
Should I retry a 402 response?
No. A 402 means a plan or billing limit, and retrying will not change it. Fix the cause or wait for the next cycle.
Does a failed try-on use up my allowance?
According to the API reference, usage is charged only when a render succeeds. Check the reference for the current rules.
How long should I poll a pending render?
Poll every 2 seconds, as the documentation advises, and set your own ceiling. Stop at the ceiling and offer the shopper a retry.
Can I call the API directly from the browser?
The documentation says to call the REST API from your server. For browser use on a store, the domain-locked script-tag widget is the intended route.
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.


