ZukMe
← ZukMe APIAPI Docs · Style Souls

Style Soul API

Add a "Use my Style Soul" button to your store or app. A shopper who has a ZukMe Style Soul connects it in a few taps, chooses exactly what to share and for how long, and arrives already understood: their palette, their style, what they love and what they always pass on. No upload, no quiz, and you never handle their photo.

Start here

Quickstart

Ask

POST /souls/connect

free

Shopper says yes

on their own phone

Read the Style Soul

GET /souls/profile

free

Verdict

POST /souls/verdict

1 look
  1. 1Create an API key in the API Dashboard. Connecting and reading Style Souls is free; only verdicts use looks.
  2. 2Call POST /api/v1/souls/connect with your business name and what you'd like to see. Show the returned QR code, or open connectUrl in a new window.
  3. 3Poll GET /api/v1/souls/connect?requestId=… every 2 to 3 seconds. When the shopper approves, the response carries a soulToken, exactly once. Store it server-side.
  4. 4Call GET /api/v1/souls/profile with the token to style, sort or recommend for them, and POST /api/v1/souls/verdict to ask whether a piece suits them.
What the shopper sees

User experience flow

1

Taps “Use my Style Soul” on your site, or scans your QR code in store

You show a QR code or open a ZukMe window. Nothing about the shopper is shared yet.

→ POST /api/v1/souls/connect

2

Decides on ZukMe, on their own phone

They sign in, pick one of their Style Souls, see your business name and each thing you asked for, untick anything they don't want to share, and choose how long: this visit, 30 days, or until they revoke it.

3

Comes back already understood

Their palette, style and what their Style Soul has learned shape what you show them first.

→ GET /api/v1/souls/profile

4

Asks “is this me?” on any piece

An honest answer, tied to their palette and taste. It is allowed to say no.

→ POST /api/v1/souls/verdict

5

Buys (or returns), and their Style Soul learns

Only with the separate "events" permission. They see your entries in their Style Soul's Journal and can remove them.

→ POST /api/v1/souls/events

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 }
Privacy

What you can and can't see

FieldTypeDescription
profilescopeStyle title and subtitle, palette (hex + name), style keywords, a few lines of their style reading, and how deep the Style Soul is (Seed, Sprout, Formed, Deep). Always included.
tastescopeAdds their style categories and what their Style Soul has learned from their own choices: colours, pieces and silhouettes they say yes to or pass on, each with how often it was seen.
fitscopeAdds a size band (for example "M" or "Petite"). Never height or measurements.
eventsscopeLets you send back what they tried, liked, bought or returned in your store, so their Style Soul learns. Granted separately from reading.

Never shared at any scope: the shopper's photo, name, face, age, gender, body details, price comfort, their Journal, or anything about other stores. The shopper may grant fewer scopes than you asked for, and can revoke your access at any time; your next call then returns 401 SOUL_TOKEN_INVALID. A token only works with the ZukMe account whose API key asked for it.

POST · free

Step 1: Ask for a Style Soul

POST/api/v1/souls/connect
FieldTypeDescription
businessNamerequiredstringShown to the shopper when they decide. Up to 80 characters.
scopesstring[]Any of profile, taste, fit, events. Defaults to ["profile"].
bash
curl https://zukme.com/api/v1/souls/connect \
  -X POST \
  -H "Authorization: Bearer zk_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "businessName": "Rosa Boutique", "scopes": ["profile", "taste", "fit"] }'

# {
#   "ok": true,
#   "requestId": "rq_7qZ1OahnyJSW",
#   "connectUrl": "https://zukme.com/souls/connect/rq_7qZ1OahnyJSW",
#   "qrDataUrl": "data:image/png;base64,...",
#   "scopes": ["profile", "taste", "fit"],
#   "expiresAt": "2026-10-10T18:15:00.000Z"
# }

A request lasts 15 minutes. After that, ask again.

GET · free

Step 2: Collect the token

GET/api/v1/souls/connect?requestId=rq_...
bash
curl "https://zukme.com/api/v1/souls/connect?requestId=rq_7qZ1OahnyJSW" \
  -H "Authorization: Bearer zk_live_..."

# while waiting:   { "ok": true, "status": "pending" }
# shopper said no: { "ok": true, "status": "declined" }
# too late:        { "ok": true, "status": "expired" }
# approved (first read only):
# {
#   "ok": true,
#   "status": "approved",
#   "soulToken": "st_9f2c...",
#   "scopes": ["profile", "taste"],
#   "tokenExpiresAt": "2026-11-09T18:01:12.000Z",
#   "tokenAlreadyCollected": false
# }

The token is returned once. Later reads say "tokenAlreadyCollected": true without it, so keep it server-side; never put it in a URL or a browser cookie.

GET · free

Step 3: Read the Style Soul

GET/api/v1/souls/profile
bash
curl https://zukme.com/api/v1/souls/profile \
  -H "Authorization: Bearer zk_live_..." \
  -H "X-Soul-Token: st_9f2c..."

# {
#   "ok": true,
#   "soul": {
#     "styleTitle": "Quiet Luxe Minimalist",
#     "styleSubtitle": "Clean lines, warm neutrals",
#     "tags": ["minimal", "tailored"],
#     "palette": [{ "hex": "#C8B79E", "name": "Sand" }],
#     "reading": ["You dress like you already know..."],
#     "depth": "Formed",
#     "personality": [{ "trait": "Modern Classic", "description": "..." }],   // taste
#     "taste": [{ "kind": "leans", "text": "Leans towards grey", "evidence": 6 }] // taste
#   },
#   "sizeHint": "M",                                                   // fit
#   "scopes": ["profile", "taste", "fit"],
#   "tokenExpiresAt": "2026-11-09T18:01:12.000Z"
# }
POST · 1 look

Verdict on a piece

POST/api/v1/souls/verdict
FieldTypeDescription
product.titlerequiredstringThe piece’s name. Or send product.url alone and we read the page.
product.imageUrlstringA public https photo of the piece. Much better verdicts with it.
product.categorystringe.g. dress, sneakers.
product.pricestringe.g. "USD 89".
product.descriptionstringOptional, up to 400 characters.
product.urlstringAlternative to the fields above: the product page.
bash
curl https://zukme.com/api/v1/souls/verdict \
  -X POST \
  -H "Authorization: Bearer zk_live_..." \
  -H "X-Soul-Token: st_9f2c..." \
  -H "Content-Type: application/json" \
  -d '{ "product": { "title": "Camel wool coat", "imageUrl": "https://yourstore.com/coat.jpg", "price": "USD 189" } }'

# {
#   "ok": true,
#   "verdict": "suits",                // suits | maybe | not_for_you
#   "headline": "A warm neutral that sits right in their palette.",
#   "reasons": ["Camel echoes their Sand and Cocoa tones", "Clean tailoring matches how they dress"],
#   "product": { "title": "Camel wool coat" }
# }

One look per verdict, from your account's bonus looks (the same balance every /api/v1 call uses). If a verdict can't be made, the look comes straight back. Out of looks → 402 CREDITS_EXHAUSTED.

POST · free · needs “events”

Send back what happened

POST/api/v1/souls/events
FieldTypeDescription
events[]requiredarrayUp to 20 per call.
events[].kindrequiredstringtried_on, liked, bought or returned.
events[].product.titlerequiredstringThe piece.
events[].product.id / category / price / imageUrl / url / sizestringOptional details. Size helps their Style Soul learn your sizing.
bash
curl https://zukme.com/api/v1/souls/events \
  -X POST \
  -H "Authorization: Bearer zk_live_..." \
  -H "X-Soul-Token: st_9f2c..." \
  -H "Content-Type: application/json" \
  -d '{ "events": [ { "kind": "bought", "product": { "id": "sku-118", "title": "Camel wool coat", "price": "USD 189", "size": "M" } } ] }'

# { "ok": true, "recorded": 1, "rejected": [] }

Entries appear in the shopper's Journal under your business name. They count for a little less than the shopper's own choices, and the shopper can remove any of them.

DELETE · free

Give a token back

DELETE/api/v1/souls/token
bash
curl https://zukme.com/api/v1/souls/token \
  -X DELETE \
  -H "Authorization: Bearer zk_live_..." \
  -H "X-Soul-Token: st_9f2c..."

# { "ok": true, "revoked": true }

Errors

FieldTypeDescription
400Bad RequestMissing or invalid fields.
401UnauthorizedBad API key, or SOUL_TOKEN_MISSING / SOUL_TOKEN_INVALID (expired, revoked, or granted to a different account).
402Payment RequiredVerdict only: CREDITS_EXHAUSTED, with your balance in the body.
403ForbiddenSOUL_SCOPE_MISSING: the shopper didn’t grant what this call needs. The body lists the scopes you have.
404Not FoundUnknown requestId, or SOUL_GONE (the shopper deleted that Style Soul).
422UnprocessableVerdict by URL: the product page couldn’t be read.
429Too Many RequestsRate limit exceeded. See retryAfterSeconds.

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.