Try-On API
Start a virtual try-on from your server and fetch the result. Endpoints, parameters, limits and error codes.
The API is asynchronous. You start a try-on, then ask for the result or receive it by webhook.
Base URL: https://genfashion.buildframe.tech/api/tryon/v1
Authentication: send a secret key in the x-api-key header. Secret keys start with sb_secret_. Create them under Settings > API keys. A publishable key (sk_publishable_) is refused here, because it is only for the storefront widget.
Endpoints#
| Method | Path | Purpose |
|---|---|---|
POST | /try-on | Start a try-on |
GET | /generations/:code | Get its status and result |
GET | /account/credits | Get your credit balance |
GET | /customers/:externalUserId | See what is held about one shopper |
DELETE | /customers/:externalUserId | Erase one shopper's data. See Privacy and data |
Webhooks are set up in the console, under Settings > Webhooks. There are no API endpoints for uploading images or managing products. Send the photo with each request, and manage products in the console or through a store sync.
Start a try-on#
POST /try-on
{
"person": { "url": "https://shop.example.com/shopper.jpg" },
"products": [{ "externalId": "shirt-42" }],
"background": "original"
}| Field | Required | What it does |
|---|---|---|
person | Yes | The shopper photo. Exactly one of url or dataUrl (a base64 data:image/ string) |
products | Yes | Up to 6 products from your catalogue, by externalId |
background | No | original, white, studio, city or nature |
modelId | No | A specific model code (mdl_...). Leave it out to use the default |
output.aiLabel | No | Shows the visible AI MODIFIED badge. Defaults to your account setting |
output.watermark | No | Shows your logo, if you have set one. Defaults to true |
externalUserId | No | Your own ID for the shopper, up to 128 characters. Also accepted as the x-external-user-id header |
Leaving out output.aiLabel is different from sending false: leaving it out uses your account setting. Provenance metadata is written into every result, whatever these fields say.
Send externalUserId if you may ever need to honour an erasure request. It is what DELETE /customers/:externalUserId matches on. Do not put personal data in it: use an opaque ID.
Response#
202 Accepted:
{ "generationId": "gen_3f9a1c2b7d4e8a10", "status": "PROCESSING", "pollAfterMs": 5000 }The photo is screened during this call, so it takes a few seconds. A 4xx response means the request was refused and no credit was used.
Get the result#
GET /generations/:code
{
"generationId": "gen_3f9a1c2b7d4e8a10",
"status": "COMPLETED",
"resultImageUrl": "https://example.com/signed-link",
"garmentPhrase": "blue and black check shirt",
"durationMs": 45137,
"creditsCharged": 1,
"externalUserId": null,
"createdAt": "2026-09-12T11:08:08Z",
"expiresAt": "2026-09-19T00:00:00Z"
}status is PROCESSING, COMPLETED or FAILED. A failed try-on also has error and message.
resultImageUrl is a signed link valid for 15 minutes. Download the image if you need it for longer. The image itself is deleted at expiresAt, set by your account's retention period.
A generation from another account returns 404, the same as one that does not exist.
Get your balance#
GET /account/credits
{ "balance": 213 }Limits#
| Limit | Value |
|---|---|
| Typical try-on | 45 to 60 seconds |
| Products per try-on | 6 |
| Photo size | 10 MB. JPEG, PNG, WebP or HEIC |
| Rate limits | Per shopper, per account and per platform. A 429 response has a retry-after header |
Errors#
Every error looks like { "error": "CODE", "message": "..." }. See Errors for every code.
Testing#
There is no free test mode. Every try-on runs on a real model and uses a credit when it succeeds. Failed try-ons are not charged. Use your free credits to test, or keep a small balance.