ZukMe
← ZukMe APIAPI Docs · Flow 2 of 4

StyleMe from ZukMe Marketplace API

Integrate ZukMe's marketplace into your store or app, and dress every visiting customer in a complete, best-fit outfit made from real, purchasable pieces, on its own or alongside your own inventory, the kind of fit that turns window-shoppers into buyers. Matching only your own products? See StyleMe for Your Own Inventory.

Start here

Quickstart

Photo

of your user

StyleMe

style reading

1 credit

Marketplace Try-On

rendered look

1 credit
  1. 1Create an API key in the API Dashboard, then contact our team to get credits added — a new key starts with none.
  2. 2Submit a photo to POST /api/v1/styleme for a style reading.
  3. 3Submit that reading and a photo to POST /api/v1/marketplace/tryon.
  4. 4Poll with the returned jobId every 2–3s until done.
What the end user actually sees

User experience flow

A plain walkthrough of what your shopper experiences on your own site or app — no implementation detail, just the moments. You build the interface; each beat notes which call powers it.

1

Uploads or picks a photo

One clear photo of themselves — the only input this flow needs.

POST /api/v1/styleme

2

A short wait while their style is read

One photo in; a few seconds later, a personalized style profile out.

POST /api/v1/styleme (poll)

3

Sees their style read back to them (optional)

A style title, a palette, a few personality notes — however much of the reading you choose to surface before moving on.

4

Picks an occasion (optional)

"Weekend brunch," "Job interview," whatever your UI offers — shapes which real pieces get shopped for next.

5

A short wait while an outfit is matched and rendered

Real, in-stock pieces from ZukMe's marketplace are matched to the reading and rendered onto their photo.

POST /api/v1/marketplace/tryon

6

Sees themselves in the finished look

The rendered photo, plus every piece used broken out individually — name, shop, price.

7

Taps a piece to buy it

Every item in the outfit is real and purchasable — you decide whether that's an affiliate link out or a straight add-to-cart on your own storefront.

Base URL

https://zukme.com

All endpoints below are relative to this base URL.

Authentication

Every request needs your API key as a bearer token — create and manage keys in the API Dashboard. The raw key is shown once; only its hash is stored.

Authorization: Bearer zk_live_<your key>

Missing, malformed, or revoked key → 401:

{ "error": "Invalid or missing API key. Pass it as \"Authorization: Bearer zk_live_...\"." }

Rate limits

30 requests per minute per key (submit and poll both count). Over the limit → 429:

{ "error": "Rate limit exceeded.", "retryAfterSeconds": 12 }

Credits

Each successful submission costs 1 credit, deducted at submit and refunded automatically if generation fails. Polling is always free. A new API key starts with 0 credits — API and embed-widget usage spends from your account's bonus credit balance only, never your app subscription's monthly quota. Contact our team to get bonus credits added before building against this in production. Check your balance in the API Dashboard.

Errors

FieldTypeDescription
400Bad RequestMissing or invalid fields in the request body.
401UnauthorizedMissing, malformed, or revoked API key.
402Payment RequiredCredits exhausted (code CREDITS_EXHAUSTED), with your current looks/bonus/total balance in the body.
404Not FoundjobId does not exist (expired, wrong id, or never submitted).
429Too Many RequestsRate limit exceeded for this key. See retryAfterSeconds.

Example 402 body:

{
  "error": "CREDITS_EXHAUSTED",
  "code": "CREDITS_EXHAUSTED",
  "looks": 0,
  "bonus": 0,
  "total": 0
}

Step 1 — StyleMe reading

Input: one photo. Output: a personalized style profile (see the reading object below) that feeds directly into Marketplace Try-On. Async: submit, then poll.

POST/api/v1/styleme
FieldTypeDescription
photoBase64requiredstringBase64-encoded photo of the person to generate a reading for.

Response (submitted):

{ "ok": true, "jobId": "a91c...", "status": "processing" }
POST/api/v1/styleme

Response when done:

{ "ok": true, "status": "done", "reading": { /* StyleMeReading, see below */ } }

The reading object

FieldTypeDescription
validbooleanFalse if the photo could not be read (see rejection_reason).
rejection_reasonstring | nullExplanation when valid is false.
styleTitlestringThe person's style archetype, e.g. "The Modern Minimalist".
styleSubtitlestringOne-line elaboration on the style title.
readingstring[]Paragraphs of the full style reading.
personality{ trait, level, description }[]Personality trait breakdown, level 0–100.
palette{ hex, name }[]Colours that suit this person's colouring.
outfits{ name, occasion, pieces, why }[]Suggested outfit concepts.
tagsstring[]Short style keyword tags.
genderstring | undefinedInferred gender, for downstream use.
bodyTypestring | undefinedInferred body type, e.g. "M", "Petite".

Step 2 — Marketplace Try-On

Matches the best real product per category from ZukMe's marketplace and renders them onto the photo. Async: submit, then poll.

POST/api/v1/marketplace/tryon
FieldTypeDescription
readingrequiredStyleMeReadingThe reading object returned by POST /api/v1/styleme.
photoBase64requiredstringBase64-encoded photo of the person to render the outfit onto.
occasionstringOptional occasion (e.g. "Weekend brunch") that shapes which pieces are shopped for.
bodyTypestringOptional body type override, e.g. "M", "Petite". Defaults to the reading's own inferred bodyType.
callbackUrlstringOptional webhook. See Callbacks below.

Response (submitted):

{ "ok": true, "jobId": "c7e2...", "status": "processing" }
POST/api/v1/marketplace/tryon

Response when done:

{
  "ok": true,
  "status": "done",
  "imageUrl": "https://...",
  "outfitBreakdown": [
    {
      "category": "top",
      "type": "matched",
      "productId": "abc123",
      "productName": "Silk Wrap Blouse",
      "shopName": "Studio Nine",
      "imageUrl": "https://...",
      "price": "USD 84",
      "source": "zukme"
    },
    {
      "category": "shoes",
      "type": "invented",
      "reason": "No good match found in the marketplace for this piece.",
      "brief": "Sleek black ankle boots with a low block heel.",
      "bestMatch": {
        "productId": "cj-9182",
        "productName": "Leather Block-Heel Boot",
        "shopName": "Studio Nine",
        "imageUrl": "https://...",
        "price": "USD 96",
        "clickUrl": "https://...",
        "explanation": "Closest real match for the designed silhouette."
      }
    }
  ]
}

Every entry has a type."matched" is a real, purchasable product — source is "zukme" or "cj", worn exactly as photographed. "invented" means nothing in the marketplace was a good enough fit for that category — the piece worn in the photo was designed by the AI instead of left empty, and (when available) bestMatch is a real product that resembles it, offered purely as a "shop similar" suggestion — it is never the piece actually rendered on the photo.

Callbacks (webhooks)

runway-edit and marketplace/tryon accept an optional callbackUrl on submit. When the job finishes (success or failure), we POST the same payload a completed poll would return — in addition to, never instead of, polling. Best-effort delivery with no retries, so keep polling as your source of truth.

// what we POST to callbackUrl on success:
{ "jobId": "...", "status": "done", "imageUrl": "https://...", "outfitBreakdown": [...] }

// on failure:
{ "jobId": "...", "status": "error", "error": "..." }

callbackUrl must be a public http(s) URL — localhost and private network addresses are rejected.

Full example

Poll every 2–3s until status is "done" or "error". A 404 means the job expired or never existed — treat it as failed.

curl
# 1. Get a StyleMe reading first (Step 2 above)
# 2. Submit
curl https://zukme.com/api/v1/marketplace/tryon \
  -X POST \
  -H "Authorization: Bearer zk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "reading": { /* from POST /api/v1/styleme */ },
    "photoBase64": "<base64>",
    "occasion": "Weekend brunch"
  }'
# → { "ok": true, "jobId": "c7e2...", "status": "processing" }

# 3. Poll until done
curl https://zukme.com/api/v1/marketplace/tryon \
  -X POST \
  -H "Authorization: Bearer zk_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "action": "poll", "jobId": "c7e2..." }'
# → { "status": "processing", "stage": "edit" }   (repeat)
# → { "ok": true, "status": "done", "imageUrl": "https://...", "outfitBreakdown": [...] }
Node.js
const KEY = process.env.ZUKME_API_KEY;
const BASE = "https://zukme.com/api/v1/marketplace/tryon";

async function call(body) {
  const res = await fetch(BASE, {
    method: "POST",
    headers: { Authorization: `Bearer ${KEY}`, "Content-Type": "application/json" },
    body: JSON.stringify(body),
  });
  return res.json();
}

const submitted = await call({
  reading, // from POST /api/v1/styleme
  photoBase64,
  occasion: "Weekend brunch",
});

let result;
while (true) {
  result = await call({ action: "poll", jobId: submitted.jobId });
  if (result.status === "done" || result.status === "error") break;
  await new Promise((r) => setTimeout(r, 2500));
}

console.log(result); // { ok: true, status: "done", imageUrl: "...", outfitBreakdown: [...] }
Python
import os, time, requests

KEY = os.environ["ZUKME_API_KEY"]
BASE = "https://zukme.com/api/v1/marketplace/tryon"
headers = {"Authorization": f"Bearer {KEY}"}

submitted = requests.post(BASE, headers=headers, json={
    "reading": reading,  # from POST /api/v1/styleme
    "photoBase64": photo_base64,
    "occasion": "Weekend brunch",
}).json()

while True:
    result = requests.post(BASE, headers=headers, json={
        "action": "poll", "jobId": submitted["jobId"],
    }).json()
    if result["status"] in ("done", "error"):
        break
    time.sleep(2.5)

print(result)  # {'ok': True, 'status': 'done', 'imageUrl': '...', 'outfitBreakdown': [...]}

ZukMe Global Network

North America

United States 7901 4th St N, Suite 300, St Petersburg, Florida 33702, United States

+1 850 696 6297

International Offices

Ghana: GS-0168-9885, Attah Mills Street, Opp. Downtown Pub, Old Barrier, Accra, Ga South, Greater Accra

Rwanda: KK 734 St, Kigali, Rwanda

+233(0)505807777

© 2026 ZukMe LLC. All rights reserved.