Permets à tes clients de réserver des cours de surf directement sur ta plateforme. REST · JSON · OCTO — la disponibilité réelle de chaque école, lisible par n'importe quel marketplace ou channel manager. Connecte une fois, atteins beaucoup.
{
"spot": "Carcavelos",
"date": "2026-06-22",
"time": "10:00",
"level": "iniciante",
"capacity": 6,
"vacancy": 4
}Pas de protocole fermé. Nous parlons OCTO — le standard ouvert des réservations d'activités. Tu intègres une fois, tu atteins tout le monde.
OCTO (octo.travel), c'est la façon dont les systèmes de réservation, channel managers et marketplaces d'activités se parlent. Une intégration contre SurfBooking, et l'offre devient lisible par n'importe quel acheteur OCTO. Pour ceux qui préfèrent, nous renvoyons aussi le format natif SB et des variantes pour les adaptateurs existants.
Si tu distribues des expériences — un hôtel, une agence, un DMC, une app de tourisme ou une plateforme d'hébergement — l'API SurfBooking met la disponibilité réelle des cours de surf entre tes mains.
Ils proposent des cours de surf en extra au client, avec réservation en temps réel — sans appels, sans coordination manuelle.
Ils incluent des cours de surf dans n'importe quel forfait, réservables directement via l'API, avec idempotence sur les requêtes répétées.
Ils ajoutent le surf à n'importe quel itinéraire de groupe et confirment la disponibilité en temps réel, avec le nombre de places libres en direct.
Ils montrent écoles, spots et disponibilité en direct. Le scope forecast ajoute les conditions par spot.
Locations courte durée et appartements font de l'upsell de surf au moment du paiement — confirmé en quelques secondes via l'API.
Une intégration. Toutes les écoles de la plateforme. Places réelles, prix réels, anti-overbooking — confirmé en millisecondes.
Ce n'est pas la même API pour tout le monde. Chaque clé est limitée (least-privilege) à ce dont ce partenaire a besoin — jamais plus que ça.
Ils lisent les cours disponibles et créent des réservations au nom du client. Le chemin v1 (OCTO). L'accès de ceux qui distribuent des cours.
Ils recommandent la bonne planche/combinaison et lisent les conditions du spot. Le chemin v2, avec scope sizing et/ou forecast — ils ne touchent jamais aux réservations.
Ils amènent des clients et touchent une commission via /aff + un cookie de 90 jours. Sans clé, sans intégration technique.
Les clés de plateforme portent des scopes. Une clé sizing n'ouvre que les endpoints de sizing — tout le reste renvoie 403 insufficient_scope.
Tout en REST + JSON, authentifié par la clé de l’école.
Les vrais cours avec jour, heure, spot, niveau, places et prix. Filtre par date et niveau. Formats sb · fh · bl · octo.
Les types de cours de l'école (niveau, groupe/privé, fourchette de prix) — en natif SB ou comme products OCTO.
Crée, consulte et annule des réservations au nom du client final. Idempotent par externalRef, avec revalidation des places et des ratios.
Le descripteur est public. Colle-le dans le terminal :
# voir l’API (sans clé) curl -s https://www.surfbooking.eu/api/partner/v1
Contrat complet, lisible par machine — pensé pour que les agents d'IA et les générateurs de SDK découvrent l'API tout seuls : /openapi.json (OpenAPI 3.1) · référence interactive sur /docs (Swagger UI).
Réservation en 2 étapes avec 2 appels — bloque la place pendant que ton client paie, puis confirme :
# 1 — hold (expira sozinho; a vaga fica segura)
curl -X POST https://www.surfbooking.eu/api/partner/v1/bookings -H "X-Partner-API-Key: A_TUA_CHAVE" -H "Content-Type: application/json" -d '{"lessonSlotId":"…","customerName":"…","customerEmail":"…",
"status":"ON_HOLD","expirationMinutes":30}'
# 2 — confirm (idempotente; hold expirado devolve 410 e liberta a vaga)
curl -X POST https://www.surfbooking.eu/api/partner/v1/bookings/{id}/confirm -H "X-Partner-API-Key: A_TUA_CHAVE"
Avec la clé de l’école, tu lis la disponibilité — ici au format OCTO :
curl -s "https://www.surfbooking.eu/api/partner/v1/availabilities?format=octo&from=2026-07-01&to=2026-07-07" \
-H "Authorization: Bearer sbpk_xxxxxxxxxxxxxxxxxxxxxxxx"Limite : 120 requêtes/min par clé. Chaque réponse porte X-RateLimit-Limit et X-RateLimit-Remaining ; en cas de dépassement tu reçois 429 avec Retry-After: 60.
En plus de l’API partenaires, chaque école peut connecter un assistant MCP à sa propre activité. Il est désactivé par défaut et n’a pas encore été validé avec un vrai client.
JSON-RPC 2.0, protocole MCP 2024-11-05. En-tête Authorization: Bearer sbek_…. L’école vient toujours de la clé, jamais des arguments.
Génère la clé avec la session du propriétaire. Corps : label, role, staffId?, scopes (read, ou read et propose), expiresInDays (30, 90 ou 365). La clé n’est renvoyée qu’une fois.
Révoque la clé et fait expirer les propositions en attente qu’elle a demandées.
Propriétaire uniquement. Envoie le payloadHash qu’il a vu ; le changement passe par le même chemin que le tableau de bord, et un cours modifié entre-temps finit en conflit.
Outils : list_my_schools · get_school_schedule · get_bookings_summary · get_lesson_roster · get_stock_summary · get_conditions_for_my_lessons · prepare_lesson_move · prepare_stock_change · list_pending_proposals
Limites : 60 appels par minute par clé et 2000 par jour. Aucun outil d’argent, et rien ne s’applique sans la confirmation du propriétaire. Le détail est sur la page MCP. /mcp
Chaque école génère sa propre clé dans SurfBooking OS — et la révoque quand elle veut. La clé passe dans un en-tête, dans l'un des deux formats :
X-Partner-API-Key: sbpk_xxxx… — le format canonique de SurfBooking.
Authorization: Bearer sbpk_xxxx… — pour les clients qui parlent OCTO. La même clé.
Génère et révoque des clés dans SurfBooking OS → Canaux Externes → API Partenaires. Nous ne stockons jamais la clé en clair — seulement son empreinte.
Base : https://www.surfbooking.eu/api/partner/v1
Descripteur de l'API (racine, sans clé). Renvoie name, version, auth, octo et la carte complète des endpoints. L'ouvrir dans le navigateur redirige vers cette page.
Cours réservables. Paramètres : from, to, level?, format? (sb·fh·bl·octo). Par défaut : from=aujourd'hui, to=+30 jours.
Alias OCTO de /availabilities — suppose format=octo par défaut (plug-and-play OCTO).
Types de cours de l'école. format? (sb·octo) — en OCTO il renvoie products.
Alias OCTO de /services — suppose format=octo par défaut. Tableau de products OCTO.
Identité du fournisseur (descripteur OCTO supplier) : id, name, endpoint, contact, locales, timeZone.
Crée une réservation. Corps : lessonSlotId, customerName, customerEmail, customerPhone?, participants?, externalRef?, notes?.
Consulte l’état d’une réservation.
Annule une réservation.
Le descripteur — GET /api/partner/v1 (sans clé) :
{
"name": "SurfBooking Partner API v1",
"version": "1.0.0",
"auth": "X-Partner-API-Key header, ou Authorization: Bearer (compatível OCTO).",
"octo": {
"supported": true,
"formatParam": "octo",
"supplierEndpoint": "/api/partner/v1/supplier"
},
"endpoints": {
"availabilities": { "method": "GET", "path": "/api/partner/v1/availabilities" },
"services": { "method": "GET", "path": "/api/partner/v1/services" },
"supplier": { "method": "GET", "path": "/api/partner/v1/supplier" },
"createBooking": { "method": "POST", "path": "/api/partner/v1/bookings" },
"getBooking": { "method": "GET", "path": "/api/partner/v1/bookings/:id" },
"cancelBooking": { "method": "DELETE", "path": "/api/partner/v1/bookings/:id" }
}
} Identité du fournisseur — GET /supplier (OCTO) :
{
"id": "school-uuid-…",
"name": "Nome da Escola",
"endpoint": "https://www.surfbooking.eu/api/partner/v1",
"contact": { "website": "https://www.surfbooking.eu", "email": null, "telephone": null, "address": null },
"locales": ["pt", "en"],
"timeZone": "Europe/Lisbon",
"_sb": { "description": "…", "logoUrl": "…" }
}Le corps d’une réservation et ce que tu reçois en retour — exactement comme l’API répond aujourd’hui.
Créer une réservation — POST /bookings :
curl -s -X POST https://www.surfbooking.eu/api/partner/v1/bookings \
-H "Authorization: Bearer sbpk_xxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"lessonSlotId": "a1b2c3d4-…",
"customerName": "Ana Silva",
"customerEmail": "[email protected]",
"customerPhone": "+351912345678",
"participants": 2,
"externalRef": "BOKUN-7782",
"notes": "Primeira aula"
}'Réponse — 201 Created :
{
"ok": true,
"bookingId": "f1e2d3c4-…",
"createdAt": "2026-06-21T11:42:00.000Z",
"lessonSlotId": "a1b2c3d4-…",
"schoolId": "…",
"status": "confirmed",
"participants": 2,
"totalAmountCents": 7000,
"currency": "EUR"
}Disponibilité en OCTO — GET /availabilities?format=octo renvoie un tableau :
[
{
"id": "a1b2c3d4-…",
"localDateTimeStart": "2026-07-02T10:00:00",
"localDateTimeEnd": "2026-07-02T12:00:00",
"available": true,
"status": "AVAILABLE",
"vacancies": 4,
"capacity": 6,
"maxUnits": 4,
"pricing": {
"original": 3500, "retail": 3500, "net": 3500,
"currency": "EUR", "currencyPrecision": 2
},
"_sb": { "level": "beginner", "spotName": "…", "bookingUrl": "https://www.surfbooking.eu/aula/…" }
}
]Prix en centimes (minor units) — 3500 = 35,00 €, selon le currencyPrecision: 2 d'OCTO. Les dates arrivent en heure locale de l'école (Europe/Lisbon).
La même disponibilité dans d'autres formats. Natif SB — ?format=sb (envelope avec _meta) :
{
"availabilities": [
{
"id": "a1b2c3d4-…",
"date": "2026-07-02",
"startTime": "10:00",
"endTime": "12:00",
"level": "beginner",
"spotsTotal": 6,
"spotsRemaining": 4,
"pricePerPerson": 3500,
"currency": "EUR",
"instructorName": "…",
"spotName": "…",
"schoolId": "…",
"schoolName": "…",
"bookingUrl": "https://www.surfbooking.eu/aula/9f3c1a2b7d"
}
],
"_meta": { "format": "sb", "total": 1, "from": "2026-07-01", "to": "2026-07-07" }
}FareHarbor — ?format=fh (envelope availabilities) :
{
"availabilities": [
{
"pk": "a1b2c3d4-…",
"start_at": "2026-07-02T10:00:00",
"end_at": "2026-07-02T12:00:00",
"capacity": 6,
"num_remaining": 4,
"is_available": true,
"customer_type_rates": [
{ "pk": "a1b2c3d4-…_default", "total": { "amount": "35.00", "currency": "EUR" } }
],
"_sb_meta": { "level": "beginner", "bookingUrl": "https://www.surfbooking.eu/aula/9f3c1a2b7d" }
}
]
}Booking Layer — ?format=bl (envelope data) :
{
"data": [
{
"id": "a1b2c3d4-…",
"date": "2026-07-02",
"startTime": "10:00",
"endTime": "12:00",
"serviceName": "Surf beginner",
"capacity": 6,
"spotsLeft": 4,
"pricePerPerson": 3500,
"currency": "EUR",
"_sb_meta": { "level": "beginner", "bookingUrl": "https://www.surfbooking.eu/aula/9f3c1a2b7d" }
}
]
}En octo la réponse est un tableau simple (sans envelope). En sb/fh elle arrive dans availabilities ; en bl, dans data.
Chaque erreur porte un corps JSON { "error": "…" } — lisible par machine.
Clé absente, trop courte, invalide ou révoquée. Inclut un hint quand l'en-tête manque.
Corps incomplet, email mal formé, ou intervalle de dates invalide (max 180 jours, from ≤ to).
Le cours ou la réservation n'existe pas dans cette école — ou, sur le DELETE, elle avait déjà été annulée.
Conflit d'état : plus de places, cours dans le passé, fermé à la vente, ratio d'instructeur dépassé, ou externalRef répété (idempotence — renvoie le bookingId qui existe déjà).
La clé est valide mais n'atteint pas cette ressource : la réservation ou le cours appartient à une autre école. Une clé ne voit que ce qui appartient à l'école qui l'a créée.
La réservation attendait confirmation et la fenêtre est passée. Ce n'est pas une erreur de ton côté : la place est repartie à qui la veut. Recrée-la.
Au-dessus de 120 requêtes/min par clé. Attends le Retry-After (60s). Chaque réponse porte X-RateLimit-Remaining.
Celle-là est de notre faute. Réessaie avec le même externalRef : la création de réservation est idempotente sur cette clé, donc réessayer ne duplique rien.
Clé absente ou invalide — 401 :
# pas d’en-tête de clé { "error": "missing_api_key", "hint": "Set X-Partner-API-Key header (or Authorization: Bearer)" } # clé inexistante ou révoquée { "error": "invalid_api_key" }
Pas assez de places (anti-overbooking) — 409 :
# le cours n’a plus de places pour le nombre de participants { "error": "insufficient_spots", "remaining": 1 } # externalRef répété → idempotence : renvoie le bookingId existant { "error": "external_ref_exists", "bookingId": "f1e2d3c4-…" }
La revalidation des places et des ratios s'exécute dans une transaction avec SELECT … FOR UPDATE — complet c'est complet, il n'y a jamais de double réservation.
Chaque réponse porte X-RateLimit-Limit et X-RateLimit-Remaining. Au-delà, un 429 avec Retry-After: 60. Pas besoin de deviner : les nombres voyagent dans chaque réponse.
L'intervalle from–to borne la réponse ; au-delà de 180 jours, ça renvoie 400. Il n'y a pas de pagination par curseur, volontairement : un cours a une date, et demander par dates est la pagination naturelle de ce domaine. Si tu en veux plus, ça fait deux requêtes.
Révoque celles que tu n'utilises pas avant d'en créer de nouvelles. Une clé révoquée cesse de fonctionner dès la requête suivante, sans délai.
Ces trois nombres sont lus dans le code qui sert l'API, pas écrits ici à la main : s'ils changent là-bas, cette page devient fausse et un test le dit.
Le chemin v2 pour les marques de matériel, les apps et l'IA. Clé de plateforme avec scope sizing, forecast et/ou brand:read — déterministe, sans données personnelles, ne touche jamais aux réservations. Découvre tes scopes sur /api/partner/v2/meta. Base : https://www.surfbooking.eu/api/partner/v2.
Planche recommandée par level + weight. Scope sizing.
Planche ajustée au jour : level, weight, swellPeriodS, swellDirectionDeg, bestSwellDirDeg. Scope sizing.
Taille de combinaison par weight + height. Scope sizing.
Leash par boardSize + category (board·soft_board). Scope sizing.
Chaussons par shoeSizeEu (ex. : 42). Scope sizing.
Liste les spots que tu peux interroger — utilise un id d'ici dans /conditions/:spotId. Scope forecast.
Conditions du spot — la même shape publique, assainie (n'expose jamais le modèle ni les sources). Scope forecast.
Les meilleurs spots du pays en ce moment, classés par le score en direct — limit + level. Scope forecast.
Pour les marques de matériel : combien de fois chaque taille de ta marque a été utilisée en cours, par month (YYYY-MM). Uniquement tes données. Scope brand:read.
Sur quels spots le matériel de ta marque a été le plus utilisé, derniers months (1–12). Scope brand:read.
Recommandation de planche — GET /sizing/board :
curl -s "https://www.surfbooking.eu/api/partner/v2/sizing/board?level=beginner&weight=75" \
-H "X-Partner-API-Key: sbpd_xxxxxxxxxxxxxxxxxxxxxxxx"{ "recommendation": { "category": "soft_board", "size": "8'0" } }Les clés de plateforme (sbpd_…) sont émises par SurfBooking, pas par l'école. Mauvais scope → 403 insufficient_scope. Limite 240 requêtes/min par clé, avec Retry-After: 60 en cas de dépassement.
Une page iframe autonome, "Powered by SurfBooking". Elle montre les conditions du spot, recommande la planche selon le poids et le niveau, et emmène le client réserver un cours — avec ton lien de partenaire premium intégré. Sans PII, sans cookies de suivi.
<iframe
src="https://www.surfbooking.eu/w/surf?key=sbpd_xxxx&spot=SPOT_ID&slug=O_TEU_SLUG"
width="360" height="520" frameborder="0"></iframe>key = ta clé de plateforme (scope sizing, et forecast si tu veux les conditions en haut). spot et slug sont optionnels — le slug relie les réservations générées à ton /aff (cookie de 90 jours).
La base est /api/partner/v1. Les changements qui cassent la compatibilité passent dans une nouvelle version (/v2) — la v1 n'a pas de dépréciation prévue. Nous pouvons ajouter des champs sans préavis, alors lis de façon tolérante : ignore ce que tu ne connais pas encore.
Tout partenaire qui veut vendre ou montrer de vrais cours de surf. Conçu sur le standard ouvert OCTO, que beaucoup de systèmes de réservation et channel managers parlent déjà.
Propose de vrais cours à tes clients sans rien gérer — la réservation et le paiement restent sur SurfBooking.
Synchronise la disponibilité en temps réel, sans double réservation. OCTO d’origine.
Liste l’offre des écoles et achemine la réservation — avec les places et les ratios toujours revalidés de notre côté.
Chaque clé ne voit que l’offre de sa propre école. Révoque-la en un clic et l’accès meurt sur-le-champ.
Chaque réservation revalide les places et les ratios de moniteur dans une transaction. Complet, c’est complet.
Le flux d’argent reste de notre côté — le partenaire achemine, SurfBooking confirme.
Seul le nécessaire à la réservation sort. Les contacts de tes élèves ne finissent sur la liste de personne.
L’API est vivante. Si tu as une école de surf, tu génères ta propre clé dans le SurfBooking OS. Si tu es partenaire externe — marque de matériel, app, IA ou hôtel — tu demandes une clé de plateforme (émise par SurfBooking).
Je suis une école · Ouvrir le SurfBooking OS Je suis partenaire externe · Demander l’accès Voir le descripteur