Identifying a shoe

The POST /shoe-selection endpoint is a single progressive loop that walks the user through brand, model (or "I don't know"), variation (if applicable), size system, and size. Your caller never needs to know whether the underlying source is a per-product chart or a brand-level fallback chart. The server picks the right path based on what the brand has.

The loop

  1. Send an empty selection.
  2. The server responds with nextStep.field and a list of options.
  3. Render the options for the user. The user picks one.
  4. Copy the previous selection object, set the picked field, send it back.
  5. Repeat until complete: true. The response then contains a shoe object.
  6. Pass the shoe object directly to POST /sessions/{id}/shoes or POST /sessions/{id}/recommendations.

Example: brand with per-product chart

# 1. Start empty
curl -X POST /api/public/v1/shoe-selection -d '{"purpose": "ADD_TO_RACK", "selection": {}}'
→ nextStep.field = "brand", options = [Nike, Adidas, ...]

# 2. Pick Nike
curl -X POST /api/public/v1/shoe-selection -d '{"purpose": "ADD_TO_RACK", "selection": {"brandId": "nike"}}'
→ nextStep.field = "model", options = [Air Max 90, Pegasus 40, ..., {id: "", name: "Don't know / Can't find"}]

# 3. Pick Air Max 90
→ nextStep.field = "variation", options = [...]

# ... → variation → sizeSystem → size → complete: true

Example: "I don't know" path

# After brand, pick the empty-id option (id = "", name = "Don't know / Can't find")
curl -X POST /api/public/v1/shoe-selection -d '{"purpose": "ADD_TO_RACK", "selection": {"brandId": "nike", "modelId": ""}}'
→ nextStep.field = "globalChart", options = [Nike Men's, Nike Women's]

# Continue with globalChart → sizeSystem → size → complete: true

The final shoe has modelId and variationId set to "" and globalChartName populated. Same endpoint consumes it as input.

Closed-world guarantee

The options list is computed on the server from the actual catalog. You can only pick values we support. This matters especially for LLM-driven clients, since the model cannot hallucinate brand or size names that don't exist.

Recommendation targets

Use purpose: "RECOMMENDATION_TARGET" to walk the same flow for a target shoe. The loop terminates once we have enough to look up a size chart. The size field is skipped, since computing the size is the whole point of the recommendation.

End-to-end example: from a fresh session to a size recommendation

A recommendation always runs against a session. The flow is: create session → (optional) store foot measurement → (optional) add known-fit shoes → walk /shoe-selection with RECOMMENDATION_TARGET → pass the completed shoe as target.

# 1. Create a session
curl -X POST https://www.getsize.shoes/api/public/v1/sessions \
  -H "X-Api-Key: $KEY"
# → { "sessionId": "ses_abc123", ... }

# 2. (Optional) Store foot length
curl -X POST https://www.getsize.shoes/api/public/v1/sessions/ses_abc123/foot-measurement \
  -H "X-Api-Key: $KEY" -H "Content-Type: application/json" \
  -d '{ "rightFootLengthMm": 268, "leftFootLengthMm": 270 }'

# 3. Walk the wizard for the TARGET shoe
curl -X POST https://www.getsize.shoes/api/public/v1/shoe-selection \
  -H "X-Api-Key: $KEY" -H "Content-Type: application/json" \
  -d '{ "purpose": "RECOMMENDATION_TARGET", "selection": { "answers": [] } }'
# → nextStep with options. Append each pick to "answers" and call again.
# ... repeat until the response has "complete": true and a "shoe" object ...

# 4. Hand the completed shoe to /recommendations as target
curl -X POST https://www.getsize.shoes/api/public/v1/sessions/ses_abc123/recommendations \
  -H "X-Api-Key: $KEY" -H "Content-Type: application/json" \
  -d '{
        "target": {
          "answers": ["nike","pegasus-40","running","EU"],
          "metadata": {}
        }
      }'
# → { "recommendedSize": "42", "sizeSystem": "EU", "confidenceBasis": [ ... ] }

Important: the target field takes a ShoeSelection (the same { answers, metadata } pair returned from the wizard) — not a free-form { brand, model, gender } object. Walk the wizard first; the server then knows exactly which canonical shoe you mean.