Developer API

Virtual try-on, one API call away.

Send a person photo and a garment image — get a photorealistic try-on back. One endpoint, one API key, credits-based billing.

curl
curl -X POST https://tryonanytime.com/api/v1/tryon \
  -H "Authorization: Bearer sk_your_key" \
  -F "person=@me.jpg" \
  -F "garment=@dress.jpg" \
  -F "prompt=keep my face and pose"

Quickstart in three steps

From zero to your first try-on in under five minutes.

  1. 01

    Create an API key

    Sign in and generate an sk_ key on the API keys page. It is stored so you can copy it again anytime — set CONFIG_ENCRYPTION_KEY to keep it encrypted at rest; without it, the key is stored in plaintext.

  2. 02

    Make your first try-on

    POST a person image and a garment image to /api/v1/tryon — as multipart uploads, or as JSON with public URLs.

  3. 03

    Fetch the result

    Poll the task status endpoint until status is succeeded, then download the image from result_url.

Authentication

Every request carries your secret key in the Authorization header. Keys start with sk_ and spend from your account's credit balance.

  • Create and revoke keys anytime at /settings/apikeys.
  • The full key is encrypted at rest (AES-256-GCM when CONFIG_ENCRYPTION_KEY is set, plaintext otherwise) and can be copied again anytime from the key list. Set CONFIG_ENCRYPTION_KEY in production.
  • Never ship an sk_ key in client-side code. Call the API from your own server.
Request header
Authorization: Bearer sk_your_key

Endpoint reference

The complete try-on surface. Every JSON response uses the same code, message and data envelope.

POST/api/v1/tryon

Create a try-on job. Upload images as multipart files, or pass publicly reachable URLs as JSON.

Request

multipart/form-data
  person      <file>   photo of the person
  garment     <file>   the garment image
  garment_url string   https URL of the garment (instead of garment)
  prompt?     string   optional styling hint

or application/json
  { "person_url": "https://…",
    "garment_url": "https://…",
    "prompt": "…" }  // prompt optional

Response

{
  "code": 0,
  "message": "ok",
  "data": {
    "id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
    "status": "succeeded",
    "result_url": "/api/v1/tryon/a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d/result",
    "demo": false
  }
}
GET/api/v1/tryon/{id}

Check a try-on job. Poll until status becomes succeeded, then use result_url.

Response

{
  "code": 0,
  "message": "ok",
  "data": {
    "id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
    "status": "succeeded",
    "result_url": "/api/v1/tryon/a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d/result",
    "created_at": "2025-01-01T12:00:00Z"
  }
}
GET/api/v1/tryon/{id}/result

Download the finished try-on. Returns the raw image bytes (image/*) — not the JSON envelope.

Response

GET /api/v1/tryon/a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d/result
Authorization: Bearer sk_your_key

→ 200 OK
  Content-Type: image/png
  <raw image bytes>
GET/api/v1/me

Look up the account behind a key — handy for showing the remaining credit balance in your own UI.

Response

{
  "code": 0,
  "message": "ok",
  "data": {
    "email": "you@example.com",
    "credits": 42
  }
}
POST/api/v1/embed/tryon

Merchant embeds only. Authenticate with a publishable pk_ key in the X-Embed-Key header; requests are accepted only from your allow-listed Origins.

Request

POST /api/v1/embed/tryon
X-Embed-Key: pk_your_embed_key
Origin: https://your-store.com   // allow-listed

multipart/form-data only
  person      <file>   photo of the person
  garment_url string   https URL of the garment (or send garment <file>)
  prompt?     string   optional styling hint

Response

{
  "code": 0,
  "message": "ok",
  "data": {
    "id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
    "status": "succeeded",
    "result_url": "/api/v1/tryon/a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d/result",
    "demo": false
  }
}
Full embed guide →

Error codes

Errors keep the same envelope with code -1; read the message string for the specific error id (e.g. invalid_api_key).

HTTPMeaningWhat to do
401invalid_api_keyThe key is missing, revoked, or malformed.Check the Authorization header; mint a fresh key if this one leaked.
400invalid_imageAn image is unreadable, too large, or an unsupported format.Re-encode as JPEG, PNG or WebP and retry.
402insufficient_creditsThe account is out of credits.Top up on the pricing page, then retry the same request.
403domain_not_allowedAn embed request arrived from an Origin outside your allow-list.Add the domain in the embed settings, or check the Origin for typos.
404not_foundThe task id is unknown or belongs to a different key.Treat it as final — do not retry with the same id.
429too_many_requestsRate capped: too_many_requests, or an embed key hit its daily credit cap (daily_limit_reached).Back off for the Retry-After seconds, then retry; queue jobs instead of bursting.
500tryon_failedThe try-on or the server failed after the request was accepted (other endpoints may return server_error).Retry with backoff; any credits charged are revoked automatically.
503unavailableThe try-on provider is temporarily down.Retry with exponential backoff; alert us if it persists.

Rate limits

Fair-use limits keep latency low for everyone. Need more headroom? Talk to us.

Per API key

Try-on calls: one every 5 seconds per key owner (the account the key belongs to). Read calls (status, result, me): one every 500 ms per key owner.

Per IP address

Try-on calls: one every 2 seconds per IP, summed across all keys. Read calls: one every 1 second per IP.

Code examples

A complete round trip: create a try-on, poll until done, save the image. Swap in your key and run it.

curl -X POST https://tryonanytime.com/api/v1/tryon \
  -H "Authorization: Bearer sk_your_key" \
  -F "person=@me.jpg" \
  -F "garment=@dress.jpg" \
  -F "prompt=keep my face and pose"

Response envelope

Every JSON response wraps its payload the same way, so success handling is identical across endpoints.

code
0 means success, -1 means failure. The specific error id is in message.
message
Human- and machine-readable label; "ok" on success.
data
The endpoint payload — shapes documented above.
{code, message, data}
{
  "code": 0,         // 0 = success, -1 = failure
  "message": "ok",   // on failure: the specific error id, e.g. "invalid_image"
  "data": { }        // endpoint payload (absent on errors)
}

Keep exploring

Put virtual try-on behind one API call

Grab an sk_ key, POST two images, and ship. Credits are shared across the app, the API, the extension and MCP.