ZukMe
← ZukMe APIAPI Docs · Flow 4 of 4

Dressroom API

Turn any wardrobe, product photos, or links into a digital wardrobe. The AI finds the fashion pieces in your images and arranges them, whether it's for a person, a family, or your store. A quick way to upload your products or build out inventory. Direct REST endpoints; you build the UI.

Start here

Quickstart

Add pieces

detect, scrape, or upload

Save

PUT inventory

  1. 1Create an API key in the API Dashboard, then contact our team to get credits added.
  2. 2Every call takes an externalUserId — your own id for the end user whose wardrobe you're building. Same id, same wardrobe, every time.
  3. 3Add pieces with detect, scrape, or upload, let your UI accept/reject, then PUT inventory to save.

That's the whole Dressroom API — building and maintaining a wardrobe. Styling a look from it is a separate feature (the same StyleMe Try-On step ZukMe Marketplace and Your Own Inventory use); see Styling from this wardrobe.

What the end user actually sees

User experience flow

A plain walkthrough of what your user experiences in your own UI — no implementation detail. Each beat notes which call powers it.

Building a wardrobe

1

Sees their wardrobe

Empty the first time, with an "Add New" entry point.

GET /api/v1/dressroom/inventory

2

Picks how to add a piece

Scan a photo with AI, paste a link, or upload and tag by hand — your UI, three calls.

3

Scans or pastes

Drops a photo, or pastes a product/shop link. Comes back as a list of drafts — photo, name, category — nothing saved yet.

POST /api/v1/dressroom/detect or /scrape

4

Optionally cleans up the photo

A raw crop or scraped photo can be rough — re-renders it as a clean studio product shot before saving. Entirely optional; skip it and save the original photo instead.

POST /api/v1/dressroom/generate

5

Reviews, then saves

Accepts or rejects each draft in your UI; saving writes the accepted ones to the wardrobe.

PUT /api/v1/dressroom/inventory

6

Or uploads by hand

One photo, typed-in details, saved immediately — no review step, no AI.

POST /api/v1/dressroom/upload

Styling a look from the saved wardrobe is a separate feature — see Styling from this wardrobe.

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. Detect and scrape cost 1 credit each; upload is free. Studio photo (optional) costs 1 credit per piece. 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
}
Three ways in

Step 1 — Add pieces

Every call below takes externalUserId (required) and an optional dressroomId, for a user with more than one wardrobe. Same pair → same wardrobe, always.

1 credit

Detect

One photo — closet, rack, or flat-lay. Finds, names, and crops every garment.

1 credit

Scrape

One link — product, category, or shop page. Every plausible product photo becomes a draft.

Free

Upload

One photo, one piece, tagged by hand. Saved immediately, no review step.

POST/api/v1/dressroom/detect
FieldTypeDescription
externalUserIdrequiredstringSee above.
dressroomIdstringOptional.
imageBase64requiredstringOne photo. Up to ~10 garments detected.
response
{ "ok": true, "drafts": [ { "id": "...", "name": "Cream Wool Blazer", "category": "outerwear", "imageUrl": "https://…" } ] }
POST/api/v1/dressroom/scrape
FieldTypeDescription
externalUserIdrequiredstringSee above.
dressroomIdstringOptional.
urlrequiredstringA product, category, or shop page.
POST/api/v1/dressroom/upload
FieldTypeDescription
externalUserIdrequiredstringSee above.
dressroomIdstringOptional.
imageBase64requiredstringOne photo.
categoryrequiredstringRequired.
name, description, price, linkstringOptional.
response
{ "ok": true, "product": { "id": "...", "name": "...", "category": "outerwear", "imageUrl": "https://…" } }

Neither detect nor scrape saves anything — save what your UI keeps with PUT inventory below.

Clean up a piece's photo before saving

Optional — Studio photo

1 credit

Generate

Re-renders an existing piece's photo as a clean, high-detail studio product shot — same garment, better photo.

Takes an imageUrl already returned by detect, scrape, or upload and re-renders it — useful for a rough crop from a busy wardrobe photo, or a low-quality scraped product shot. Entirely optional: skip it and save the original photo with PUT inventory instead. Async: submit, then poll, same pattern as every other generation call.

POST/api/v1/dressroom/generate
FieldTypeDescription
externalUserIdrequiredstringSee above.
dressroomIdstringOptional.
imageUrlrequiredstringA photo already returned by detect, scrape, or upload.
name, category, descriptionstringOptional — improves the result by telling the model what it’s looking at.
response
{ "ok": true, "jobId": "..." }
// poll: { "action": "poll", "jobId": "..." }
// → { "ok": true, "status": "done", "imageUrl": "https://..." }

The returned imageUrl replaces the original for that piece — pass it along instead when you PUT inventory to save.

Step 2 — Save & read

GET/api/v1/dressroom/inventory?externalUserId=…&dressroomId=…
PUT/api/v1/dressroom/inventory
FieldTypeDescription
externalUserIdrequiredstringBody field on PUT, query param on GET.
dressroomIdstringOptional.
productsrequiredarrayPUT only — the full wardrobe. Replaces whatever was there.
response
{ "ok": true, "count": 4, "products": [ { "id": "p1", "name": "Linen blazer", "category": "outerwear", "imageUrl": "https://…" } ] }

products in the response is the true saved state, not an echo of what you sent — an item with an unreachable image is dropped silently, so always read this back rather than assume.

A separate feature — StyleMe's Try-On step

Styling from this wardrobe

Not part of building a wardrobe — this is the same StyleMe Try-On step ZukMe Marketplace and Your Own Inventory use, sourced from this wardrobe instead of a catalog. Input: a StyleMe reading and a photo. Output: a rendered look, matched from the wardrobe you just saved. Async: submit, then poll.

POST/api/v1/dressroom/tryon
FieldTypeDescription
externalUserIdrequiredstringWhose wardrobe to style from.
dressroomIdstringOptional.
readingrequiredStyleMeReadingFrom POST /api/v1/styleme.
photoBase64requiredstringPhoto to render the outfit onto.
occasionstringOptional, shapes which pieces are picked.
bodyTypestringOptional override.
callbackUrlstringOptional webhook. See Callbacks below.
response
{ "ok": true, "jobId": "..." }
// poll: { "action": "poll", "jobId": "..." }
// → { "ok": true, "status": "done", "imageUrl": "https://...", "outfitBreakdown": [...] }

Each outfitBreakdown entry has a type: "matched" is a real piece from their wardrobe, worn exactly as photographed. A category with nothing good in their wardrobe gets "invented" instead of being left empty — an AI-designed piece, optionally paired with a real bestMatch "shop similar" suggestion that is never the piece actually rendered.

Callbacks (webhooks)

dressroom/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

Building the wardrobe — the Dressroom API itself:

Node.js
const KEY = process.env.ZUKME_API_KEY;
const BASE = "https://zukme.com/api/v1/dressroom";
const externalUserId = "customer-42";

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

// 1. Scan a photo
const { drafts } = await call("/detect", { imageBase64 });

// 2. Your UI shows drafts for accept/reject — say the user kept all of them

// 3. Save
const { products } = await fetch(`${BASE}/inventory`, {
  method: "PUT",
  headers: { Authorization: `Bearer ${KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({ externalUserId, products: drafts }),
}).then((r) => r.json());

Styling from it — a separate call into the StyleMe Try-On step (see StyleMe reading for how to get a reading first):

Node.js
const submitted = await call("/tryon", { reading, photoBase64, occasion: "Weekend brunch" });

let result;
while (true) {
  result = await call("/tryon", { 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: [...] }

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.