Corlen

Developer API reference

Overview

The Corlen API generates AI virtual try-on images: send a customer's photo and a garment image, get back an image of that person wearing the garment. Every generation runs asynchronously: you start it with a POST request, get a jobId back immediately, and poll a GET endpoint until it finishes.

No account yet? Sign up for a free trial (7 days, 10 generations, no credit card needed). Once you have a key, try the Playground to run a real generation from your browser with no code.

Download Postman collection

Quickstart

A full try-on in two calls: start the generation, then poll until it finishes.

# 1. Start the generation
curl -X POST https://corlen.io/api/v1/tryon \
  -H "Authorization: Bearer corlen_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "customerPhotoBase64": "data:image/jpeg;base64,...",
    "garmentImageUrl": "https://your-catalog.example.com/garment.jpg",
    "category": "upper_body"
  }'
# -> { "jobId": "b1e4...", "status": "processing" }

# 2. Poll until it's done (every 2-3 seconds)
curl https://corlen.io/api/v1/tryon/b1e4... \
  -H "Authorization: Bearer corlen_live_..."
# -> { "status": "completed", "resultImageBase64": "data:image/jpeg;base64,..." }

That's the whole integration. See Recommended workflow for how to poll politely, and Python example for a full working script.

Authentication

Every request needs an API key, created from your dashboard, sent as a bearer token:

Authorization: Bearer corlen_live_...

A missing or invalid key returns 401. Keys are shown once at creation and cannot be retrieved again, only revoked and replaced.

Rate limits and quotas

Requests are limited to 20 per 5 minutes per API key. Exceeding this returns 429 with a Retry-After header.

Your plan also caps how many generations you can run per day and per month; these are shown in your dashboard Overview. Going over your included monthly volume returns a 402 until you buy a top-up pack (see Credits) - a real, one-time payment, never billed after the fact.

Endpoints

POST/api/v1/tryon

Generates a single garment try-on.

curl -X POST https://corlen.io/api/v1/tryon \
  -H "Authorization: Bearer corlen_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "customerPhotoBase64": "data:image/jpeg;base64,...",
    "garmentImageUrl": "https://your-catalog.example.com/garment.jpg",
    "category": "upper_body"
  }'

# 202 Accepted
{ "jobId": "b1e4...", "status": "processing" }

Body fields:

  • customerPhotoBase64 (required): a data: URI. Never a remote URL: the customer's photo is always sent to us directly by your server, never fetched from a link.
  • productId (optional): the id of a garment you registered under Products, instead of passing garmentImageUrl/category/garmentCategory on every call. Any of those fields sent alongside productId override the registered value just for that request.
  • garmentImageUrl (required unless productId is given): an https:// URL from your own catalog, or a data: URI.
  • garmentBackImageUrl (optional): a back-view reference photo, used when viewAngle is back.
  • category (required unless productId is given): upper_body, lower_body, or full_body.
  • garmentCategory, size, customerSize (optional): improve fit rendering when provided.
  • garmentState (optional): open or closed, for jackets/shirts/waistcoats.
  • tuckState (optional): tucked or untucked.
  • viewAngle (optional): front (default), left, right, or back.
POST/api/v1/tryon/combo

Generates a combined look from 2 to 4 garments (e.g. a top, a jacket, and jeans) in one request.

curl -X POST https://corlen.io/api/v1/tryon/combo \
  -H "Authorization: Bearer corlen_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "customerPhotoBase64": "data:image/jpeg;base64,...",
    "garments": [
      { "garmentImageUrl": "https://.../top.jpg", "category": "upper_body", "garmentCategory": "t_shirt" },
      { "garmentImageUrl": "https://.../jeans.jpg", "category": "lower_body", "garmentCategory": "jeans" }
    ]
  }'

# 202 Accepted
{ "jobId": "b1e4...", "status": "processing" }

Same fields as above, applied per garment inside the garments array, including productId for any registered garment. Use this endpoint only for 2 or more garments; a single item should use POST /api/v1/tryon instead.

GET/api/v1/tryon/{jobId}

Poll this until the job finishes.

curl https://corlen.io/api/v1/tryon/b1e4... \
  -H "Authorization: Bearer corlen_live_..."

# while processing
{ "status": "processing" }

# once complete
{
  "status": "completed",
  "resultImageBase64": "data:image/jpeg;base64,...",
  "generationTimeMs": 24310
}

# if it failed
{ "status": "failed", "error": "..." }

While a generation is processing

A generation isn't instant, and the API doesn't return a percentage, only processing. Don't show your customers a countdown or a specific time estimate: it draws attention to the wait instead of the result. Corlen's own kiosk and website use the same pattern below, rotating through a few friendly lines with a simple animation while polling continues in the background.

const stages = [
  "Reading your photo...",
  "Preparing the garment...",
  "Matching your fit...",
  "Adding the final touches...",
];

let i = 0;
const interval = setInterval(() => {
  i = Math.min(i + 1, stages.length - 1);
  showMessage(stages[i]); // pair this with a spinner or a few progress dots
}, 4000);

// stop rotating once your poll to GET /api/v1/tryon/{jobId} comes back
// with status "completed" or "failed"

Images

  • Accepted formats: JPEG, PNG, WebP.
  • Maximum size: 8MB per image.
  • Garment images may be a public HTTPS URL or a base64 data URI; customer photos must always be a data URI you send directly.

Watermark

Brand every result with your own logo, placed in the bottom-right corner. This is an account-wide preference, not a per-request field: turn it on and add your logo URL once from Settings, and every generation on both /tryon and /tryon/combo is watermarked automatically from then on.

Errors

401Missing, invalid, or revoked API key.
403Your account has been blocked. Contact support@corlen.io.
400 / 413 / 422Malformed request, oversized body, or an image could not be processed.
404No product found for the productId you sent.
429Rate limit or quota exceeded. Check the Retry-After header.
500Something went wrong on our end. Failed generations are never billed.

Response format

Every endpoint returns one of these three shapes.

Job created (202, from POST /tryon or /tryon/combo):

{
  "jobId": "string, uuid",
  "status": "processing"
}

Job finished (200, from GET /tryon/{jobId}):

{
  "status": "completed",
  "resultImageBase64": "string, a data:image/jpeg;base64,... URI",
  "generationTimeMs": "number, how long generation took"
}

Job failed:

{
  "status": "failed",
  "error": "string, a message safe to show your own users"
}

Any error response (4xx/5xx):

{ "error": "string" }

Python example

import base64
import time
import requests

API_KEY = "corlen_live_..."
BASE_URL = "https://corlen.io/api/v1"
headers = {"Authorization": f"Bearer {API_KEY}"}

with open("customer_photo.jpg", "rb") as f:
    photo_b64 = base64.b64encode(f.read()).decode()

response = requests.post(
    f"{BASE_URL}/tryon",
    headers=headers,
    json={
        "customerPhotoBase64": f"data:image/jpeg;base64,{photo_b64}",
        "garmentImageUrl": "https://your-catalog.example.com/garment.jpg",
        "category": "upper_body",
    },
)
response.raise_for_status()
job_id = response.json()["jobId"]

while True:
    time.sleep(2.5)
    poll = requests.get(f"{BASE_URL}/tryon/{job_id}", headers=headers).json()
    if poll["status"] == "completed":
        print("Done:", poll["resultImageBase64"][:40], "...")
        break
    if poll["status"] == "failed":
        print("Failed:", poll["error"])
        break

API changelog

Version history for the API contract itself. For product-wide updates, see the Corlen changelog.

  • August 2026: Added watermarking: brand every result with your own logo, configured once from Settings.
  • August 2026: Added productId to POST /tryon and /combo, backed by the new Products catalog. Added the Playground.
  • August 2026: Public API launched: POST /tryon, POST /tryon/combo, GET /tryon/{jobId}.