Télécharger le guide PDF SBY · Contrat OpenAPI JSON

Jicky Marine — FileMaker / Warren API v1

Documentation technique du 18 octobre 2026, mise à jour après activation des droits HOLD Jicky. Contact : Sébastien Loret, sebastien.loret@hertzstbarth.com.

Environnements et authentification

Sandbox : https://sandbox.stbarth-yachting.com

Production : https://stbarth-yachting.com

Version du contrat : 1.0 ; préfixe des routes /api/v1. Certaines actions réutilisent /api/reservations.

Documentation : /integration-api.html ; contrat OpenAPI : /integration-openapi.json sur chaque environnement.

Guide PDF aux couleurs SBY : /integration-api.pdf. Aucune clé ni aucun secret n’est inclus dans les documents.

En-tête X-API-Key: <clé>. Authorization: Bearer <clé> est également accepté. Toujours HTTPS.

Clés distinctes : sby_test_… pour la sandbox, sby_live_… pour la production. Aucune clé ne fonctionne dans l’autre environnement.

Profil partner_booking identique : seulement catalogue, disponibilités, devis, création et gestion des propres réservations. Aucun accès aux autres partenaires, clients, rapports, paiements ou administration.

Clés conservées côté serveur FileMaker, jamais dans une URL ni dans un fichier partagé. Remise séparée par canal sécurisé ; aucune clé dans cette documentation ou dans l’e-mail de réponse.

Les deux clés Jicky sont actives sans expiration automatique ; révocation et remplacement dans l’administration. Pas de renouvellement silencieux ni de restriction IP configurée. Prévoir une période de chevauchement lors d’une rotation explicite.

La sandbox a sa propre base et ses propres identités fictives. Elle ne copie ni réservations, ni clients, ni comptes, ni clés de production. Le catalogue, les tarifs et les règles métier sont initialisés depuis la production à la création ; aucune synchronisation automatique ultérieure.

Aucun paiement réel, e-mail client, push ou écriture iCloud en sandbox. Les options HOLD y suivent le même délai d’expiration qu’en production.

Données opérationnelles

externalReference : identifiant FileMaker stable, chaîne de 1 à 100 caractères. Utiliser systématiquement ce champ et un Idempotency-Key stable par création logique.

yachtId : entier positif issu du catalogue. Les identifiants disponibles sont 1 (Lagoon 55), 2 (Pardo 43), 3 (Contender 39). La correspondance avec les noms LOLA 3 et SEARENITY doit être confirmée avant la production ; ne pas déduire un identifiant depuis le nom.

serviceId : entier positif de /api/v1/catalog. Il choisit le bateau et le créneau / type de sortie. Toujours vérifier service.yachtId et service.timeSlot. Ne pas confondre serviceId et timeSlotId.

bookingDate : YYYY-MM-DD, date locale du charter, future. Fuseau America/Guadeloupe (UTC−4, sans heure d’été). Les heures retournées sont locales, au format HH:mm:ss ; aucun horaire libre à envoyer.

numGuests : entier positif ; respecter minGuests / maxGuests du service.

specialRequests : instructions opérationnelles pour l’équipage, facultatives, 2 000 caractères maximum. Éviter tout nom, téléphone, e-mail ou information sensible dans ce texte.

customer : facultatif pour Jicky, avec firstName, lastName, email, phone, country tous facultatifs. L’administrateur peut imposer séparément ces champs par partenaire dans « API & webhooks ». Les valeurs fournies restent contrôlées : noms 100 caractères, e-mail 255 et syntaxe valide, téléphone 50, pays 100. L’absence d’identité crée une fiche technique interne, sans réutiliser l’identité d’un autre canal.

extras : tableau facultatif de {extraId, quantity} ; pas d’extra réservé à l’administration. sendToCustomer vaut false par défaut.

id et referenceCode : identifiants Warren retournés à la création, à conserver avec externalReference.

Les montants retournés restent ceux de Warren, calculés selon le catalogue. Aucun champ de montant payé FileMaker n’est accepté comme preuve de paiement.

Parcours et endpoints

Tous les appels utilisent X-API-Key. Les écritures utilisent Content-Type: application/json.

GET /api/v1/catalog?lang=fr : bateaux, services, créneaux, tarifs, extras et politique effective du partenaire.

GET /api/v1/availability?date=2027-06-14&yachtId=2 : disponibilité. Une lecture n’est pas une garantie ; la création réserve le créneau de manière atomique.

POST /api/v1/quote : {"serviceId":4,"bookingDate":"2027-06-14","numGuests":4,"extras":[]} ; prendre le serviceId réel dans le catalogue.

POST /api/v1/bookings : ajouter Idempotency-Key. Exemple : {"externalReference":"FM-2027-001","yachtId":2,"serviceId":4,"bookingDate":"2027-06-14","numGuests":4,"specialRequests":"Préparer le matériel de snorkeling"}. Aucun nom, prénom, e-mail ou téléphone requis pour Jicky.

Succès création HTTP 201 : {"version":"1.0","replayed":false,"booking":{"id":1234,"referenceCode":"R-26-1234","externalReference":"FM-2027-001","status":"pending","paymentStatus":"pending","paymentMode":"account","paymentUrl":null,"paymentExpiresAt":null,"totalAmount":2800,"commissionAmount":280,"currency":"EUR"}}. Exemple indicatif ; les identifiants et montants dépendent de l’environnement.

GET /api/v1/bookings/FM-2027-001 ou GET /api/v1/bookings/R-26-1234 : dossier propre au partenaire, dont date, bateau, service, créneau, passagers, demandes, statut, paiement, updatedAt et montants. L’identifiant numérique id sert aux actions ci-dessous, pas à cette route de recherche.

PUT /api/reservations/1234/partner-edit : {"numGuests":5,"specialRequests":"Instruction modifiée"}. Le même endpoint accepte bookingDate, yachtId, serviceId pour déplacer la réservation, avec recalcul du tarif et contrôle atomique des conflits. Les changements d’horaire / type passent par serviceId, pas par des heures arbitraires. Succès HTTP 200.

Les modifications restent refusées pour les dossiers annulés, terminés, payés ou facturés et hors fenêtre partenaire. Un déplacement avec remise, incentive ou extra sur mesure exige une intervention admin. Le nouveau créneau doit également être dans la fenêtre autorisée. Une erreur 409 de conflit conserve la réservation d’origine.

Le réglage « Autoriser la modification et l’annulation sans frais des options API HOLD non confirmées » est ACTIVÉ pour Jicky Marine en production et en sandbox, sur décision de Sébastien. Il concerne uniquement les réservations créées par l’API (source api_v1), en compte, au statut pending / HOLD, futures, non payées, non facturées et non expirées. Ces options peuvent être modifiées ou annulées sans frais. La modification ne remet pas à zéro le délai initial de 48 h.

Après confirmation, la dérogation HOLD cesse de s’appliquer. En Confirmed, l’API ne permet une modification ou annulation en libre-service que dans une fenêtre sans frais ; la politique standard actuelle prévoit 5 % + 95 € même à plus de 7 jours, donc une intervention SBY est nécessaire. Les modifications restent également bloquées après paiement ou facturation.

PUT /api/reservations/1234/partner-notes : {"notes":"Note privée du partenaire"}. Cette note privée ne remplace pas specialRequests et n’est pas envoyée dans les webhooks.

POST /api/reservations/1234/confirm : {} ; confirme une option en compte pending. Succès HTTP 200, status confirmed. Ne crée aucun paiement ni débit.

GET /api/reservations/1234/cancellation-estimate : montant des frais et conditions applicables au dossier.

GET /api/v1/cancellation-policy?bookingDate=2027-06-14&totalAmount=2800 : simulation générale.

POST /api/reservations/1234/cancel : {"reason":"Annulation FileMaker"}. Succès HTTP 200 seulement dans les conditions autorisées ; consulter l’estimation. Une annulation est terminale ; confirmer de nouveau renvoie 409. Un nouveau dossier nécessite une nouvelle référence FileMaker et une nouvelle clé d’idempotence.

La route /api/v1/bookings/{reference}/cancel n’est pas autorisée par ce profil : utiliser l’action numérique ci-dessus.

Statuts FileMaker et reprises

HOLD FileMaker = pending Warren : création en option, durée 48 h selon le paramètre partner_account_hold_hours actuellement à 48. Confirmer avant expiration ; à défaut, annulation automatique. Le catalogue expose les règles de paiement ; ne pas assimiler paymentTimeoutExempt du compte à une exemption automatique des options.

PAID FileMaker : pour le partenaire en compte, appeler confirm pour garantir le charter. Warren passe à confirmed et peut conserver paymentStatus pending jusqu’au rapprochement comptable. PAID FileMaker ne vaut pas paiement enregistré chez Warren. Ce choix de correspondance doit être validé entre les équipes avant la production.

CANCELLED FileMaker = cancelled Warren, sous réserve de l’acceptation des conditions d’annulation. En cas de refus API, ne pas forcer le statut local comme synchronisé ; demander une intervention St Barth Yachting.

Statuts techniques Warren : completed (sortie terminée), no_show, deposit_paid / paid le cas échéant. Ne pas réactiver automatiquement une réservation terminale.

Même Idempotency-Key et même JSON : réponse de création mémorisée, replayed true, même id, sans doublon. Même clé avec JSON différent : 409. Conserver la clé tant que le résultat est incertain, y compris après une coupure réseau.

Même externalReference avec une nouvelle clé : HTTP 200, même identifiant et status already_exists ; cela ne modifie pas le dossier. Relire ensuite le dossier et utiliser partner-edit. L’unicité est limitée au partenaire.

Les actions confirm/cancel ne sont pas idempotentes au sens de la réponse HTTP : après timeout, relire le statut avant toute reprise. Une deuxième confirmation/annulation peut répondre 409 sans nécessiter une nouvelle création.

En cas d’appel concurrent/conflictuel, relire et reprendre avec temporisation. Ne jamais générer automatiquement une nouvelle externalReference pour contourner un conflit.

Alertes de modification et d’annulation

Les modifications opérationnelles et annulations enregistrées sont signalées automatiquement à l’équipe SBY et à Sébastien, y compris les actions administratives. Les tentatives partenaire refusées pour des raisons de statut ou de politique sont également signalées ; elles ne changent pas la réservation.

Si des frais sont prévus par la politique, le mail les affiche en grand et en rouge, avec la base de calcul, le pourcentage, les frais fixes et le délai avant départ. Une annulation enregistrée sans les frais attendus est signalée comme anomalie à contrôler.

Les conditions sont calculées sur l’état du dossier avant l’action, à la date locale de Saint-Barthélemy, puis figées pour les reprises d’envoi. L’alerte seule ne débite, ne facture ni ne rembourse automatiquement.

Les HOLD API Jicky éligibles bénéficient désormais de la dérogation sans frais. Les autres statuts gardent leurs conditions habituelles. Les notifications réelles restent neutralisées en sandbox.

Webhooks sortants

Configuration dans le portail partenaire et dans la fiche partenaire admin, bouton « API & webhooks ». Le partenaire peut gérer son URL et ses notifications ; seul l’administrateur choisit les champs client obligatoires.

URL HTTPS publique sur port 443, domaine sans identifiants ni fragment. Résolution IPv4 publique contrôlée et figée pour chaque tentative ; adresses privées / locales et redirections refusées. Une URL FileMaker privée doit être exposée via un point d’entrée HTTPS contrôlé par Jicky.

Événements : booking.created, booking.updated, booking.cancelled. Ils couvrent les transitions validées dans la base, y compris celles réalisées dans l’administration ou par les traitements métier. Pas d’historique rejoué lors de l’activation.

L’URL d’Emmanuel n’étant pas connue, les webhooks Jicky restent désactivés jusqu’à sa configuration. Secret de signature distinct de la clé API, généré lors de l’enregistrement, affiché une seule fois, renouvelable et conservé chiffré côté serveur.

Enveloppe JSON stable : {"version":"1.0","environment":"sandbox","eventId":"uuid","event":"booking.updated","occurredAt":"2026-10-18T18:00:00.000Z","booking":{"id":1234,"externalReference":"FM-2027-001","status":"confirmed"}}. Exemple abrégé ; occurredAt est UTC ISO 8601 et les dates/heures du charter restent locales.

Champs proposés sous booking : id, referenceCode, externalReference, yachtId, yachtName, serviceId, bookingDate, timeSlotId, startTime, endTime, numGuests, status, paymentStatus, specialRequests, totalAmount, currency. Aucun objet customer, coordonnées client, note interne ni donnée bancaire.

Le formulaire permet de renommer chaque champ (ex. externalReference vers filemaker_id), sans ajouter de données non proposées. Noms uniques, 1 à 64 caractères, lettres/chiffres/underscore, commençant par une lettre. L’enveloppe event/eventId/occurredAt reste fixe.

Headers : Content-Type application/json, X-SBY-Event-ID, X-SBY-Signature: t=<unix-secondes>,v1=<hmac-hex>. Vérifier HMAC-SHA256(secret, timestamp + "." + corps_JSON_BRUT) par comparaison à temps constant ; ne jamais re-sérialiser le JSON avant vérification. Tolérance recommandée : ±300 s sur le timestamp.

Répondre HTTP 2xx sous 10 s après stockage durable, puis traiter en arrière-plan. Ne pas renvoyer de redirection. Huit tentatives au maximum, espacées de 30 s, 2 min, 10 min, 30 min, 2 h, 6 h, 12 h ; passage du worker toutes les 15 s. Corps et eventId restent identiques en reprise ; la signature est recalculée avec un timestamp frais.

Livraison au moins une fois, ordre non garanti. Dédupliquer par eventId ; après réception, relire la réservation par sa référence pour appliquer l’état courant et éviter qu’un événement ancien ne remplace un état récent.

L’admin / partenaire voit les 20 dernières livraisons, le statut HTTP, le nombre de tentatives et les échecs. Après 8 échecs, intervention et réconciliation par GET. Le changement ou la désactivation de configuration suspend les anciens événements, sans envoi automatique vers une nouvelle URL.

IP de sortie attendue : 147.93.41.214 ; privilégier la signature comme preuve d’origine. Aucun accès entrant à votre base FileMaker n’est nécessaire.

Erreurs et exploitation

400 : données invalides, champ obligatoire manquant, clé d’idempotence absente. Corriger l’entrée avant reprise.

401 : clé inconnue, révoquée, expirée ou d’un autre environnement.

403 : opération hors profil, autre partenaire, fenêtre de modification / annulation fermée ou fonction indisponible en sandbox.

404 : dossier non accessible ou introuvable dans le contexte du partenaire.

409 : créneau occupé, transition de statut interdite, dossier déjà payé/facturé ou clé d’idempotence réutilisée avec un autre JSON.

429 : plafond général 200 requêtes / minute / IP ; respecter Retry-After et les headers RateLimit. Aucune hausse spécifique en sandbox.

500 / 503 / coupure : relire la réservation et reprendre la création avec exactement la même clé d’idempotence, temporisation exponentielle avec aléa. Timeout client conseillé 30 s. Ne pas relancer en boucle les 4xx.

Erreur API v1 typique : {"error":{"message":"Booking not found"}}. Les actions historiques /api/reservations renvoient plutôt {"error":"…","code":"…"}. Tester les deux formes.

Aucun SLA ou créneau de maintenance contractuel défini. Incident : envoyer au contact technique l’environnement, l’heure UTC, la méthode/route, le code HTTP, externalReference et referenceCode si disponibles ; ne jamais transmettre les secrets ni les données client.

Validation puis passage en production

Tester authentification, catalogue, création fictive sans identité client, lecture par référence FileMaker, changement de passagers / instructions / créneau dans la fenêtre autorisée, confirmation, annulation autorisée et refus hors fenêtre.

Répéter une création avec la même clé, puis avec la même externalReference et une autre clé : aucun doublon. Tester aussi une clé identique avec un corps différent (409), un conflit de créneau et l’isolation des partenaires.

Fournir l’URL de webhook de test, activer les événements souhaités, conserver le secret affiché, vérifier signature, renommage, déduplication et reprise après erreur HTTP.

Confirmer avec Emmanuel les correspondances LOLA 3 / SEARENITY et HOLD / PAID / CANCELLED. Aucun alias de bateau ou enregistrement de paiement n’est inventé.

Activation vérifiée sur les deux catalogues : policies.partner.allowUnconfirmedHoldChanges vaut true pour Jicky. Le parcours de recette doit inclure une modification et annulation de HOLD sans frais, puis une confirmation sur un second dossier et le refus des actions soumises à frais.

Après validation fonctionnelle par les deux équipes : changer uniquement base URL et clé pour la production, configurer séparément le webhook de production, puis contrôler une première réservation réelle autorisée. Les identifiants internes / références de sandbox ne sont pas des dossiers de production et ne sont jamais migrés.