Size products for the shopper

post/v1/shoppers/me/size

The size to buy in each product, from the sizes the shopper wears at other brands ("30 in Levi's jeans", "M at Uniqlo"), their body measurements, or both. It is the same sizing the Stylor chat agent uses, so an app and the chat give the same answer.

How a size is worked out

  1. Each size worn elsewhere is read against that brand's published size chart (Stylor holds about 90 brands') as a range of each body measurement: who that size is made for. Several sizes narrow it; sizes that disagree widen it and lower the confidence.
  2. Body measurements, when sent or kept, replace what the sizes suggest for those measurements.
  3. The result is laid on the product's own store's size guide, read from the store's pages, by what decides that garment (the chest for a top, the waist and hips for a bottom). A waist worn as a number sizes a pant sold by the waist directly. Between two sizes, the shopper's fit decides, then how the product runs and its cut.

A size the shopper wears at the product's own store is their size there, with nothing to convert. A store with no size guide we can read gets the label they wear, as a hedged guess.

What is read

What you send is laid over what the profile keeps, yours winning: a size for the same brand and kind replaces the kept one, and each measurement sent replaces the kept one. Send no token to size from the request alone. With save: true what you sent is kept on the profile (as remember would); without a token a profile is made for it and its token returned.

Each product is sized under its store's own rules: a brand the store chose to leave out is not read, and a store that turned sizes from other brands off is sized from measurements only.

Reading the answer

confidence is certain when the sizes agree or the measurements decide it: say the size plainly. hedged names its one reason in basis (between sizes, their sizes disagree, one weak source, no chart): say it as a best guess. Between two sizes, options holds both, each with what it gives. inStock is whether the recommended size is in stock now.

When there is nothing to size from (no sizes or measurements sent or kept), each result's size is null and needs says what to ask for: sizes and measurements, or only measurements when the product's store does not size from other brands.

Public keyapi.v1.shoppersDemo key OK

Headers

1
X-Shopper-Tokenstring

The shopper's profile token, from auth/start, auth/verify or any call that made a profile. Optional here.

Request body

application/jsonrequired
itemIdsarray<string>required

The products to size, as full itemIds. Duplicates are sized once; ids not in your active catalogue are listed in unknown.

minItems: 1maxItems: 24
array<object>

Sizes they wear at other brands (or at the product's own store). Laid over the profile's, one per brand and kind.

maxItems: 8
brandstringrequired

The brand as they said it. Spelling is forgiven ("levis", "Levi's 501", "h&m").

kindstringnullable

What the size is for. Null or omitted when they did not say.

One oftopsjeanstrousersdressesouterwearsuitsnull
labelstringrequired

The size as they said it ("M", "30", "32x32", "US 6", "UK 10", "40R").

fitstringnullable

How that size fits them. Null or omitted for "it fits".

One oftightrightloosenull
object

Body measurements, laid over the profile's one by one. Same keys and ranges as remember's body, without fit.

bustnumber

Bust or chest.

waistnumber

Natural waist.

hipsnumber

Hips at the widest.

inseamnumber

Inside leg.

heightnumber

Height. Kept with save; sizes nothing.

unitstring

The unit of the measurements. Required with any measurement.

One ofcmin
fitstring

How they like things to fit. Decides between two sizes. Else the profile's.

One offittedregularrelaxed
departmentstring

Whose brand charts to read the sizes on. Else each product's own department.

One ofwomensmens
countrystring

The shopper's two-letter country, so inStock is their market's stock.

saveboolean

Keep the sizes, measurements and fit sent on the profile. Without a token, a profile is made and its token returned.

default: false

Response

200A size per product found, in the order asked.
array<ShopperSizeResult>required

One per product found, in the order asked.

itemIdstringrequired

The product.

namestringnullablerequired

The product's name.

sizestringnullablerequired

The size to buy, as the product labels it. Null when it could not be sized.

runnerUpstringnullablerequired

The other size worth considering, on a hedged answer only, and only one in stock.

array<object>

Between two sizes, both, the recommended first, each with what it gives.

confidencestringnullablerequired

certain: say it plainly. hedged: a best guess, for the reason in basis.

One ofcertainhedgednull
basisstringnullablerequired

Why it is this sure, in a few words (agree, one source, measured, between sizes, one weak source, conflict, no store chart, their size with us).

reasonstringnullablerequired

One line of why, in the second person, in the store's voice ("Your 30 waist at Levi's: our 30 is your size.").

inStockbooleannullablerequired

Whether the recommended size is in stock now. Null with no size.

outsideboolean

Present and true when their measurements are past the largest size this is made in.

needsstring

Present when the sizes given do not say what this garment's chart needs ("jeans or trousers").

unknownarray<string>

Ids that are not products in your active catalogue. Present only when there are some.

array<object>

Sizes that could not be read (a brand we hold no chart for, a size not on its chart). Present only when there are some.

saidstring

The size as read ("30 at Levi's").

whystring

Why it was not read.

needsarray<string>

Present when there was nothing to size any product from. What to ask the shopper for.

One ofsizesmeasurements
savedboolean

Present when save was sent. true when something was kept.

tokenstring

Only when save made a profile. Keep it.

Errors

39

Every error is JSON with a single error string unless noted. Match on the status code; the message is for humans.

400
Request body must be valid JSON.

The request body could not be parsed as JSON.

400
Request body must be a JSON object.

The request body is empty, or parsed to something other than a JSON object.

401
That shopper token is not valid here. Start a profile or sign in again.

X-Shopper-Token was sent but cannot be opened with this key. Leave it out to size from the request alone.

404
No active datasets found for this organization. Activate one via the dashboard (Dataset → Settings) or through the REST API before proceeding.

None of your datasets is active.

422
itemIds must be a non-empty array.

itemIds is missing, not an array, or empty.

422
itemIds can hold at most 24 ids.

itemIds holds more than 24 ids.

422
Each itemId must be a non-empty string.

An entry of itemIds is not a string, is blank, or is longer than 100 characters.

422
sizes must be an array.

sizes was sent (non-null) but is not an array.

422
sizes can hold at most 8 sizes.

sizes holds more than 8 entries.

422
sizes[<i>] must be an object.

An entry of sizes is not an object.

422
sizes[<i>].brand must be a brand name of 1–60 characters.

An entry's brand is missing, blank or too long.

422
sizes[<i>].label must be a size of 1–20 characters, as the brand writes it.

An entry's label is missing, blank or too long.

422
sizes[<i>].kind must be one of tops, jeans, trousers, dresses, outerwear, suits.

An entry's kind is another value.

422
sizes[<i>].fit must be tight, right or loose.

An entry's fit is another value. A profile's small and large are also read, as tight and loose.

422
measurements.<key> must be between <low>–<high> cm.

A measurement is outside what a person can have (in inches when unit is in). measurements is checked as remember's body is, with measurements. in each message, and takes no fit.

422
fit must be one of fitted, regular, relaxed.

fit is another value.

422
department must be womens or mens.

department is another value.

422
country must be a two-letter ISO 3166 country code, such as 'US'.

country was sent (non-null) but is not two letters.

422
save must be a boolean.

save was sent but is not true or false.

422
Validation failed.

More than one field is invalid. details lists each, by path; nothing is sized or kept.

{
  "error": "Validation failed.",
  "details": [
    {
      "path": "itemIds",
      "message": "itemIds must be a non-empty array."
    },
    {
      "path": "sizes[0].kind",
      "message": "sizes[0].kind must be one of tops, jeans, trousers, dresses, outerwear, suits."
    }
  ]
}
curl -X POST "https://stylor.ai/api/v1/shoppers/me/size" \
  -H "Authorization: Bearer $STYLOR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "itemIds": [
    "701e5cee-41da-4e91-a688-69e8c8dd5fe3",
    "a342cbe3-965b-4055-8ac3-20f63103cade",
    "35a725c8-23fb-4009-a52a-2a778d2e504a"
  ],
  "sizes": [
    {
      "brand": "Levi'\''s",
      "kind": "jeans",
      "label": "30"
    }
  ]
}'
Response · 200
{
  "results": [
    {
      "itemId": "701e5cee-41da-4e91-a688-69e8c8dd5fe3",
      "name": "Straight-Leg Jean — Washed Blue",
      "size": "30",
      "runnerUp": null,
      "confidence": "certain",
      "basis": "one source",
      "reason": "Your 30 waist at Levi's: our 30 is your size.",
      "inStock": true
    },
    {
      "itemId": "35a725c8-23fb-4009-a52a-2a778d2e504a",
      "name": "SLIM JEAN DENIM",
      "size": "30",
      "runnerUp": null,
      "confidence": "certain",
      "basis": "one source",
      "reason": "Your 30 waist at Levi's: our 30 is your size.",
      "inStock": false
    }
  ]
}