A public REST API at /api/v1 gives developers read access to school, resort, and instructor data, with scoped API keys, per-key rate limits, and a documented error shape. The MCP server at /mcp lets AI assistants search the platform — and, with a school-scoped key, manage your school's profile, lessons, bookings, and reviews.
Quick answer
The REST API lives at /api/v1 (Swagger docs at /api/v1/docs) and accepts keys via the Authorization: Bearer or X-API-Key header. MCP uses /mcp over Streamable HTTP: public discovery needs no key; private school reads and writes need a school-scoped bearer key with the matching scopes on every request. Default shared REST/MCP key limits: 60 requests/minute, 10,000/day.
For technical teams who want programmatic access to platform data — building custom dashboards, integrating with internal systems, or making your school workable by AI agents — the platform provides a public REST API and an MCP (Model Context Protocol) server.
The API is versioned under /api/v1 (every response carries an X-API-Version header). Read endpoints:
GET /api/v1/schools and GET /api/v1/schools/{slug} — search and detail, with filters for country, resort, activity, level, language, school type, certified, and featured, plus page and limit (max 100 per page)GET /api/v1/resorts and GET /api/v1/resorts/{slug}GET /api/v1/countries and GET /api/v1/countries/{slug}GET /api/v1/instructorsGET /api/v1/activities, /experience-levels, /languages, and /age-ranges — the taxonomy lists used by the filtersInteractive documentation lives at /api/v1/docs (Swagger UI), the machine-readable spec at /api/v1/openapi.json, and a developer guide at /api-docs on the main site. For AI agents there are also /llms.txt and /llms-full.txt site descriptions.
Every response uses one envelope:
Errors invert it: { "success": false, "error": { "message": "...", "status": 404 } }.
Keys start with the fass_ prefix. For REST requests, either header works:_
Authorization: Bearer fass_xxxX-API-Key: fass_xxxQuery-string keys (?api_key=) are deliberately not supported — they leak long-lived credentials into proxy logs and browser history.
MCP uses Authorization: Bearer on every authenticated request. The REST X-API-Key alternative is not the MCP authentication contract.
Each key carries: a name and description, a set of scopes, optional per-minute and per-day rate limits, an optional expiry date, and optionally a school link. Scopes follow a resource:read / resource:write pattern — schools:read, instructors:read, lessons:write, bookings:write, reviews:write, analytics:read, and so on. The scope model fails closed: a request needs the matching scope for its resource and method, and endpoints outside the documented surface are denied outright.
School owners and co-owners can approve short-lived school MCP keys at /account/school-mcp-access, choosing only the necessary scopes. These keys require a verified active account, explicit consent, and the issuer's current ownership access; they expire within 30 days and can be rotated or revoked from that page. Inbox permission is a separate opt-in. Administrator-issued service keys remain available from the dashboard's API keys panel and retain their separate lifetime. The full key is shown once; only its hash is stored. Delegated school/customer credentials must be replaced through their consent pages; generic administrator edits cannot widen or restore their consent. Usage records include endpoint, status, and response time.
Three layers apply, all per minute unless stated:
/api/v1 works for anonymous reads but is limited to 60 requests/minute per IP./api surface against runaway clients.Keyed responses include live quota headers: X-RateLimit-Limit-Minute, X-RateLimit-Remaining-Minute, X-RateLimit-Limit-Day, and X-RateLimit-Remaining-Day. Watch the remaining counts and back off before you hit zero.
When you exceed a key's limit you get HTTP 429 with a Retry-After header (in seconds) and:
The outer per-IP fence uses a shorter body: { "error": "rate_limited", "retryAfter": 60 }, also with Retry-After. Honour the header — sleeping for retryAfter seconds and retrying is the correct client behaviour. If you hit limits routinely, that's usually a polling pattern that should be a cache.
The codes you'll meet, and what they mean:
{ "error": "Invalid API key", "message": "The provided API key is invalid, expired, or has been revoked." }success: false envelopeThe MCP server is the API's equivalent for AI agents. It runs at:
using the Streamable HTTP transport (POST for JSON-RPC requests, GET for the notification stream, DELETE to close a session — your MCP client handles all of that). A discovery document at /mcp/info lists every tool, and the full developer guide is at /mcp-docs.
For school users, the main tool groups are:
search_schools, get_school_detail, search_resorts, get_resort_detail, list_countries, list_activities, search_instructors, compare_schools, search_lessons, get_lesson_detail, get_lesson_availability, and get_lesson_quote. These expose public school, resort, instructor, and lesson information. Lesson search shares the website's filters. Availability is provisional: typical school times do not establish remaining capacity, and quotes reserve no places. The booking form rechecks eligibility, capacity, and price.get_my_school requires schools:read, instructors:read, and lessons:read; get_my_dashboard requires analytics:read, bookings:read, reviews:read, and instructors:read.Additional platform-administration and content tools have separate restricted keys and scopes; a school key does not grant that access.
Four operational read tools are also available. get_my_calendar and get_instructor_availability read up to 31 school-local days with the required booking/instructor/availability scopes and omit learner contact, medical, and payment fields. list_school_conversations and get_school_conversation require messages:read, current owner/co-owner inbox permission, and the account's existing history cutoff. Administrator observer powers are not delegated through school keys. Message text is included only on explicit request, is bounded, and reading does not mark a thread read.
Customers can grant separate, short-lived personal access at /account/mcp-access after signing in with a verified email. The customer scopes are customer:bookings:read and customer:bookings:write; they cannot be combined with school or administration scopes. list_my_customer_bookings and get_customer_booking_status read only the customer's account-owned bookings. prepare_customer_booking returns a signed handoff for the same customer to continue in the browser. It creates no booking or capacity hold until the customer submits the booking form with participant details, policy acceptance, and CAPTCHA; online checkout then uses the existing browser payment flow where supported. Keys expire within 30 days and can be revoked or rotated from the same account page.
To connect an MCP-capable client, add a remote server with the URL above. For management access, send your key as an Authorization: Bearer fass_xxx header on every request, including session POST, GET, and DELETE requests. A session ID alone does not authenticate the client. Start a new session when changing keys or scopes. Public access needs no authentication header.
MCP has its own limits: 60 requests/minute per IP, 30 authenticated tool calls/minute per key, and a deliberately tight 5/minute throttle on failed key attempts. Authenticated requests also consume the shared REST/MCP key budget described above. Invalid-key failures come back as JSON-RPC errors — code -32001 (HTTP 401), or -32002 when failed attempts are throttled (HTTP 429). Tool-level scope or ownership refusals are returned as MCP tool errors.
Native clients that omit Origin are supported. Browser clients that supply Origin must match the deployment's configured trusted origins. Sessions have idle timeouts and count limits; reconnect if a session expires, and close unused sessions.
list_my_bookings accepts optional status, start_date (inclusive), and end_date (exclusive) filters. Dates are ISO 8601 timestamps with a timezone. Pagination uses limit (default 50, maximum 100) and offset (default 0). The result includes total, limit, offset, nextOffset, and bookings. Repeat the same filters with offset set to nextOffset until it is null.
get_my_booking accepts booking_id to retrieve one booking belonging to your school. Both booking read tools require bookings:read.
Customer booking confirmation, participant details, consent, CAPTCHA, and payment require the browser. Selected-instructor slots may report observed 0/1 session capacity; unverified staffing and remaining group seats remain unknown. Availability reserves no capacity. Customer cancellation/refunds, school inbox replies, calendar/availability changes, rescheduling, instructor assignments, refunds, photo galleries, school policies/FAQs, support tickets, and full lesson configuration still require the website. cancel_booking changes booking status; it does not issue a refund. update_my_school accepts description, website, email, phone, and default currency, rather than school name, hours, or pricing.
An Ask ChatGPT or Ask Claude link can open a prepared prompt about a public guide. It does not automatically connect the assistant to your FASS account, grant a key, or give it access to a private dashboard. Provider support for prefilled prompts and remote MCP depends on the client and account.
To act on school data, configure an MCP-capable client separately using the current MCP guide and a school-scoped key. Start with the minimum read permissions you need. Review proposed changes before authorising write actions; an AI answer is not proof the change was saved.
Keep API keys in the connector's secure configuration, never in a prompt, guide URL, screenshot, or public message. Do not paste private learner details into an external assistant unless you are authorised to share them. Public guide links can help explain a process without disclosing account data.
Search French schools, five results per page, with a key:
The response's data array contains school objects (slug, name, type, description, country, resort, contact details, private and group lesson prices, currency, and canonical URL), with pagination in meta. Drop the header and the same call still works under the anonymous per-IP limit — useful for trying things out before a key is issued.
Outbound webhooks currently cover support-ticket events only: ticket.created, ticket.replied, ticket.status_changed, and ticket.resolved, configured from the dashboard's ticket webhooks tab. Payloads are signed with HMAC-SHA256 in an X-Ticket-Signature header so your handler can verify authenticity. There are no booking or review webhooks yet; use the school's MCP read tools at a sensible polling interval.
API and MCP support is best-effort for Starter and Independent Instructor plans, and prioritised for School and Multi-School plans. For most integrations the Swagger docs and /mcp-docs are enough; for edge cases or higher rate limits, contact us through the dashboard support channel.
Still need help with this article?
Send the article URL and the step that needs more explanation.