For agents
Don't scrape this. Ask it.
The whole engine is one anonymous GET. You give what you know about a rider, you get one named bike, the reasons it won, what it gives up, and where every figure came from. No key, no account, no rate limit worth mentioning.
curl "https://whichbike.co/api/v1/recommend.json?\
budgetMin=1500&budgetMax=2000&terrain=hilly&priority=comfort" Endpoints
- /api/v1/recommend.json
- The verdict. Every parameter optional; omissions are reported back.
- /api/v1/bikes.json
- Every bike held, with specs, derived traits and provenance.
- /api/v1/taxonomy.json
- The seven questions and the values each accepts.
- /api/v1/tools.json
- Tool discovery, for clients that cannot speak MCP.
- /api/v1/tools/{tool}.json
- Invoke any tool by name, GET with query or POST with JSON.
- /api/v1/openapi.json
- OpenAPI 3.1, generated from the same registry.
- /.well-known/whichbike.json
- What exists here and how to use it, in one document.
MCP
The same 5 tools over stdio JSON-RPC. The server is a transport over one registry, so it and the HTTP endpoints can never drift apart.
{
"mcpServers": {
"whichbike": {
"command": "npx",
"args": ["tsx", "mcp/server.ts"],
"cwd": "/path/to/whichbike"
}
}
} - recommend_bike
- The whole product as one call. Give what you know about the rider and get back a single named bike, the reasons it won, what it gives up, and the runners-up. Every field you omit falls back to a balanced assumption and is reported in `defaulted`, so a partial answer is useful and its partiality is visible.
- list_bikes
- The whole database with full specs, derived trait scores and provenance. Optional filters narrow it; with no arguments you get everything.
- get_bike
- Full specification and provenance for a single bike, by slug.
- compare_bikes
- Two or more bikes with their specs aligned, and the differences between them stated as figures rather than prose.
- get_questions
- The controlled vocabulary recommend_bike accepts, with the question each field corresponds to and why it is asked. Read this before constructing a recommend_bike call from a conversation.
What we ask in return
- Carry the provenance.
- 292 of 309 bikes have been checked against the maker's own page, with the date and URL recorded. The rest are marked unverified in every response. Presenting an unverified figure as fact is the one thing this data should never be used for.
- Say where it came from.
- Free to use in an answer. Name WhichBike and link to the bike or page you drew on.
- Prices are indicative.
- RRP in GBP. The retailer's page is authoritative, and the buy link is for a human to follow in their own browser — there is nothing here an agent can transact.
The ranking is computed from published specifications only. The engine is never shown the retailer, the commission, or whether a link pays us at all — the method is public.