API partenaires
De vrais cours de surf,en un appel API.
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.
API en direct · Bearer / X-Partner-API-Key
{
"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.
Cinq types de partenaire. Une API.
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.
Expérience au check-in
Ils proposent des cours de surf en extra au client, avec réservation en temps réel — sans appels, sans coordination manuelle.
Forfaits surf
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.
Le surf dans l’itinéraire
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.
Listings + disponibilité en direct
Ils montrent écoles, spots et disponibilité en direct. Le scope forecast ajoute les conditions par spot.
Upsell d’expériences
Locations courte durée et appartements font de l'upsell de surf au moment du paiement — confirmé en quelques secondes via l'API.
Comment ça marche.
Une intégration. Toutes les écoles de la plateforme. Places réelles, prix réels, anti-overbooking — confirmé en millisecondes.
Chaque partenaire se connecte seulement à ce qui lui sert.
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.
Disponibilité + réservations
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.
Tailles + conditions
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.
Attribution, sans API
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.
Trois choses. Disponibilité, services, réservations.
Tout en REST + JSON, authentifié par la clé de l’école.
Lire la disponibilité
Les vrais cours avec jour, heure, spot, niveau, places et prix. Filtre par date et niveau. Formats sb · fh · bl · octo.
Lister les services
Les types de cours de l'école (niveau, groupe/privé, fourchette de prix) — en natif SB ou comme products OCTO.
Créer et gérer des réservations
Crée, consulte et annule des réservations au nom du client final. Idempotent par externalRef, avec revalidation des places et des ratios.
Un appel et tu vois l’API répondre.
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.
Un assistant dans ton école, avec une clé rien qu’à toi.
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.
/api/mcp/escola
JSON-RPC 2.0, protocole MCP 2025-06-18. En-tête Authorization: Bearer sbek_…. L’école vient toujours de la clé, jamais des arguments.
/api/schools/:id/conector/tokens
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.
/api/schools/:id/conector/tokens/:tokenId
Révoque la clé et fait expirer les propositions en attente qu’elle a demandées.
/api/schools/:id/conector/propostas/:pid/confirmar
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_briefing · get_school_schedule · get_bookings_summary · get_lesson_roster · get_stock_summary · get_conditions_for_my_lessons · review_week_with_sea · 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
Une clé par école. C’est toi qui contrôles.
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 :
En-tête natif SB
X-Partner-API-Key: sbpk_xxxx… — le format canonique de SurfBooking.
Compatible OCTO
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 de vente → API Partenaires. Nous ne stockons jamais la clé en clair — seulement son empreinte.
Les endpoints.
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.
/availabilities
Cours réservables. Paramètres : from, to, level?, format? (sb·fh·bl·octo). Par défaut : from=aujourd'hui, to=+30 jours.
/availability
Alias OCTO de /availabilities — suppose format=octo par défaut (plug-and-play OCTO).
/services
Types de cours de l'école. format? (sb·octo) — en OCTO il renvoie products.
/products
Alias OCTO de /services — suppose format=octo par défaut. Tableau de products OCTO.
/supplier
Identité du fournisseur (descripteur OCTO supplier) : id, name, endpoint, contact, locales, timeZone.
/bookings
Crée une réservation. Corps : lessonSlotId, customerName, customerEmail, customerPhone?, participants?, externalRef?, notes?.
/bookings/:id
Consulte l’état d’une réservation.
/bookings/:id
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": "…" }
}Requête et réponse, pour de vrai.
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": "EXT-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" }
}Un autre système de réservation — ?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" }
}
]
}Un autre système de réservation — ?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.
Codes d’état.
Chaque erreur porte un corps JSON { "error": "…" } — lisible par machine.
missing_api_key · invalid_api_key
Clé absente, trop courte, invalide ou révoquée. Inclut un hint quand l'en-tête manque.
missing_fields · invalid_email · invalid_date_range
Corps incomplet, email mal formé, ou intervalle de dates invalide (max 180 jours, from ≤ to).
slot_not_found · booking_not_found · booking_not_found_or_already_cancelled
Le cours ou la réservation n'existe pas dans cette école — ou, sur le DELETE, elle avait déjà été annulée.
insufficient_spots · slot_expired · slot_not_purchasable · ratio_exceeded · external_ref_exists
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à).
forbidden · not_owner
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.
hold_expired
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.
rate_limit_exceeded
Au-dessus de 120 requêtes/min par clé. Attends le Retry-After (60s). Chaque réponse porte X-RateLimit-Remaining.
internal_error
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.
Ce que tu peux demander, et combien.
Par clé, pas par partenaire
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.
C'est la page, et il n'y a pas de curseur
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.
Clés actives par école
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.
Recommande le bon matériel. Sans toucher aux réservations.
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.
/sizing/board
Planche recommandée par level + weight. Scope sizing.
/sizing/board/conditions
Planche ajustée au jour : level, weight, swellPeriodS, swellDirectionDeg, bestSwellDirDeg. Scope sizing.
/sizing/wetsuit
Taille de combinaison par weight + height. Scope sizing.
/sizing/leash
Leash par boardSize + category (board·soft_board). Scope sizing.
/sizing/boots
Chaussons par shoeSizeEu (ex. : 42). Scope sizing.
/spots
Liste les spots que tu peux interroger — utilise un id d'ici dans /conditions/:spotId. Scope forecast.
/conditions/:spotId
Conditions du spot — la même shape publique, assainie (n'expose jamais le modèle ni les sources). Scope forecast.
/intelligence/surf-now
Les meilleurs spots du pays en ce moment, classés par le score en direct — limit + level. Scope forecast.
/brand/equipment-stats
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.
/brand/spot-activity
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.
Les tailles sur ton site. Une ligne.
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).
v1 — stable.
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.
Channel managers, marketplaces, hôtels.
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à.
Hôtels & resorts
Propose de vrais cours à tes clients sans rien gérer — la réservation et le paiement restent sur SurfBooking.
Channel managers
Synchronise la disponibilité en temps réel, sans double réservation. OCTO d’origine.
Marketplaces
Liste l’offre des écoles et achemine la réservation — avec les places et les ratios toujours revalidés de notre côté.
C’est l’école qui décide. Toujours.
Par école, révocable
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.
Jamais d’overbooking
Chaque réservation revalide les places et les ratios de moniteur dans une transaction. Complet, c’est complet.
Confirmé sur SurfBooking
Le flux d’argent reste de notre côté — le partenaire achemine, SurfBooking confirme.
Données protégées
Seul le nécessaire à la réservation sort. Les contacts de tes élèves ne finissent sur la liste de personne.
Prends une clé et commence.
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

