ZukMe
← ZukMe APIAPI Docs · Flow 1 of 4

AI Custom Design API

Let your customers submit any photo, a memory, a story, art, or a favorite person, and AI turns it into a high-fashion piece in your design style, ready for you to make and ship. No catalog, no StyleMe reading required. This is the Runway Edit feature from the ZukMe app, available here as an API.

Start here

Quickstart

Customer's photo

memory, story, art, or portrait

Your design style

outfit + scene

1 credit

High-fashion piece

photorealistic image

  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 your image plus outfit and scene direction to POST /api/v1/runway-edit.
  3. 3Poll with the returned jobId every 2–3s until done (typically 30–90s).

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
}

Submit

POST/api/v1/runway-edit
FieldTypeDescription
artPhotoBase64requiredstringBase64-encoded source image (art, photo, or design) the outfit is built from.
outfitNamerequiredstringShort name for the outfit, e.g. "Tailored Blazer Set".
outfitDirectionrequiredstringFree-text description of the garment(s): cut, pieces, silhouette. Up to 3000 characters.
sceneNamerequiredstringShort name for the scene/location, e.g. "Golden Hour Rooftop".
styleDirectionrequiredstringFree-text mood/style direction for the scene and shot. Up to 2000 characters.
size"S" | "M" | "L" | "XL" | "XXL" | "XXXL"Model build size. Defaults to "M".
gender"Male" | "Female" | "Neutral"Model gender direction. Defaults to "Neutral".
ageGroup"Adult" | "New Wave""New Wave" generates a teen model profile. Defaults to "Adult".
callbackUrlstringOptional webhook — see below.

Response:

{ "ok": true, "jobId": "b3f1...", "status": "processing" }

Poll

POST/api/v1/runway-edit
FieldTypeDescription
actionrequired"poll"Selects the poll branch.
jobIdrequiredstringThe jobId returned by the submit call.

Response, by status:

// processing
{ "status": "processing", "stage": "t2i" }

// done
{ "ok": true, "status": "done", "imageUrl": "https://..." }

// error (credit already refunded)
{ "status": "error", "error": "The AI model failed on this image. Please try again." }

Callbacks (webhooks)

Pass a callbackUrl on submit to also get the completed payload POSTed there when the job finishes — in addition to, never instead of, polling. Best-effort, no retries: keep polling as your source of truth. Must be a public http(s) URL; localhost and private network addresses are rejected.

Full example

curl
curl https://zukme.com/api/v1/runway-edit \
  -X POST \
  -H "Authorization: Bearer zk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "artPhotoBase64": "<base64>",
    "outfitName": "Tailored Blazer Set",
    "outfitDirection": "structured double-breasted blazer, wide-leg trousers",
    "sceneName": "Golden Hour Rooftop",
    "styleDirection": "warm, cinematic, editorial"
  }'
# → { "ok": true, "jobId": "b3f1...", "status": "processing" }

curl https://zukme.com/api/v1/runway-edit \
  -X POST \
  -H "Authorization: Bearer zk_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "action": "poll", "jobId": "b3f1..." }'
# → { "ok": true, "status": "done", "imageUrl": "https://..." }
Node.js
const KEY = process.env.ZUKME_API_KEY;
const BASE = "https://zukme.com/api/v1/runway-edit";

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({
  artPhotoBase64,
  outfitName: "Tailored Blazer Set",
  outfitDirection: "structured double-breasted blazer, wide-leg trousers",
  sceneName: "Golden Hour Rooftop",
  styleDirection: "warm, cinematic, editorial",
});

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: "..." }

Want real, purchasable garments on your user instead of an original design?

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.