# Yeww — availability and MCP reference This file explains how to query public Yeww availability. It does not list live sessions. A response from the API or MCP is the availability at that moment. It does not hold the lesson and it can change before the customer books. The short guide is https://yeww.app/llms.txt. ## Live availability These URLs are examples inside the booking horizon. The API returns the sessions that are free when the URL is fetched. An empty offer list is a valid live result. The booking page checks the chosen session again. None of these links promises that a session is still free. - https://yeww.app/api/availability?sport=snowboard&date=2026-12-27&resort=Morzine - https://yeww.app/api/availability?sport=ski&date=2026-12-27&resort=Morzine - https://yeww.app/api/availability?sport=mtb&date=2026-12-27&resort=Morzine - https://yeww.app/snowboard/morzine?date=2026-12-27 - https://yeww.app/ski/morzine?date=2026-12-27 - https://yeww.app/mtb/morzine?date=2026-12-27 - https://yeww.app/.well-known/openapi.json Compatible agent clients can use MCP at https://yeww.app/api/mcp. A person connects that URL. Yeww does not join an assistant by itself. The human page is https://yeww.app/mcp. ## What a query returns Each offer is one session with one instructor: - instructor name, as shown publicly (a shortened name, not an internal id) - resort names, not meeting points - date, start and end in Europe/Paris wall-clock time (`HH:MM`) - session name and duration in minutes - customer price in euros, with two decimal places, currency `EUR`, `type` `customer` - `booking_url` and `profile_url` The HTTP field for the name is `coach_name`. The MCP field is `instructor`. The HTTP price is `{ "amount": "165.00", "currency": "EUR", "type": "customer" }`. MCP uses `"price": "165.00"`, `"currency": "EUR"` and `"price_type": "customer"`. `type` and `price_type` mean this is the final amount the customer is charged. It is the instructor's take-home plus a 10% Yeww fee. An instructor price of 15000 cents is charged as 165.00. The website charges those same cents. Not included: email, phone, payout, meeting point, booking reference, or any database id. Offers that would share one booking URL are omitted rather than guessed. A session that only touches the end of another session, such as 12:00 after a lesson that ends at 12:00, can still be offered. At most 100 offers are returned. `truncated` is true when more matched. ## GET https://yeww.app/api/availability No API key. Authentication is not required. Send no request body. The response uses `Cache-Control: no-store`. The same request is described at https://yeww.app/.well-known/openapi.json (OpenAPI 3.1.0). ### Parameters | Name | Required | Rule | | --- | --- | --- | | sport | yes | `ski`, `snowboard` or `mtb` | | date | one of date or from+to | `YYYY-MM-DD`, a Europe/Paris calendar day from today through 365 days ahead | | from, to | together, instead of date | Inclusive. At most 14 days. Do not send `date` as well | | resort | no | Resort name, up to 80 characters. Case, accents and extra spaces are ignored, so `chatel` matches Châtel. The response uses the stored spelling | | duration | no | Exact duration in minutes, from 1 to 1440 | | language | no | Exact language name, case-insensitive, up to 40 letters | | instructor | no | Public profile slug | | party | no | Riders in the group, from 1 to 99. Sessions that cannot take that many people are omitted | A missing `sport` returns `Missing required parameter: sport`. A missing date returns `Missing required parameter: date`. `from` without `to` returns `Missing required parameter: to`, and the reverse returns `Missing required parameter: from`. Sending `date` together with `from` or `to` returns `Use either date or from and to, not both`. An unusable date returns `Date must be YYYY-MM-DD`. A range longer than 14 days returns `Date range must be 14 days or fewer`. A range that ends before it starts returns `Date range must start on or before its end`. A date outside today through 365 days ahead returns `Date must be from today through 365 days ahead`. An unknown sport returns `Sport must be ski, snowboard or mtb`. An unknown parameter returns `Unknown parameter:` and the parameter name. An unknown instructor slug returns HTTP 404 and `{ "error": "Instructor not found" }`. These are HTTP 400 except for the missing instructor. A valid query that finds nothing returns HTTP 200 and `"offers": []`. That is not an error. An instructor who exists but is not free that day is an empty offer list, not `Instructor not found`. HTTP 429 means the caller should wait. The body is `{ "error": "Too many attempts. Please try again shortly." }` and `Retry-After` is set. HTTP 503 with `{ "error": "Rate limiter unavailable" }` means the limiter could not run, which is not the same as an invalid request. HTTP 500 with `{ "error": "Could not check availability" }` means the check failed. These responses do not include sessions, and they do not include a database message. The response allows any browser origin (`Access-Control-Allow-Origin: *`) because the body is public, the request uses no cookies and no credentials, and the rate limit still applies. `OPTIONS` is the preflight. Other Yeww routes are not covered by that header. Crawlers may fetch this path, `/api/mcp`, and `/.well-known/openapi.json`. `robots.txt` allows those paths and still disallows the rest of `/api/`. 30 requests per minute are allowed for this API and for each MCP tool call. The website search is separate. ### Example request ``` GET https://yeww.app/api/availability?sport=ski&date=2026-12-20&resort=Morzine ``` ### Example shape This is a shape example. `Example Coach` is not a Yeww instructor and `180.00` is not a live price. ```json { "timezone": "Europe/Paris", "checked_at": "2026-11-09T18:00:00.000Z", "truncated": false, "offers": [ { "coach_name": "Example C.", "profile_url": "https://yeww.app/coaches/example", "verified": true, "sports": ["ski"], "resorts": ["Morzine"], "languages": ["English"], "session_name": "Morning ski", "date": "2026-12-20", "start_time": "09:00", "end_time": "12:00", "duration_minutes": 180, "price": { "amount": "180.00", "currency": "EUR", "type": "customer" }, "booking_url": "https://yeww.app/coaches/example/book?date=2026-12-20&start=09%3A00&duration=180" } ] } ``` `checked_at` is UTC. `start_time` and `end_time` are Paris wall-clock times. The end time is the start plus the duration on that clock, including across the autumn clock change. ## MCP https://yeww.app/api/mcp Connect https://yeww.app/api/mcp. A person has to add that connection. Yeww is not invoked by a general question to an assistant. The page https://yeww.app/mcp explains the same endpoint for a human. It is not a coach profile. `POST` JSON-RPC 2.0. Send `content-type: application/json` and `accept: application/json, text/event-stream`. A browser `Origin` must be https://yeww.app. The response echoes that origin. A request with no `Origin`, such as a server-side assistant, is allowed. Another origin is HTTP 403 and is not given `Access-Control-Allow-Origin`. Preflight is `OPTIONS`. Allowed headers include `Content-Type`, `Accept`, `MCP-Protocol-Version` and `Mcp-Session-Id`. CORS does not skip the origin check, and the tools stay read-only. The body may come back as JSON or as `text/event-stream`. In the stream, read the `data:` line. It is a JSON-RPC object. Responses use `Cache-Control: no-store`. ### initialize ```json { "jsonrpc": "2.0", "id": 1, "method": "initialize", "params": { "protocolVersion": "2025-03-26", "capabilities": {}, "clientInfo": { "name": "example", "version": "1.0.0" } } } ``` The result identifies the server as `yeww` and says that booking happens on the booking URL. ### tools/list ```json { "jsonrpc": "2.0", "id": 2, "method": "tools/list", "params": {} } ``` The tools are `search_availability` and `get_instructor`. Both are read-only. There is no booking tool and no payment tool. ### search_availability Arguments are a strict object. Unknown keys, including a client-supplied price, are rejected. | Argument | Required | Rule | | --- | --- | --- | | sport | yes | `ski`, `snowboard` or `mtb` | | date | date, or from and to | `YYYY-MM-DD` | | from, to | together, instead of date | Inclusive, at most 14 days | | resort | no | string. Case, accents and extra spaces are ignored | | duration | no | minutes, number or numeric string | | language | no | string | | instructor | no | public slug | | party | no | number or numeric string | ```json { "jsonrpc": "2.0", "id": 3, "method": "tools/call", "params": { "name": "search_availability", "arguments": { "sport": "ski", "date": "2026-12-20", "resort": "Morzine" } } } ``` A successful `structuredContent` has `timezone` `Europe/Paris`, `checked_at`, `truncated` and `offers`. This shape example is not a live listing: ```json { "timezone": "Europe/Paris", "checked_at": "2026-11-09T18:00:00.000Z", "truncated": false, "offers": [ { "instructor": "Example C.", "resorts": ["Morzine"], "date": "2026-12-20", "start_time": "09:00", "end_time": "12:00", "session_name": "Morning ski", "duration_minutes": 180, "price": "180.00", "currency": "EUR", "price_type": "customer", "booking_url": "https://yeww.app/coaches/example/book?date=2026-12-20&start=09%3A00&duration=180", "profile_url": "https://yeww.app/coaches/example" } ] } ``` A tool failure sets `isError` and returns the same text as the HTTP `error` field, with no database detail. Examples: `Sport must be ski, snowboard or mtb`, `Date must be YYYY-MM-DD`, `Date range must be 14 days or fewer`, `Instructor not found`, `Could not check availability`, `Rate limiter unavailable`, `Too many attempts. Please try again shortly.` ### get_instructor `slug` is the last segment of https://yeww.app/coaches/{slug}. Letters, numbers and hyphens, up to 40 characters. ```json { "jsonrpc": "2.0", "id": 4, "method": "tools/call", "params": { "name": "get_instructor", "arguments": { "slug": "example" } } } ``` A found instructor has `name`, `slug`, `profile_url`, `verified: true`, `tagline`, `bio`, `sports`, `resorts`, `languages`, `specialisms`, `years_experience`, `rating`, `review_count`, `price_from`, `avatar_url` and up to five published `reviews`. `price_from` is the cheapest standard public price, `{ "amount": "180.00", "currency": "EUR", "type": "customer" }`, or null. It is the final customer price for that standard session, not a date-specific price and not the instructor's take-home. Use `search_availability` for a date. `example` above is not a real slug. A missing instructor returns `Instructor not found`. A slug of the wrong shape returns `Invalid instructor request`. A failed lookup returns `Could not load instructor`, which is not the same as not found. Reviews use the rider name shown on the public profile. Meeting points, contact details and internal ids are not returned. ## Booking Open `booking_url`. The customer chooses the session and pays on that Yeww page. Do not send the customer to a constructed URL with a different date or a price of your own. If the session has gone, the page does not substitute another one. Profile URL: https://yeww.app/coaches/{slug}. ## Timezone Search dates are Paris calendar days, not the visitor's local date and not the UTC date. Session times are Paris wall-clock times. `checked_at` is an UTC timestamp for when the query ran. ## Public pages Home https://yeww.app. Facts https://yeww.app/facts. FAQ https://yeww.app/faq. Instructors https://yeww.app/instructors. Ski https://yeww.app/ski. Snowboard https://yeww.app/snowboard. Mountain bike https://yeww.app/mtb. Winter resorts: https://yeww.app/ski/morzine, https://yeww.app/ski/les-gets, https://yeww.app/ski/avoriaz, https://yeww.app/ski/chatel, and the same paths under `/snowboard`. Mountain bike also has https://yeww.app/mtb/morgins and https://yeww.app/mtb/champery. The HTML of a resort page lists real sessions for the next 14 days. `?date=YYYY-MM-DD` lists one day, for example https://yeww.app/snowboard/morzine?date=2026-12-25. An instructor profile does the same with `/coaches/{slug}?date=YYYY-MM-DD`. Those pages use the same availability search as the API. They do not invent sessions. The sitemap does not list each date. Booking still opens `booking_url` and checks the session again. Contact: mailto:admin@yeww.app and https://yeww.app/faq.