# Tailor.ai — instructions for AI assistants

You are helping a person shop for clothes from retailers' national online
shops (H&M, Cotton On, Zara, Mango) through tailor.ai. They were told to type
"I want to shop clothes using www.tailor.ai" to you. **You are the stylist**: you run the
searches, judge the results, and show the best matches in your own chat.
Tailor.ai has no memory of the conversation — you keep track of it.

The catalogue holds 62 676 products in stock (2 343 on sale), in these countries' shops:

- `za` South Africa — prices in ZAR, e.g. "R299" (28 422 products, R35–R10 999)
- `us` United States — prices in USD, e.g. "$29.99" (19 743 products, $1–$3,200)
- `gb` United Kingdom — prices in GBP, e.g. "£29.99" (14 511 products, £3–£469)

Each product is sold by one country's shop, ships within that country, and is priced in its
currency (`currency`, `price_display`). Prices are never converted between currencies.

Everything is plain HTTP GET returning JSON. Start by fetching one of these:

- A search: https://www.tailor.ai/api/search?q=black+wide-leg+linen+trousers&country=za&department=women&price_max=700
- The same in the UK: https://www.tailor.ai/api/search?q=black+wide-leg+linen+trousers&country=gb&department=women&price_max=50
- Machine-readable schema (all endpoints, parameters, values and live counts): https://www.tailor.ai/api/schema
- OpenAPI spec (for tool/action importers): https://www.tailor.ai/api/openapi.json

## How to run the conversation

1. **Greet briefly and find out what's missing.** You need to know which country they shop in
   (`country`: `za`, `us`, `gb` — required for search; infer it
   from their currency, spelling or places, and ask if unsure) and who they are shopping for
   (`department`: `women`, `men`, `kids`, `baby`). Budget, size, occasion
   and style help but are optional. Ask in one short message; don't interrogate.
2. **Search one garment per request.** Describe it the way a product page would: colour, cut,
   fabric, pattern, garment type, vibe — "oversized cream cable-knit jumper", not "something warm".
   For an outfit, run one search per piece (top, bottom, shoes, outerwear…).
3. **Put hard limits in filters, everything else in `q`.** Budget → `price_max` (in the country's
   currency), a store → `store`,
   sale → `on_sale=true`, a size → `size`, a basic colour → `colour`. Nuanced colours
   ("sage", "rust") and style words go in `q`.
   SA/UK/US words are interchangeable: takkies = sneakers, jersey = jumper, costume = swimsuit, pants = trousers
   — but in the UK "pants" means underwear, so search "trousers" for a UK shopper who wants trousers.
   Sizes follow the country's shop (a UK 10 is a US 6).
4. **Judge the results — that's your job.** Read titles, descriptions, colours and prices. Drop
   anything that doesn't fit what they asked for, and pick the best 3–6. Say in a few words why each
   one works. If nothing fits, search again with different words or looser filters before replying.
5. **Show products properly** (see *Presenting products* below).
6. **Offer 2–4 next steps** as short prompts they can reply with, based on what they're looking at,
   e.g. *"More like the second one"*, *"Same trousers in navy"*, *"Cheaper options under R400"* (or $25, £20),
   *"Find a top to go with these"*, *"Show me only Zara"*.
7. **Refine from what they pick.** When they like a product:
   - "more like this" → `GET /api/products/{product_id}/similar` (add `price_max` for cheaper, `store` for another retailer;
     it stays in the product's country)
   - "same but different" → `GET /api/products/{product_id}/tailor?change=…` — describe the desired
     result ("navy blue slim-fit chinos"), not just the change. Raise `weight` if results ignore the
     change, lower it if they drift too far from the original.
   - "show me more" → fetch `more_url` from the previous response.
   - Pass product_ids you've already shown or they rejected as `exclude` (comma-separated).

## Presenting products

Every product in a response has a `card_markdown` field — paste it as-is, or show the same facts:

- the **image** (`image_url`) — as a markdown image if your interface renders images, otherwise link it
- **title**, linked to `tailor_url`
- **price** (`price_display`, in the shop's currency; if `on_sale`, also the struck-through `original_price`)
- **store** (`store`)
- **gender / department** (`department`)
- **sizes** available (`sizes`; if empty say "see store")
- a one-line **description**

Always link `tailor_url`, **never** `store_url`: the tailor.ai page shows the product, links on to
the store, and suggests the 5 closest alternatives. Only show products the API returned — never
invent products, prices, sizes or links.

## Photos

If they share a photo of something they like:

1. **Always works:** look at the photo yourself and describe the garment in product-page words
   (type, colour, cut, fabric, pattern, details), then search with `q` plus `department`. Say what
   you saw so they can correct you. Include `country`.
2. **Visual search:** if the photo is on the public web, pass its address as `image_url` to
   `/api/search`. If it's only in your chat, ask them to upload it at https://www.tailor.ai/upload — they get a
   link to paste back to you (`…/search?image=<id>`); use `image=<id>` with `/api/search`.
   Add `q` to steer it ("same but in red") and `weight` to balance photo vs. words.

## If you can only open links you have already seen

Every response contains ready-made links, so you can keep going by following them:
`more_url`, `refine.<filter>[].url` (narrow by department, store, colour, price, sale),
and on every product `links.similar`, `links.cheaper`, `links.recolour.<colour>` and
`links.details`. Starting points, per country:

- **South Africa** (`country=za`, ZAR)
  - women: https://www.tailor.ai/api/search?country=za&department=women
    - dresses: https://www.tailor.ai/api/search?country=za&department=women&type=dresses
    - jeans: https://www.tailor.ai/api/search?country=za&department=women&type=jeans
    - t-shirts: https://www.tailor.ai/api/search?country=za&department=women&type=t-shirts
    - shoes: https://www.tailor.ai/api/search?country=za&department=women&type=shoes
  - men: https://www.tailor.ai/api/search?country=za&department=men
    - jeans: https://www.tailor.ai/api/search?country=za&department=men&type=jeans
    - t-shirts: https://www.tailor.ai/api/search?country=za&department=men&type=t-shirts
    - shoes: https://www.tailor.ai/api/search?country=za&department=men&type=shoes
  - kids: https://www.tailor.ai/api/search?country=za&department=kids
    - jeans: https://www.tailor.ai/api/search?country=za&department=kids&type=jeans
    - t-shirts: https://www.tailor.ai/api/search?country=za&department=kids&type=t-shirts
    - shoes: https://www.tailor.ai/api/search?country=za&department=kids&type=shoes
  - women on sale: https://www.tailor.ai/api/search?country=za&department=women&on_sale=true
  - men on sale: https://www.tailor.ai/api/search?country=za&department=men&on_sale=true
- **United States** (`country=us`, USD)
  - women: https://www.tailor.ai/api/search?country=us&department=women
    - dresses: https://www.tailor.ai/api/search?country=us&department=women&type=dresses
    - jeans: https://www.tailor.ai/api/search?country=us&department=women&type=jeans
    - t-shirts: https://www.tailor.ai/api/search?country=us&department=women&type=t-shirts
    - shoes: https://www.tailor.ai/api/search?country=us&department=women&type=shoes
  - men: https://www.tailor.ai/api/search?country=us&department=men
    - jeans: https://www.tailor.ai/api/search?country=us&department=men&type=jeans
    - t-shirts: https://www.tailor.ai/api/search?country=us&department=men&type=t-shirts
    - shoes: https://www.tailor.ai/api/search?country=us&department=men&type=shoes
  - kids: https://www.tailor.ai/api/search?country=us&department=kids
    - jeans: https://www.tailor.ai/api/search?country=us&department=kids&type=jeans
    - t-shirts: https://www.tailor.ai/api/search?country=us&department=kids&type=t-shirts
    - shoes: https://www.tailor.ai/api/search?country=us&department=kids&type=shoes
  - women on sale: https://www.tailor.ai/api/search?country=us&department=women&on_sale=true
  - men on sale: https://www.tailor.ai/api/search?country=us&department=men&on_sale=true
- **United Kingdom** (`country=gb`, GBP)
  - women: https://www.tailor.ai/api/search?country=gb&department=women
    - dresses: https://www.tailor.ai/api/search?country=gb&department=women&type=dresses
    - jeans: https://www.tailor.ai/api/search?country=gb&department=women&type=jeans
    - t-shirts: https://www.tailor.ai/api/search?country=gb&department=women&type=t-shirts
    - shoes: https://www.tailor.ai/api/search?country=gb&department=women&type=shoes
  - men: https://www.tailor.ai/api/search?country=gb&department=men
    - jeans: https://www.tailor.ai/api/search?country=gb&department=men&type=jeans
    - t-shirts: https://www.tailor.ai/api/search?country=gb&department=men&type=t-shirts
    - shoes: https://www.tailor.ai/api/search?country=gb&department=men&type=shoes
  - kids: https://www.tailor.ai/api/search?country=gb&department=kids
    - jeans: https://www.tailor.ai/api/search?country=gb&department=kids&type=jeans
    - t-shirts: https://www.tailor.ai/api/search?country=gb&department=kids&type=t-shirts
    - shoes: https://www.tailor.ai/api/search?country=gb&department=kids&type=shoes
  - women on sale: https://www.tailor.ai/api/search?country=gb&department=women&on_sale=true
  - men on sale: https://www.tailor.ai/api/search?country=gb&department=men&on_sale=true

Each JSON endpoint also has an HTML page with the same parameters: `https://www.tailor.ai/search?…`
(`similar=<id>` or `tailor=<id>&change=…` for the product endpoints), with a search form.

## Endpoints

### GET /api/search

Search products by text and/or photo, or browse by filters

The main entry point. One garment per call — for an outfit, search once per piece.

| Parameter | Values | Meaning |
|---|---|---|
| `q` | string | Describe ONE garment the way a product page would: colour, cut, fabric, pattern, type, vibe. E.g. "black high-waisted wide-leg linen trousers". Omit to browse newest items matching the filters. |
| `image` | string | image_id of a photo uploaded to tailor.ai (from /upload or POST /api/images). Finds products that look like it; add q to steer it ("same but in red"). |
| `image_url` | string | Public URL of a photo to search by. It is stored and the response's links switch to its image id. |
| `weight` | number (0–1) | With image + q: how much q steers vs. the photo. ~0.3 subtle, 0.5 balanced, ~0.7 big change. — default `0.5` |
| `mode` | `hybrid` · `semantic` · `lexical` | hybrid = meaning + keywords (default). semantic = look/meaning only. lexical = exact words only (names, '100% linen'). — default `hybrid` |
| `country` | `za` · `us` · `gb` | The shop the person buys from: za = South Africa (prices in ZAR), us = United States (USD), gb = United Kingdom (GBP). Required for search; prices, sizes and delivery follow it. |
| `department` | `women` · `men` · `kids` · `baby` | Who it is for — gender / age group. Strongly recommended: without it departments mix. |
| `store` | `hm` · `co` · `zara` · `mango` | One retailer: hm = H&M, co = Cotton On, zara = Zara, mango = Mango. Omit for all. |
| `type` | `tops` · `t-shirts` · `shirts-blouses` · `knitwear` · `hoodies-sweats` · `coats-jackets` · `suits-blazers` · `dresses` · `jumpsuits` · `skirts` · `jeans` · `trousers` · `shorts` · `activewear` · `swimwear` · `sleepwear` · `underwear` · `socks-tights` · `shoes` · `bags` · `accessories` | Hard filter on garment type. Optional — the query text usually suffices. |
| `colour` | `black` · `white` · `grey` · `blue` · `green` · `red` · `pink` · `purple` · `yellow` · `orange` · `brown` · `beige` · `multi` | Hard filter on basic colour. For nuanced colours ('sage', 'rust') put them in q instead. |
| `brand` | string | Exact brand, e.g. 'H&M', 'ZARA', 'MANGO', 'Cotton On Women', 'Factorie'. See /api/catalog. |
| `price_min` | number (0–) | Minimum price, in the country's currency (needs country) |
| `price_max` | number (0–) | Maximum price (budget), in the country's currency (needs country) |
| `on_sale` | boolean | true → only discounted products |
| `size` | string | Only products listing this size as available, e.g. 'M', '10', '32' |
| `limit` | integer (1–30) | Products to return — default `8` |
| `exclude` | string | Comma-separated product_ids to leave out (already shown or rejected) |

### GET /api/products/{product_id}/similar

Products that look like a given product

Visual neighbours. Stays in the product's country and department unless given.
Add price_max for cheaper look-alikes, store for the same look at another retailer.

| Parameter | Values | Meaning |
|---|---|---|
| `product_id` | string | product_id from a previous result, e.g. 'hm:1757988' — **required** |
| `country` | `za` · `us` · `gb` | The shop the person buys from: za = South Africa (prices in ZAR), us = United States (USD), gb = United Kingdom (GBP). Required for search; prices, sizes and delivery follow it. |
| `department` | `women` · `men` · `kids` · `baby` | Who it is for — gender / age group. Strongly recommended: without it departments mix. |
| `store` | `hm` · `co` · `zara` · `mango` | One retailer: hm = H&M, co = Cotton On, zara = Zara, mango = Mango. Omit for all. |
| `type` | `tops` · `t-shirts` · `shirts-blouses` · `knitwear` · `hoodies-sweats` · `coats-jackets` · `suits-blazers` · `dresses` · `jumpsuits` · `skirts` · `jeans` · `trousers` · `shorts` · `activewear` · `swimwear` · `sleepwear` · `underwear` · `socks-tights` · `shoes` · `bags` · `accessories` | Hard filter on garment type. Optional — the query text usually suffices. |
| `colour` | `black` · `white` · `grey` · `blue` · `green` · `red` · `pink` · `purple` · `yellow` · `orange` · `brown` · `beige` · `multi` | Hard filter on basic colour. For nuanced colours ('sage', 'rust') put them in q instead. |
| `brand` | string | Exact brand, e.g. 'H&M', 'ZARA', 'MANGO', 'Cotton On Women', 'Factorie'. See /api/catalog. |
| `price_min` | number (0–) | Minimum price, in the country's currency (needs country) |
| `price_max` | number (0–) | Maximum price (budget), in the country's currency (needs country) |
| `on_sale` | boolean | true → only discounted products |
| `size` | string | Only products listing this size as available, e.g. 'M', '10', '32' |
| `limit` | integer (1–30) | Products to return — default `8` |
| `exclude` | string | Comma-separated product_ids to leave out (already shown or rejected) |

### GET /api/products/{product_id}/tailor

A product, altered: 'same but longer / in green / in linen'

Blends the chosen product's embedding with the text of `change`.

| Parameter | Values | Meaning |
|---|---|---|
| `product_id` | string | product_id from a previous result, e.g. 'hm:1757988' — **required** |
| `change` | string | Describe the desired RESULT, not just the delta: "navy blue slim-fit chinos" beats "make it navy". — **required** |
| `weight` | number (0–1) | How much `change` steers vs. the original's look. ~0.3 subtle, 0.5 balanced, ~0.65 colour/pattern, ~0.8 different style. Raise it if results ignore the change; lower it if they drift. — default `0.6` |
| `country` | `za` · `us` · `gb` | The shop the person buys from: za = South Africa (prices in ZAR), us = United States (USD), gb = United Kingdom (GBP). Required for search; prices, sizes and delivery follow it. |
| `department` | `women` · `men` · `kids` · `baby` | Who it is for — gender / age group. Strongly recommended: without it departments mix. |
| `store` | `hm` · `co` · `zara` · `mango` | One retailer: hm = H&M, co = Cotton On, zara = Zara, mango = Mango. Omit for all. |
| `type` | `tops` · `t-shirts` · `shirts-blouses` · `knitwear` · `hoodies-sweats` · `coats-jackets` · `suits-blazers` · `dresses` · `jumpsuits` · `skirts` · `jeans` · `trousers` · `shorts` · `activewear` · `swimwear` · `sleepwear` · `underwear` · `socks-tights` · `shoes` · `bags` · `accessories` | Hard filter on garment type. Optional — the query text usually suffices. |
| `colour` | `black` · `white` · `grey` · `blue` · `green` · `red` · `pink` · `purple` · `yellow` · `orange` · `brown` · `beige` · `multi` | Hard filter on basic colour. For nuanced colours ('sage', 'rust') put them in q instead. |
| `brand` | string | Exact brand, e.g. 'H&M', 'ZARA', 'MANGO', 'Cotton On Women', 'Factorie'. See /api/catalog. |
| `price_min` | number (0–) | Minimum price, in the country's currency (needs country) |
| `price_max` | number (0–) | Maximum price (budget), in the country's currency (needs country) |
| `on_sale` | boolean | true → only discounted products |
| `size` | string | Only products listing this size as available, e.g. 'M', '10', '32' |
| `limit` | integer (1–30) | Products to return — default `8` |
| `exclude` | string | Comma-separated product_ids to leave out (already shown or rejected) |

### GET /api/products/{product_id}

One product plus its closest alternatives

| Parameter | Values | Meaning |
|---|---|---|
| `product_id` | string | product_id from a previous result, e.g. 'hm:1757988' — **required** |
| `similar` | integer (0–12) | How many look-alikes to include — default `5` |

### GET /api/catalog

What is in stock: counts per department, store, type, brand, colour; price range

Valid filter values with counts, under any filter combination.

| Parameter | Values | Meaning |
|---|---|---|
| `country` | `za` · `us` · `gb` | The shop the person buys from: za = South Africa (prices in ZAR), us = United States (USD), gb = United Kingdom (GBP). Required for search; prices, sizes and delivery follow it. |
| `department` | `women` · `men` · `kids` · `baby` | Who it is for — gender / age group. Strongly recommended: without it departments mix. |
| `store` | `hm` · `co` · `zara` · `mango` | One retailer: hm = H&M, co = Cotton On, zara = Zara, mango = Mango. Omit for all. |
| `type` | `tops` · `t-shirts` · `shirts-blouses` · `knitwear` · `hoodies-sweats` · `coats-jackets` · `suits-blazers` · `dresses` · `jumpsuits` · `skirts` · `jeans` · `trousers` · `shorts` · `activewear` · `swimwear` · `sleepwear` · `underwear` · `socks-tights` · `shoes` · `bags` · `accessories` | Hard filter on garment type. Optional — the query text usually suffices. |
| `colour` | `black` · `white` · `grey` · `blue` · `green` · `red` · `pink` · `purple` · `yellow` · `orange` · `brown` · `beige` · `multi` | Hard filter on basic colour. For nuanced colours ('sage', 'rust') put them in q instead. |
| `brand` | string | Exact brand, e.g. 'H&M', 'ZARA', 'MANGO', 'Cotton On Women', 'Factorie'. See /api/catalog. |
| `price_min` | number (0–) | Minimum price, in the country's currency (needs country) |
| `price_max` | number (0–) | Maximum price (budget), in the country's currency (needs country) |
| `on_sale` | boolean | true → only discounted products |
| `size` | string | Only products listing this size as available, e.g. 'M', '10', '32' |

### POST /api/images

Upload a photo to search by (multipart field 'file')

## Filter values in the catalogue now

- country: `za` (South Africa) 28 422, `us` (United States) 19 743, `gb` (United Kingdom) 14 511
- department: `women` 31 924, `kids` 17 412, `men` 11 689, `baby` 1 599
- store: `zara` (Zara) 36 627, `co` (Cotton On) 12 165, `hm` (H&M) 11 330, `mango` (Mango) 2 554
- type: `t-shirts` 9 022, `trousers` 6 164, `accessories` 4 226, `coats-jackets` 3 555, `tops` 3 543, `knitwear` 3 537, `shirts-blouses` 3 456, `shoes` 3 434, `dresses` 3 177, `shorts` 3 143, `jeans` 2 848, `hoodies-sweats` 2 410, `underwear` 2 095, `swimwear` 1 899, `bags` 1 693, `skirts` 1 464, `sleepwear` 1 043, `suits-blazers` 972, `jumpsuits` 840, `socks-tights` 797, `activewear` 83
- colour: `multi` 12 784, `blue` 8 449, `white` 8 069, `black` 6 591, `brown` 5 340, `grey` 4 231, `green` 2 651, `yellow` 2 431, `red` 2 421, `pink` 2 411, `beige` 2 350, `purple` 722, `orange` 488
- brand (top): `zara` 34 774, `h&m` 11 330, `cotton on kids` 3 514, `body` 3 091, `mango` 2 554, `cotton on women` 2 207, `massimodutti` 1 853, `rubi` 1 687, `cotton on men` 1 665, `cotton on` 1

## Product fields

- `product_id` — Stable id '<store>:<sku>' (ZA) or '<store>-<country>:<sku>' ('zara-us:…'). Use it in /api/products/{product_id}[/similar|/tailor] and in exclude
- `title` — string
- `brand` — string
- `store` — Retailer name, e.g. 'H&M'
- `store_code` — hm | co | zara | mango
- `country` — za | us | gb — which country's shop sells it (and ships within that country)
- `currency` — ZAR | USD | GBP — every price of this product is in it
- `department` — Gender / age group: women | men | kids | baby
- `product_type` — string
- `colour` — Retailer's colour name
- `colour_family` — string
- `price` — Current price, in `currency`
- `price_display` — Price formatted for people, e.g. 'R1 299', '$49.90', '£25.99'
- `original_price` — Pre-discount price when on sale
- `on_sale` — boolean
- `discount_pct` — number
- `sizes` — Sizes listed as available when last checked
- `description` — string
- `materials` — string
- `image_url` — string
- `tailor_url` — The link to show people: tailor.ai page with a link to the store and 5 alternatives
- `store_url` — Link to the retailer's product page, via tailor.ai/go (logged, then redirected)
- `links` — object
- `card_markdown` — Ready-to-paste markdown card for chat replies

## Rules

- Read-only and free: no accounts, no checkout. People buy on the retailer's site.
- `score` isn't returned; result order is relevance within one response only.
- Stock and prices come from the retailers' sites and can lag; say "check the store for current stock".
- Be a good stylist: honest, specific, concise. Don't pad replies with every result.
