{"openapi":"3.1.0","info":{"title":"Washlib Public API","version":"1.0.0","description":"Read-only API to discover car-wash centers, services, prices and availability on Washlib. Catalog and availability endpoints are open (no API key). An MCP server is also available at /api/mcp for AI agents."},"servers":[{"url":"https://www.washlib.com"}],"paths":{"/api/public/centers":{"get":{"operationId":"findCenters","summary":"Find centers by location text or coordinates","description":"Provide ?location (city, postal code, name or slug) OR ?latitude&longitude&radiusKm.","parameters":[{"name":"location","in":"query","required":false,"schema":{"type":"string"},"description":"City, postal code, center name or slug"},{"name":"latitude","in":"query","required":true,"schema":{"type":"number","minimum":-90,"maximum":90}},{"name":"longitude","in":"query","required":true,"schema":{"type":"number","minimum":-180,"maximum":180}},{"name":"radiusKm","in":"query","required":true,"description":"Search radius in kilometres (max 50)","schema":{"type":"number","exclusiveMinimum":true,"minimum":0,"maximum":50,"description":"Search radius in kilometres (max 50)"}},{"name":"serviceType","in":"query","required":false,"schema":{"type":"string","enum":["fixed","mobile","home"]}}],"responses":{"200":{"description":"Matching centers"},"400":{"description":"Invalid query"},"429":{"description":"Rate limit exceeded"}}}},"/api/public/centers/{id}/services":{"get":{"operationId":"getServices","summary":"List a center’s services with starting prices","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":"Numeric center id"}],"responses":{"200":{"description":"Services for the center"},"400":{"description":"Invalid center id"}}}},"/api/public/availability":{"get":{"operationId":"searchAvailableSlots","summary":"Available slots near a location on a date","parameters":[{"name":"location","in":"query","required":true,"description":"City, postal code, center name or slug, e.g. \"Paris\" or \"75017\"","schema":{"type":"string","minLength":1,"description":"City, postal code, center name or slug, e.g. \"Paris\" or \"75017\""}},{"name":"date","in":"query","required":true,"description":"Target day in YYYY-MM-DD (Europe/Paris)","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Target day in YYYY-MM-DD (Europe/Paris)"}},{"name":"serviceType","in":"query","required":false,"description":"Filter: fixed (on-site), mobile, or home service","schema":{"type":"string","enum":["fixed","mobile","home"],"description":"Filter: fixed (on-site), mobile, or home service"}}],"responses":{"200":{"description":"Centers with available slots"},"400":{"description":"Invalid query"}}}},"/api/public/recommend":{"get":{"operationId":"recommendWash","summary":"Recommend a wash formula","parameters":[{"name":"vehicleType","in":"query","required":true,"description":"e.g. citadine, berline, SUV, utilitaire","schema":{"type":"string","minLength":1,"description":"e.g. citadine, berline, SUV, utilitaire"}},{"name":"dirtLevel","in":"query","required":true,"schema":{"type":"string","enum":["light","moderate","heavy"]}},{"name":"season","in":"query","required":false,"schema":{"type":"string","enum":["winter","spring","summer","autumn"]}}],"responses":{"200":{"description":"Recommendation"}}}},"/api/mcp":{"post":{"operationId":"mcpStreamableHttp","summary":"MCP server (Streamable HTTP)","description":"Model Context Protocol endpoint. Tools: search_available_slots, find_centers, get_services, recommend_wash (open) and get_booking (requires a Firebase phone-OTP bearer token). Resources: washlib://centers, washlib://services, washlib://pricing, washlib://faq.","responses":{"200":{"description":"MCP JSON-RPC response"}}}}},"components":{"schemas":{"FindCentersInput":{"type":"object","properties":{"latitude":{"type":"number","minimum":-90,"maximum":90},"longitude":{"type":"number","minimum":-180,"maximum":180},"radiusKm":{"type":"number","exclusiveMinimum":true,"minimum":0,"maximum":50,"description":"Search radius in kilometres (max 50)"},"serviceType":{"type":"string","enum":["fixed","mobile","home"]}},"required":["latitude","longitude","radiusKm"],"additionalProperties":false},"GetServicesInput":{"type":"object","properties":{"centerId":{"type":"integer","exclusiveMinimum":true,"minimum":0,"description":"Numeric center id as returned by find_centers"}},"required":["centerId"],"additionalProperties":false},"SearchAvailableSlotsInput":{"type":"object","properties":{"location":{"type":"string","minLength":1,"description":"City, postal code, center name or slug, e.g. \"Paris\" or \"75017\""},"date":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Target day in YYYY-MM-DD (Europe/Paris)"},"serviceType":{"type":"string","enum":["fixed","mobile","home"],"description":"Filter: fixed (on-site), mobile, or home service"}},"required":["location","date"],"additionalProperties":false},"RecommendWashInput":{"type":"object","properties":{"vehicleType":{"type":"string","minLength":1,"description":"e.g. citadine, berline, SUV, utilitaire"},"dirtLevel":{"type":"string","enum":["light","moderate","heavy"]},"season":{"type":"string","enum":["winter","spring","summer","autumn"]}},"required":["vehicleType","dirtLevel"],"additionalProperties":false}}}}