Surf Booking.PTAPI
ManifesteAgentCouche IntelligenteTechnologieConstitutionIAMCPPartner API
API partenaires

Une intégration.Mille canaux.

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
surfbooking.eu/developers
/api/partner/v1/availabilities
GET
{
  "spot":     "Carcavelos",
  "date":     "2026-06-22",
  "time":     "10:00",
  "level":    "iniciante",
  "capacity": 6,
  "vacancy":  4
}
Plateforme ouverte

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.

Qui se connecte

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.

Hôtels

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.

Agences de voyage

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.

DMCs

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.

Apps de tourisme

Listings + disponibilité en direct

Ils montrent écoles, spots et disponibilité en direct. Le scope forecast ajoute les conditions par spot.

Hébergement

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

En 5 secondes, n’importe quel CTO comprend.

Ta plateforme
Hôtel · OTA · Agence · App
SurfBooking API
REST · JSON · OCTO
Écoles
Disponibilité
Paiements
Réservations

Une intégration. Toutes les écoles de la plateforme. Places réelles, prix réels, anti-overbooking — confirmé en millisecondes.

Partenaires différents, accès différents

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.

Hôtels · OTA · channel managers

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.

Marques de matériel · apps · IA

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.

Partenaires

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.

Ce que fait l’API

Trois choses. Disponibilité, services, réservations.

Tout en REST + JSON, authentifié par la clé de l’école.

availabilities

Lire la disponibilité

Les vrais cours avec jour, heure, spot, niveau, places et prix. Filtre par date et niveau. Formats sb · fh · bl · octo.

services

Lister les services

Les types de cours de l'école (niveau, groupe/privé, fourchette de prix) — en natif SB ou comme products OCTO.

bookings

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.

En cours

Un appel et tu vois l’API répondre.

Le descripteur est public. Colle-le dans le terminal :

terminal · descripteur de l’API
# 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).

OCTO
Pour les OTA et revendeurs
Produits, disponibilité et réservation en 2 étapes (hold → confirm). Plug-and-play façon Bókun/Rezdy.
iCal
Universel, dans les deux sens
Importe le flux de n’importe quel canal dans le calendrier SB — et exporte le calendrier SB (avec les annulations) vers le canal.
MCP
Pour les agents IA
11 outils — chercher des cours, score de surf en direct par spot, tailles de matériel — via Model Context Protocol.

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 :

terminal · disponibilité (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.

Connecteur privé d’école

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.

POST

/api/mcp/escola

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.

POST

/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.

DELETE

/api/schools/:id/conector/tokens/:tokenId

Révoque la clé et fait expirer les propositions en attente qu’elle a demandées.

POST

/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_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

Authentification

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 :

X-Partner-API-Key

En-tête natif SB

X-Partner-API-Key: sbpk_xxxx… — le format canonique de SurfBooking.

Authorization: Bearer

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 Externes → API Partenaires. Nous ne stockons jamais la clé en clair — seulement son empreinte.

Référence

Les endpoints.

Base : https://www.surfbooking.eu/api/partner/v1

GET

/

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.

GET

/availabilities

Cours réservables. Paramètres : from, to, level?, format? (sb·fh·bl·octo). Par défaut : from=aujourd'hui, to=+30 jours.

GET

/availability

Alias OCTO de /availabilities — suppose format=octo par défaut (plug-and-play OCTO).

GET

/services

Types de cours de l'école. format? (sb·octo) — en OCTO il renvoie products.

GET

/products

Alias OCTO de /services — suppose format=octo par défaut. Tableau de products OCTO.

GET

/supplier

Identité du fournisseur (descripteur OCTO supplier) : id, name, endpoint, contact, locales, timeZone.

POST

/bookings

Crée une réservation. Corps : lessonSlotId, customerName, customerEmail, customerPhone?, participants?, externalRef?, notes?.

GET

/bookings/:id

Consulte l’état d’une réservation.

DELETE

/bookings/:id

Annule une réservation.

Le descripteur — GET /api/partner/v1 (sans clé) :

réponse · descripteur
{
  "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) :

réponse · 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": "…" }
}
Exemples

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 :

requête · 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 :

réponse · 201
{
  "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 :

réponse · availabilities (OCTO)
[
  {
    "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) :

réponse · availabilities (SB)
{
  "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) :

réponse · availabilities (FH)
{
  "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) :

réponse · availabilities (BL)
{
  "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.

Erreurs

Codes d’état.

Chaque erreur porte un corps JSON { "error": "…" } — lisible par machine.

401

missing_api_key · invalid_api_key

Clé absente, trop courte, invalide ou révoquée. Inclut un hint quand l'en-tête manque.

400

missing_fields · invalid_email · invalid_date_range

Corps incomplet, email mal formé, ou intervalle de dates invalide (max 180 jours, from ≤ to).

404

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.

409

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à).

403

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.

410

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.

429

rate_limit_exceeded

Au-dessus de 120 requêtes/min par clé. Attends le Retry-After (60s). Chaque réponse porte X-RateLimit-Remaining.

500

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 :

réponse · 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 :

réponse · 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.

Limites

Ce que tu peux demander, et combien.

120 / min

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.

180 jours

C'est la page, et il n'y a pas de curseur

L'intervalle fromto 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.

50

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.

Tailles + conditions · v2

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.

GET

/sizing/board

Planche recommandée par level + weight. Scope sizing.

GET

/sizing/board/conditions

Planche ajustée au jour : level, weight, swellPeriodS, swellDirectionDeg, bestSwellDirDeg. Scope sizing.

GET

/sizing/wetsuit

Taille de combinaison par weight + height. Scope sizing.

GET

/sizing/leash

Leash par boardSize + category (board·soft_board). Scope sizing.

GET

/sizing/boots

Chaussons par shoeSizeEu (ex. : 42). Scope sizing.

GET

/spots

Liste les spots que tu peux interroger — utilise un id d'ici dans /conditions/:spotId. Scope forecast.

GET

/conditions/:spotId

Conditions du spot — la même shape publique, assainie (n'expose jamais le modèle ni les sources). Scope forecast.

GET

/intelligence/surf-now

Les meilleurs spots du pays en ce moment, classés par le score en direct — limit + level. Scope forecast.

GET

/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.

GET

/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 :

terminal · sizing (v2)
curl -s "https://www.surfbooking.eu/api/partner/v2/sizing/board?level=beginner&weight=75" \
  -H "X-Partner-API-Key: sbpd_xxxxxxxxxxxxxxxxxxxxxxxx"
réponse · sizing
{ "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.

Widget intégrable

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.

Exemple en direct — c’est exactement ce que voient tes visiteurs :
html · embed
<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).

Versions

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.

Pour qui

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é.

Ta sécurité

C’est l’école qui décide. Toujours.

CLÉ

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.

PLACES

Jamais d’overbooking

Chaque réservation revalide les places et les ratios de moniteur dans une transaction. Complet, c’est complet.

PAIEMENT

Confirmé sur SurfBooking

Le flux d’argent reste de notre côté — le partenaire achemine, SurfBooking confirme.

ÉLÈVES

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.

Prêt à connecter

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