# See a product on the shopper's body

```http
POST /v1/tryon
```

Source: https://docs.tryyoursize.com/api/reference/operations/starttryon/

**Key:** publishable (`pk_test_…` / `pk_live_…`), from an origin registered for the key.

Shows every size of the product's published garment on the body and recommends a size (from a few seconds to about 2 minutes). A body already shown with this garment version answers 200 at once; otherwise 202 and a job to poll. Every answer carries a new `viewer_token`, the only way (with the shopper's session) to read the job. With a shopper session (`Authorization: Bearer tys_sess_…`) the try-on is linked to the shopper and, in live mode, delivering a done result records the store connection and the size the store receives.

## Authentication

Publishable key (`pk_test_…` / `pk_live_…`), from an origin registered for the key.

## Parameters

- `view` (query, `"full" | "summary"`, optional): `full` (default) answers with the whole `result` (meshes for every size, MBs). `summary` leaves `result` out and answers `summary` instead (the recommended size and the sizes that can be worn, a few bytes): for the size-guide button and the store's recommended-size event, which never need the meshes.
- `start` (query, `boolean`, optional): `false` answers only with an existing result and never queues a simulation: a done or running try-on of this body, or 404 ("not simulated yet"). With `view=summary`, a miss may answer 200 with a size estimate instead (`status: done`, empty `id`, `summary.method: estimate`). Page views (the size-guide and inline elements) use it; a full simulation starts only on an explicit shopper action ("See it on you").

## Request body

`application/json`: `TryOnRequest`

The product and the shopper's body as on screen: the same body as `/v1/bodies/preview`, with the preview's `body_state` (required for garments; opaque). For a `footwear` product, `feet` is what counts (without it the answer is 404: no shoe size without feet) and `body_state` may be omitted.

- `product` (`string`, required, max length 120): The product's SKU / style ID in the store (what the shop passes to the element).
- `basics` (`BodyBasics`, required)
  - `sex` (`"female" | "male"`, required)
  - `age_years` (`integer`, required)
  - `height_mm` (`number (double)`, required)
  - `weight_kg` (`number (double)`, required)
- `measurements` (`Measurement[]`, optional, max 64 items)
  - `code` (`"neck_girth" | "shoulder_width" | "arm_length" | "armscye_girth" | "upper_arm_girth" | "wrist_girth" | "chest_girth" | "underbust_girth" | "bust_point_to_bust_point" | "shoulder_to_bust_point" | "back_length" | "waist_girth" | "front_waist_arc" | "high_hip_girth" | "abdomen_girth" | "hip_girth" | "front_hip_arc" | "thigh_girth" | "knee_girth" | "calf_girth" | "ankle_girth" | "inseam" | "outseam" | "crotch_length"`, required): Body measurement from set v1.
  - `value_mm` (`number (double)`, required): Measured value in millimetres.
  - `source` (`"tape_self" | "tape_helper" | "flat_garment" | "estimated" | "bra_size"`, required): How the value was obtained. bra_size: derived from the shopper's bra size (underbust and bust only).
  - `sd_mm` (`number (double)`, optional): The value's uncertainty (one standard deviation, mm), when known: set for values from a bra size; a tape measured twice may send its own. Omitted: the default for its source.
- `feet` (`Feet`, optional): The shopper's feet: the larger foot, in millimetres. `paper`: traced at home (heel against a wall, both feet, measured twice). `reference`: implied by a size the shopper wears (`reference`; `length_mm` is then derived). `estimated`: from height and sex (less precise; `length_mm` is derived from the request's basics).
  - `source` (`"paper" | "reference" | "estimated"`, required)
  - `length_mm` (`number (double)`, optional): Heel to the longest toe. Required for `paper`.
  - `width_mm` (`number (double)`, optional): Optional width at the widest point (the ball).
  - `girth_mm` (`number (double)`, optional): Optional ball (instep) girth.
  - `reference` (`object`, optional)
    - `brand` (`string`, optional, max length 80)
    - `system` (`"eu" | "uk" | "us_men" | "us_women" | "mondopoint"`, required): A shoe size system: `eu` (Paris points), `uk`, `us_men`, `us_women`, or `mondopoint` (foot length in mm).
    - `size` (`string`, required, max length 16)
  - `updated_at` (`string (date-time)`, optional)
- `fit` (`FitProfile`, optional): The shopper's fit preference and usual sizes (optional). Without it, a signed-in shopper's saved profile is used; a guest gets sizes for a regular fit.
  - `preference` (`PreferredFit`, optional)
  - `preference_tops` (`PreferredFit`, optional)
  - `preference_bottoms` (`PreferredFit`, optional)
  - `usual_sizes` (`UsualSize[]`, optional, max 20 items)
    - `id` (`string (uuid)`, optional)
    - `brand` (`string`, required, max length 40): A brand key from GET /v1/usual-size-brands.
    - `line` (`"tops" | "bottoms"`, required)
    - `sex` (`"female" | "male"`, optional): The brand's women's (female) or men's (male) line. Defaults to the shopper's own.
    - `size` (`string`, required, max length 16): The size label as the brand writes it (one of the brand's sizes for this line).
    - `source` (`"declared" | "kept_purchase"`, optional)
    - `created_at` (`string (date-time)`, optional)
  - `updated_at` (`string (date-time)`, optional)
- `body_state` (`number (double)[]`, optional, max 64 items): The `body_state` of the body preview on screen.

## Responses

### 200

Done (an existing result) (`TryOnJob`)

- `id` (`string`, required): The try-on's id (uuid). Empty only for a size estimate (POST ?start=false&view=summary answered with no try-on of this body); there is nothing to poll.
- `viewer_token` (`string`, optional): Only in the answer to POST /v1/tryon: the window's proof that it may read this try-on. Send it as `Authorization: Bearer tys_view_…` to GET /v1/tryon/{tryon_id}. Stored hashed; never sent again.
- `status` (`"queued" | "running" | "done" | "failed"`, required)
- `progress` (`object`, required)
  - `sizes_done` (`integer`, required)
  - `sizes_total` (`integer`, required)
- `result` (`object`, optional): Present when `status` is `done`, and while it runs: the sizes computed so far, each with `method` (simulated) and `state` (preview: shown early, may still change; settled; refining: still being computed, no mesh yet; simulated). The try-on result for the window: body mesh and body_state (no basics, no tape measurements), garment with its fabric and estimated POMs, recommended size and per-size meshes, pressure kPa, ease mm and zones. Binary arrays are base64 little-endian; per-vertex values are rounded to display precision.
- `summary` (`object`, optional): Present when `status` is `done` and the request asked for `view=summary`: what a store may receive (sizes only, never measurements). Size labels are the garment's (Studio) sizes; map them with `shop_sizes` from GET /v1/products/{product}/tryon.
  - `recommended_size` (`string`, optional): The recommended size; absent when no size can be worn.
  - `no_size_fits` (`boolean`, required)
  - `wearable_sizes` (`string[]`, required): Sizes that can be worn on this body (judged on this body), smallest to largest.
  - `between` (`string[]`, optional): Footwear only - the two sizes the foot sits between (see `footwear.between`).
  - `method` (`"estimate" | "simulated" | "measured"`, optional): How the size was determined (`measured`: a footwear size from the shopper's measured feet): `estimate` (a size estimate, no try-on of this body yet) or `simulated` (from the try-on of this body). A coarse informational label: do not build logic on its values.
- `recommendation` (`object`, optional): The size answer with its method. On the first answer of a try-on it may already be there (`method: estimate`) while the 3D view is computed; once done it is the try-on's own size. An estimate is final (`ready` or `none`) only when it is certain for this body; otherwise the status is `computing`, no size is named, and the try-on's 3D view gives it.
  - `recommended_size` (`string`, optional)
  - `method` (`"estimate" | "simulated" | "measured"`, required): Same as `summary.method`. A coarse informational label; do not build logic on its values.
  - `status` (`"ready" | "none" | "computing" | "unavailable"`, required)
  - `between` (`string[]`, optional): Two adjacent sizes when they are genuinely close (smaller first), or, for footwear, the two sizes the foot sits between.
  - `confidence` (`number (double)`, optional): Calibrated probability (0-1) that the shopper keeps the recommended size (either size of `between`). Present on some estimates.
  - `facts` (`object[]`, optional): Facts for the explanation, per zone - the body girth the answer rests on (`measured` or `estimated`, with its uncertainty) and the room (garment girth minus body girth, mm; negative is smaller than the body) in the recommended size and its neighbours.
    - `zone` (`string`, optional)
    - `body_mm` (`integer`, optional)
    - `body_sd_mm` (`integer`, optional)
    - `body_source` (`"measured" | "estimated"`, optional)
    - `sizes` (`object[]`, optional)
      - `size` (`string`, optional)
      - `garment_mm` (`integer`, optional)
      - `room_mm` (`integer`, optional)
  - `wearable_sizes` (`string[]`, optional)
- `footwear` (`FootwearAnswer`, optional): The numbers behind a footwear size, per size of the chart. Lengths in millimetres, rounded to 0.1 mm. Facts only: the room in front of the toes and how the width compares, never a verdict.
  - `source` (`"paper" | "reference" | "estimated"`, required)
  - `foot_length_mm` (`number (double)`, required)
  - `uncertainty_mm` (`number (double)`, required): The typical measuring uncertainty of the foot length.
  - `between` (`string[]`, optional): Two sizes when the foot sits at their boundary within its measuring uncertainty (the recommended size is the longer one); for an estimate, the range of sizes it may be. Absent when the size is clear.
  - `fitting` (`string`, optional): The recommended width fitting, when the chart has fittings.
  - `room_from_chart` (`boolean`, optional): True when the brand's chart gives foot lengths (then `chart_foot_mm` is the foot length each size is made for) rather than the shoe's inside length.
  - `sizes` (`object[]`, required)
    - `size` (`string`, required)
    - `fitting` (`string`, optional)
    - `toe_room_mm` (`number (double)`, required): Room in front of the longest toe (negative - shorter than the foot).
    - `chart_foot_mm` (`number (double)`, optional)
    - `width_diff_mm` (`number (double)`, optional): The size's width minus the foot's (negative - narrower than the foot).
    - `girth_diff_mm` (`number (double)`, optional)
    - `wearable` (`boolean`, required): The toe room is within the shoe type's usual range.
- `error` (`object`, optional): Present when `status` is `failed`.
  - `code` (`string`, required): INVALID_BODY, UNSUPPORTED_CATEGORY, MISSING_POM, INVALID_POM, INVALID_FABRIC, NO_SIZES, UNAVAILABLE or ENGINE_ERROR.
  - `message` (`string`, required)

### 202

Queued or running; poll GET /v1/tryon/{tryon_id} (`TryOnJob`)

- `id` (`string`, required): The try-on's id (uuid). Empty only for a size estimate (POST ?start=false&view=summary answered with no try-on of this body); there is nothing to poll.
- `viewer_token` (`string`, optional): Only in the answer to POST /v1/tryon: the window's proof that it may read this try-on. Send it as `Authorization: Bearer tys_view_…` to GET /v1/tryon/{tryon_id}. Stored hashed; never sent again.
- `status` (`"queued" | "running" | "done" | "failed"`, required)
- `progress` (`object`, required)
  - `sizes_done` (`integer`, required)
  - `sizes_total` (`integer`, required)
- `result` (`object`, optional): Present when `status` is `done`, and while it runs: the sizes computed so far, each with `method` (simulated) and `state` (preview: shown early, may still change; settled; refining: still being computed, no mesh yet; simulated). The try-on result for the window: body mesh and body_state (no basics, no tape measurements), garment with its fabric and estimated POMs, recommended size and per-size meshes, pressure kPa, ease mm and zones. Binary arrays are base64 little-endian; per-vertex values are rounded to display precision.
- `summary` (`object`, optional): Present when `status` is `done` and the request asked for `view=summary`: what a store may receive (sizes only, never measurements). Size labels are the garment's (Studio) sizes; map them with `shop_sizes` from GET /v1/products/{product}/tryon.
  - `recommended_size` (`string`, optional): The recommended size; absent when no size can be worn.
  - `no_size_fits` (`boolean`, required)
  - `wearable_sizes` (`string[]`, required): Sizes that can be worn on this body (judged on this body), smallest to largest.
  - `between` (`string[]`, optional): Footwear only - the two sizes the foot sits between (see `footwear.between`).
  - `method` (`"estimate" | "simulated" | "measured"`, optional): How the size was determined (`measured`: a footwear size from the shopper's measured feet): `estimate` (a size estimate, no try-on of this body yet) or `simulated` (from the try-on of this body). A coarse informational label: do not build logic on its values.
- `recommendation` (`object`, optional): The size answer with its method. On the first answer of a try-on it may already be there (`method: estimate`) while the 3D view is computed; once done it is the try-on's own size. An estimate is final (`ready` or `none`) only when it is certain for this body; otherwise the status is `computing`, no size is named, and the try-on's 3D view gives it.
  - `recommended_size` (`string`, optional)
  - `method` (`"estimate" | "simulated" | "measured"`, required): Same as `summary.method`. A coarse informational label; do not build logic on its values.
  - `status` (`"ready" | "none" | "computing" | "unavailable"`, required)
  - `between` (`string[]`, optional): Two adjacent sizes when they are genuinely close (smaller first), or, for footwear, the two sizes the foot sits between.
  - `confidence` (`number (double)`, optional): Calibrated probability (0-1) that the shopper keeps the recommended size (either size of `between`). Present on some estimates.
  - `facts` (`object[]`, optional): Facts for the explanation, per zone - the body girth the answer rests on (`measured` or `estimated`, with its uncertainty) and the room (garment girth minus body girth, mm; negative is smaller than the body) in the recommended size and its neighbours.
    - `zone` (`string`, optional)
    - `body_mm` (`integer`, optional)
    - `body_sd_mm` (`integer`, optional)
    - `body_source` (`"measured" | "estimated"`, optional)
    - `sizes` (`object[]`, optional)
      - `size` (`string`, optional)
      - `garment_mm` (`integer`, optional)
      - `room_mm` (`integer`, optional)
  - `wearable_sizes` (`string[]`, optional)
- `footwear` (`FootwearAnswer`, optional): The numbers behind a footwear size, per size of the chart. Lengths in millimetres, rounded to 0.1 mm. Facts only: the room in front of the toes and how the width compares, never a verdict.
  - `source` (`"paper" | "reference" | "estimated"`, required)
  - `foot_length_mm` (`number (double)`, required)
  - `uncertainty_mm` (`number (double)`, required): The typical measuring uncertainty of the foot length.
  - `between` (`string[]`, optional): Two sizes when the foot sits at their boundary within its measuring uncertainty (the recommended size is the longer one); for an estimate, the range of sizes it may be. Absent when the size is clear.
  - `fitting` (`string`, optional): The recommended width fitting, when the chart has fittings.
  - `room_from_chart` (`boolean`, optional): True when the brand's chart gives foot lengths (then `chart_foot_mm` is the foot length each size is made for) rather than the shoe's inside length.
  - `sizes` (`object[]`, required)
    - `size` (`string`, required)
    - `fitting` (`string`, optional)
    - `toe_room_mm` (`number (double)`, required): Room in front of the longest toe (negative - shorter than the foot).
    - `chart_foot_mm` (`number (double)`, optional)
    - `width_diff_mm` (`number (double)`, optional): The size's width minus the foot's (negative - narrower than the foot).
    - `girth_diff_mm` (`number (double)`, optional)
    - `wearable` (`boolean`, required): The toe room is within the shoe type's usual range.
- `error` (`object`, optional): Present when `status` is `failed`.
  - `code` (`string`, required): INVALID_BODY, UNSUPPORTED_CATEGORY, MISSING_POM, INVALID_POM, INVALID_FABRIC, NO_SIZES, UNAVAILABLE or ENGINE_ERROR.
  - `message` (`string`, required)

### 400

Invalid request (`Error`)

### 401

Missing or invalid credentials (`Error`)

### 403

Not allowed (`Error`)

### 404

No published garment for the product, or (start=false) this body was not simulated yet (`Error`)

### 422

The content is rejected (e.g. a body that cannot be rebuilt) (`Error`)

### 503

A dependency is temporarily unavailable; retry later (`Error`)

## Example

```bash
curl -X POST https://api.tryyoursize.com/v1/tryon \
  -H "Authorization: Bearer pk_test_…" \
  -H "TYS-Version: 2026-10-25" \
  -H "Content-Type: application/json" \
  -d @body.json
```
