Test keys¶
A test key lets you build and check a whole integration - a CMS module, a custom server, the widget on a development stand - without spending money and without waiting for us. A try-on made with a test key goes through the real API path: the same validation, image checks, idempotency and answers as a live key. Only the end is different: it finishes with a simulated result instead of a real generation.
What a test key is¶
| Secret test key | Publishable test key | |
|---|---|---|
| Looks like | tryon_test_ + 32 characters |
pk_test_ + 32 characters |
| Where it may live | Your server or dev stand | A page on a development host |
Needs Origin / Referer |
No | Yes (but no bound domain) |
- No plan, no money. A test try-on is free. It does not use your plan's quota, does not count against the daily caps and is not billed.
- Always a simulated result. After a few seconds the job ends
completedwith a placeholder: either the photo you uploaded or a fixed sample picture. Nothing is generated and no provider is called. - It is never a way to a live job. A test key cannot read live jobs, and a live key cannot read test jobs (see What a test key can see).
The shop-facing widget shows a TEST badge in the header of its window when its key is a test key, so nobody mistakes a test page for a real one.
Get a test key¶
Test keys are issued by you, in the client portal at https://app.ziex-tryon.com:
- Sign in with your live secret key. (A test key cannot sign in to the portal: see below.)
- Open the API keys page and create a test key. Give it a name and, if you need them, its allowed hosts.
- Copy the secret. It is shown once, in the dialog that creates the key. The publishable key (
pk_test_…) stays visible in the list.
Rules:
- Up to 3 test keys per account. Creating a fourth answers
409 TEST_KEY_LIMIT. Delete one to make room. - When a new account is created, one test key can be issued with it automatically; its secret is shown once, with the new account.
- A test key is not rotated. To replace it, delete it and create another.
- A test key cannot sign in to the portal: the login answers
401 TEST_KEY_NOT_ALLOWED. This is deliberate - a test key must never open the shop's live photos. The shop's owner signs in with the live key, creates test keys and hands one to the developer, who never needs the portal.
Where a test key works¶
A live publishable key works only from the shop's own domain. A test key is built for development, so it is also accepted from:
- Development hosts:
localhostand*.localhost, loopback addresses (127.0.0.0/8,::1), private networks (10.0.0.0/8,172.16.0.0/12,192.168.0.0/16), and the names*.test,*.localand*.internal. - A page with no origin:
Origin: null, which is what afile://page or a sandboxed iframe sends. - Any domain of your account, with
www.and subdomains. - The test key's own allowed hosts - a list you set when you create or edit the key, up to 20 hosts, with
www.and subdomains. Put there a staging host such asstaging.shop.example. Write a host as a name only; a scheme, a path and a port are removed. An internationalized name such asмагазин.рфis stored in its ASCII form.
A live key used from a development host is refused. Use a test key there. See Local development for the setup step by step.
GET /api/v1/tryon/integration accepts a test key too. It answers with key.mode set to "test" and an empty plan,
and site.allowed follows the same host rules, so a CMS module can verify a test key on a local site.
GET /api/v1/tryon/domain-check returns mode (live or test), which a publishable key may read.
Send a test try-on¶
Use the API as for a live key. Three things differ.
1. The photo must be an upload. Both kinds of test key require model_image to be a data URI. A URL answers
422 PHOTO_UPLOAD_REQUIRED. The garment image may stay a URL. Nothing fetches a URL in test mode.
2. You can choose how it ends. Add test_outcome to the body:
test_outcome |
Result |
|---|---|
completed (default) |
The job ends completed. |
failed |
The job ends failed with error_code GENERATION_FAILED and the message TEST: simulated failure. |
Any other value is treated as completed and never refuses the request. A live key ignores the field: it is not a free
way to fail a real job.
3. Webhooks. webhook_url works with a test secret key and is signed the same way as for a live job (see
Webhooks); a pk_test_… key that sends it gets
403 WEBHOOK_NOT_ALLOWED, like any publishable key.
curl -X POST https://api.ziex-tryon.com/api/v1/tryon \
-H "X-API-Key: tryon_test_YOUR_TEST_KEY" \
-H "Idempotency-Key: 8d1f0a52c7e94b6f9a3e5c21d4b70f88" \
-H "User-Agent: MyShop/1.0" \
-H "Content-Type: application/json" \
-d '{
"model_image": "data:image/jpeg;base64,/9j/4AAQSkZJRg...",
"garment_image": "https://shop.example/images/linen-shirt.jpg",
"category": "tops",
"test_outcome": "completed"
}'
Then follow the job as usual with GET /api/v1/tryon/status/{job_id}; it ends within a few seconds.
What a test key can see¶
The two modes never mix, in either direction.
- A test key - secret or publishable - sees only the test jobs of its own key:
GET /api/v1/tryon/status/{job_id},GET /api/v1/tryon/result/{job_id}andGET /api/v1/tryon/attempts/{key}. A secret test key's job list (GET /api/v1/tryon/jobs) holds only its own test jobs. - A live key sees no test job. Asking a live key for a test job's id answers
404 NOT_FOUND, not403.
A test job carries test: true in a webhook body. Webhook endpoints have a mode too: an endpoint created in mode test
receives only the events of test jobs, and an endpoint in mode live receives none of them. Register a separate
test endpoint for development. See Webhooks.
Files¶
The photos of a test job are stored for 72 hours and are then deleted. Live photos are kept for 180 days; test files never are. The result URL of a test job can stop working after that, so do not store it.
Limits¶
A test key has limits of its own, so test traffic from your office never uses up that office's live budget.
| Limit | Value |
|---|---|
| Submits per client address, all test keys | 30 per minute (a separate counter from the live one) |
pk_test_… per (key, client address) |
60 created jobs per 10 minutes (live: 10) |
| The key's hourly limit | The key's own, 100 per hour by default |
| Plan quota, daily caps | None |
A refusal carries Retry-After, as on the Limits page.
Moving to live¶
Nothing in your code changes except the keys: replace the test keys by your live ones, and for the widget use the
live pk_… bound to the shop's domain. A page that still carries a test key shows the TEST badge, which is the easy
way to notice a key left behind.