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
- Send an empty selection.
- The server responds with
nextStep.fieldand a list of options. - Render the options for the user. The user picks one.
- Copy the previous
selectionobject, set the picked field, send it back. - Repeat until
complete: true. The response then contains ashoeobject. - Pass the
shoeobject directly toPOST /sessions/{id}/shoesorPOST /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.