Connectez votre application tierce à SuperHote : lisez et mettez à jour vos hébergements, votre calendrier et vos réservations, créez des réservations directes, échangez avec vos voyageurs, répondez à leurs avis, recevez les événements par webhook. Tout ce qu’il faut pour intégrer l’API en moins d’une heure — et pour brancher votre assistant IA via le serveur MCP.
Sécurité multi-comptes. Chaque token est limité au périmètre de son propriétaire (ses hébergements, ses réservations). Tout accès hors périmètre renvoie 404 — jamais 403, pour ne pas révéler l’existence d’une ressource.
API publique V21 / 22Dans SuperHote : Plateformes → API → Créer un token. Cochez les permissions nécessaires, copiez le token immédiatement — il ne sera plus jamais affiché.
Listez vos hébergements pour vérifier que le token fonctionne :
Si vous recevez 401 → token mal copié. Si 403 → permission manquante (cf. section 2).
API publique V22 / 22Chaque requête doit porter l’en-tête :
Un token possède une ou plusieurs permissions (scopes). Chaque endpoint en exige une précise :
| Scope | Ce qu’il permet | Lecture | Écriture |
|---|---|---|---|
| public-api:rentals.read | Voir les hébergements | ✓ | — |
| public-api:rentals.write | Modifier un hébergement (nom, adresse, capacité, règles de séjour) | — | ✓ |
| public-api:calendar.read | Voir dispo, prix, restrictions | ✓ | — |
| public-api:calendar.write | Modifier dispo, prix, restrictions | — | ✓ |
| public-api:reservations.read | Voir les réservations | ✓ | — |
| public-api:reservations.write | Modifier une réservation (statut, dates, voyageurs, notes internes) | — | ✓ |
| public-api:reservations.create | Créer une réservation directe (bloque les nuits sur toutes vos plateformes) | — | ✓ |
| public-api:messages.read | Lire la conversation d’une réservation | ✓ | — |
| public-api:messages.write | Envoyer un message au voyageur | — | ✓ |
| public-api:reviews.read | Lire les avis voyageurs et les réponses déjà publiées (Airbnb) | ✓ | — |
| public-api:reviews.write | Répondre publiquement à un avis voyageur (Airbnb) | — | ✓ |
| public-api:webhooks.manage | Lister, créer et supprimer vos webhooks sortants | ✓ | ✓ |
| public-api:all | Tout (raccourci wildcard) — non proposé à la création depuis cet écran | ✓ | ✓ |
Lecture et écriture sont deux scopes distincts : un scope .read n’autorise jamais d’écriture. Pour modifier un hébergement, une réservation ou le calendrier, cochez le .write correspondant, et n’accordez à chaque token que le strict nécessaire. Créer une réservation demande public-api:reservations.create, que reservations.write n’inclut pas.
public-api:all est reconnu par le serveur mais ne se coche pas. L’écran de création ne propose que les 12 scopes ci-dessus : sélectionnez un à un ceux dont votre intégration a besoin. Un token qui le porte déjà remplace n’importe lequel des 12.
API publique V23 / 22La quasi-totalité des réponses — succès comme erreurs — porte la même enveloppe : testez success en premier, puis lisez result.
✓ Succès
✗ Erreur
Une exception : les 422 de validation de paramètres. Quand un paramètre est mal formé (date au mauvais format, per_page hors bornes, canal inconnu…), la réponse ne passe pas par l’enveloppe : elle porte message et un objet errors (champ → liste de messages), sans success ni error_code. Votre client doit donc traiter les deux formes : ne concluez jamais au succès sur la seule absence de success: false, testez d’abord le code HTTP.
✗ 422 — validation de paramètres (forme distincte)
| Code | Signification | Que faire |
|---|---|---|
200 | Succès | — |
401 | Token absent / invalide / expiré | Vérifier l’en-tête, régénérer le token |
403 | Scope manquant — ou, sur POST /reservations, accès à l’espace désactivé (code: MEMBER_INACTIVE) | Recréer un token avec la bonne permission ; pour MEMBER_INACTIVE, contacter le propriétaire de l’espace |
404 | Ressource hors périmètre ou inexistante | Vérifier l’ID et le compte propriétaire du token |
409 | Conflit à la création d’une réservation : nuit déjà prise, ou référence externe déjà utilisée pour un autre séjour | Relire le calendrier, ne pas rejouer tel quel |
422 | Paramètres invalides ou opération refusée | Validation de paramètres : lire errors (champ → messages). Refus métier (payload vide, réservation annulée, canal impossible…) : lire message |
429 | Limite de 120 requêtes/minute atteinte | Attendre le délai du header Retry-After (cf. section 9) |
503 | Création de réservation déjà en cours avec la même référence externe | Rejouer après le délai du header Retry-After |
Toujours du JSON. Toutes les réponses — succès comme erreurs — sont renvoyées en JSON, que votre client envoie ou non l’en-tête Accept: application/json.
API publique V24 / 22Vue d’ensemble des 18 endpoints, lecture et écriture comprises. Les cartes détaillées de cette section couvrent la lecture ; l’écriture est décrite aux sections 5 et 6.
| Méthode | Chemin | Usage | Scope |
|---|---|---|---|
| GET | /reference | Tables de correspondance (statuts de réservation et de paiement, plateformes, devises, types de lignes de prix) | n’importe lequel |
| GET | /rentals | Lister les hébergements | rentals.read |
| GET | /rentals/{id} | Détail d’un hébergement | rentals.read |
| PATCH | /rentals/{id} | Modifier un hébergement | rentals.write |
| GET | /rentals/{id}/calendar | Lire le calendrier | calendar.read |
| PATCH | /rentals/{id}/calendar | Modifier le calendrier | calendar.write |
| GET | /reservations | Lister les réservations | reservations.read |
| GET | /reservations/{id} | Détail d’une réservation | reservations.read |
| POST | /reservations | Créer une réservation | reservations.create |
| PATCH | /reservations/{id} | Modifier une réservation | reservations.write |
| GET | /reservations/{id}/messages | Lire la conversation d’une réservation | messages.read |
| POST | /reservations/{id}/messages | Envoyer un message au voyageur | messages.write |
| GET | /reviews | Lister les avis voyageurs | reviews.read |
| GET | /reviews/{id} | Détail d’un avis | reviews.read |
| POST | /reviews/{id}/reply | Répondre publiquement à un avis | reviews.write |
| GET | /webhooks | Lister vos webhooks sortants | webhooks.manage |
| POST | /webhooks | Créer un webhook sortant | webhooks.manage |
| DELETE | /webhooks/{id} | Supprimer un webhook sortant | webhooks.manage |
Tables de correspondance des valeurs renvoyées par l’API : reservation_statuses (status → libellé), platforms (platform → nom), currencies (currency_id → code ISO), price_detail_types (type → libellé des lignes de prix), payment_statuses (payment_status → libellé), rental_unit_types (unit_type → libellé) et payment_write_methods (moyens de paiement acceptés à l’écriture). Les identifiants plateformes/devises dépendent de l’environnement — cette route est la source de référence, ne codez jamais ces tables en dur.
Exemple
Réponse (extrait)
price_detail_types donne la correspondance type → libellé (anglais stable) de toutes les lignes de prix. Utilisez-la pour mapper les type rencontrés dans price_details comme dans host_fees (objet Reservation, sections 7.5 & 7.6).
Données de référence globales, identiques pour tous les comptes — un appel au démarrage de votre intégration suffit (rafraîchissement quotidien recommandé). La réponse peut porter d’autres tables que celles décrites ici : ignorez les clés que vous ne connaissez pas plutôt que de valider la réponse contre une liste figée.
API publique V25 / 22Liste vos hébergements, triés par nom, paginés.
| Paramètre | Type | Défaut | Note |
|---|---|---|---|
per_page | int | 25 | maximum 100 |
page | int | 1 | — |
updated_since | ISO 8601 | — | Synchro incrémentale : ne renvoie que les hébergements modifiés depuis cette date. Mêmes formats acceptés que sur GET /reservations |
Réponse
Détail d’un hébergement. Renvoie l’objet Rental complet (section 7.1). 404 si l’ID n’existe pas ou n’appartient pas au compte du token.
Calendrier nuit par nuit entre deux dates incluses : disponibilité, prix, min/max nights, restrictions check-in/out.
| Paramètre | Requis | Format |
|---|---|---|
from | ✓ | YYYY-MM-DD |
to | ✓ | YYYY-MM-DD, ≥ from |
Exemple
Réponse — un objet par nuit
Sans restriction définie, les défauts sont : available = true, le reste null / false.
API publique V26 / 22Applique les champs fournis à toutes les nuits de la plage [from, to]. La synchro vers Airbnb, Booking et PriceLabs est automatique — rien d'autre à faire.
| Champ | Type | Requis | Contraintes |
|---|---|---|---|
from / to | string | ✓ | YYYY-MM-DD, to ≥ from |
available | bool | ① | — |
price | number | ① | ≥ 0 |
min_nights / max_nights | int | ① | ≥ 1 · min ≤ max si les deux fournis |
no_checkin / no_checkout | bool | ① | — |
Au moins un des 6 champs modifiables doit être présent, sinon 422. Les champs omis ne sont pas modifiés.
Aucune borne haute sur min_nights / max_nights : certains hébergeurs utilisent 999999999 comme convention « pas de limite ». L’API la lit et l’écrit telle quelle, sans la traduire.
Exemple — ouvrir juillet et fixer le prix
Réponse
Met à jour la fiche d’un hébergement. Passe par le même service que l’interface SuperHote : la propagation vers les plateformes connectées est automatique. Renvoie l’objet Rental complet mis à jour (section 7.1).
| Champ | Type | Requis | Contraintes |
|---|---|---|---|
name | string | ① | 255 caractères max |
address / city | string | ① | 255 caractères max |
latitude / longitude | number | ① | [-90, 90] · [-180, 180] |
timezone | string | ① | Fuseau IANA, ex. Europe/Paris |
enabled | bool | ① | Active / désactive l’hébergement |
capacity | int | ① | ≥ 1 — voyageurs max |
bathrooms | int | ① | ≥ 0 |
min_nights / max_nights | int | ① | ≥ 1 · min ≤ max si les deux fournis |
Au moins un de ces champs doit être présent, sinon 422. Les champs omis ne sont pas modifiés.
Aucune borne haute sur capacity, bathrooms, min_nights et max_nights : l’API accepte en écriture toute valeur qu’elle peut renvoyer en lecture, y compris la convention « pas de limite » 999999999 sur les nuits.
Exemple — renommer et rouvrir un hébergement
Seuls les champs ci-dessus sont modifiables. Les autres champs de l’objet Rental (section 7.1) — zip_code, country, check_in_time / check_out_time, currency — sont en lecture seule via l’API. L’objet Rental ne porte aucun tarif : les prix se lisent et s’écrivent nuit par nuit via GET / PATCH /rentals/{id}/calendar.
API publique V27 / 22Liste paginée des réservations, triées par création (plus récentes d'abord). Tous les filtres sont optionnels et cumulables.
| Filtre | Format | Usage |
|---|---|---|
updated_since | ISO 8601 — 2026-07-01T00:00:00Z, 2026-07-01T00:00:00+02:00 ou 2026-07-01T00:00:00 (UTC implicite) | Synchro incrémentale — ne récupérer que ce qui a changé |
created_from / created_to | YYYY-MM-DD | Plage de création |
checkin_from / checkin_to | YYYY-MM-DD | Plage d’arrivée |
checkout_from / checkout_to | YYYY-MM-DD | Plage de départ |
status | enum | Un libellé de la table de correspondance (section 7.4) : CONFIRMED · UNCONFIRMED · CANCELED · NO_SHOW · REQUEST · CANCELED_BY_TRAVELER · PRE_APPROVED · REQUEST_INFORMATION |
rental_id | string | Un seul hébergement |
page / per_page | int | max 100, défaut 25 |
Pattern recommandé pour votre synchro : toutes les 5–15 min, appelez /reservations?updated_since=<dernier passage> et stockez l’horodatage de l’appel. Vous ne traitez que le delta — léger et fiable.
Exemple — réservations confirmées modifiées depuis hier
Si le token n’a accès à aucun hébergement, la réponse est un tableau vide (meta.total = 0) — jamais une erreur.
Détail d’une réservation par son ID (statut inclus, y compris CANCELED). 404 si elle n’existe pas ou plus — utile pour votre process de détection des suppressions sans parcourir toute la collection.
Met à jour les champs fournis d’une réservation. Passe par le même service que l’interface SuperHote : synchro OTA, codes de serrure, notifications et tâches sont propagés. Renvoie l’objet Reservation complet mis à jour (section 7.3).
| Champ | Type | Requis | Contraintes |
|---|---|---|---|
status | enum | ① | CONFIRMED · UNCONFIRMED · CANCELED uniquement |
checkin / checkout | string | ① | YYYY-MM-DD, checkout > checkin · checkin obligatoire dès que checkout est fourni |
adults_count · children_count · infants_count | int | ① | [0, 100] |
private_notes | string | ① | Notes internes de la réservation, 5 000 caractères max |
Au moins un de ces champs doit être présent, sinon 422. Une réservation déjà annulée n’est plus modifiable — également 422.
Exemple — confirmer une réservation et corriger le nombre d’adultes
Le filtre status de GET /reservations accepte les 8 libellés de la table 7.4 ; l’écriture n’en accepte que 3. Les autres statuts sont posés par les plateformes, jamais par l’API.
API publique V28 / 22Crée une réservation directe sur un hébergement de votre périmètre, pour un séjour déjà vendu sur votre site. Passe par le même parcours que la création dans l’interface SuperHote : les nuits sont fermées sur Airbnb, Booking et tous les canaux connectés, et l’échéancier, les tâches, les codes de serrure et les messages automatiques sont générés. Renvoie 201 et l’objet Reservation complet (section 7.3).
| Champ | Type | Requis | Contraintes |
|---|---|---|---|
rental_id | int | ✓ | Hébergement de votre périmètre |
checkin / checkout | string | ✓ | YYYY-MM-DD, checkout > checkin, 365 nuits au plus |
time_in / time_out | string | — | HH:mm, heure locale du logement |
adults_count | int | ✓ | [1, 100] |
children_count · infants_count · pets_count | int | — | [0, 100] |
status | enum | — | CONFIRMED (défaut) · UNCONFIRMED |
payment_status | enum | ✓ | PAID (encaissé chez vous, enregistré comme paiement manuel) · UNPAID. Aucun lien de paiement n’est jamais envoyé |
nights_price | number | — | Total des nuits. Fourni : votre prix est pris tel quel, avec cleaning_fee, city_tax, other_fees (absents = 0). Absent : SuperHote calcule le séjour sur le calendrier et les frais du logement |
currency | string | — | Code ISO 4217, doit être celui de l’hébergement |
external_reference | string | — | Votre référence de commande, 191 caractères max — rend le renvoi sans risque |
private_notes | string | — | 5 000 caractères max |
guest.first_name / guest.last_name | string | ✓ | Plus guest.email ou guest.phone ; country_code, address, postal_code, city optionnels. Un voyageur déjà connu du compte est réutilisé |
| Code | Cas | Que faire |
|---|---|---|
403 | Accès à l’espace désactivé par son propriétaire (code MEMBER_INACTIVE) | Ne pas rejouer, contacter le propriétaire de l’espace |
404 | Hébergement hors de votre périmètre | Corriger |
409 | Une nuit est déjà réservée ou bloquée, ou la référence désigne un autre séjour | Relire le calendrier, ne pas rejouer tel quel |
422 | Capacité dépassée, logement désactivé, arrivée passée, devise différente, champ invalide | Corriger, ne pas rejouer |
503 | Une création avec la même référence est en cours | Rejouer après Retry-After |
Renvoi sans doublon : avec external_reference, un renvoi pour le même hébergement et les mêmes dates rend la réservation déjà créée, en 200 avec idempotent_replay: true, au lieu d’en créer une seconde. Envoyez-la systématiquement : une coupure réseau se rejoue alors sans risque.
Exemple — créer un séjour de 3 nuits déjà encaissé
Réponse — 201, la réservation créée
Les durées minimale et maximale de séjour et les jours sans arrivée ne bloquent pas la création : vous les avez déjà appliqués avant de vendre le séjour. PAID se relit PAID_MANUALLY. Ne ressortent pas dans la réponse : infants_count, pets_count, private_notes et external_reference (external_id vaut SH + l’id SuperHote) ; guest_email et guest_phone restent à null comme en lecture (section 7.3). La création émet le webhook reservation.created, y compris vers vos propres abonnements.
API publique V29 / 22En lecture, la conversation remonte les messages de tous les canaux de l’interface SuperHote : thread Airbnb, API Booking, e-mail, SMS, WhatsApp et page voyageur. En écriture, l’API n’accepte que quatre canaux — platform, email, sms et whatsapp : la page voyageur se lit, elle ne s’alimente pas depuis l’API.
Messages de la réservation, du plus récent au plus ancien, paginés.
| Filtre | Format | Usage |
|---|---|---|
since | ISO 8601 — mêmes 3 formats que updated_since | Synchro incrémentale de la conversation |
direction | inbound · outbound | inbound = voyageur → hôte · outbound = hôte → voyageur |
page / per_page | int | max 100, défaut 25 |
Réponse — un objet par message
| Champ | Valeurs | Description |
|---|---|---|
direction | inbound · outbound | Sens du message, dérivé de l’expéditeur |
sender | guest · guest_page · user · service · cohost | Expéditeur réel |
channel | airbnb · booking · email · sms · whatsapp · guest_page · platform | Canal de transport emprunté. platform est le seul qui n’en désigne aucun : il marque un message posté en channel: platform sur une réservation sans canal plateforme — enregistré, mais jamais remis au voyageur (voir POST ci-dessous) |
sent_at | ISO 8601|null | Horodatage plateforme — c’est lui qui donne le bon ordre conversationnel, pas created_at (date d’import dans SuperHote) |
API publique V210 / 22Poste un message hôte → voyageur. Il est enregistré dans la conversation SuperHote et, si un canal est retenu, remis au voyageur — même chemin que l’interface. Le canal retenu dépend de channel et de la plateforme de la réservation : lisez les encarts ci-dessous avant de vous fier à platform.
| Champ | Type | Requis | Contraintes |
|---|---|---|---|
content | string | ✓ | 60 000 caractères max |
channel | enum | — | platform (défaut) · email · sms · whatsapp |
subject | string | — | E-mail uniquement, 255 caractères max |
channel: platform ne résout un canal que sur quatre plateformes : Airbnb → thread Airbnb, Booking → API Booking, Direct et site de réservation → e-mail (422 si le voyageur n’a pas d’adresse exploitable). C’est le défaut, et le bon choix sur ces quatre plateformes uniquement.
Un 201 ne veut pas dire « remis au voyageur ». Il confirme l’enregistrement du message dans la conversation, pas son acceptation par un canal. Trois cas à traiter côté intégration :
"channel": "platform". Choisissez explicitement email, sms ou whatsapp.channel: whatsapp sans compte WhatsApp connecté à l’hébergement : réponse 201, message non remis.channel: email sur une réservation Airbnb ou Booking renvoie 422 : les messages manuels doivent passer par la plateforme. Renvoient également 422, motif dans message : un voyageur sans adresse e-mail exploitable (email), sans numéro de téléphone (sms, whatsapp), ou un hébergement déconnecté de Booking. Les pièces jointes ne sont pas exposées par l’API.
Exemple — prévenir le voyageur sur le canal de sa plateforme
Réponse — 201, le message créé
API publique V211 / 22Airbnb uniquement à ce jour : seuls les avis Airbnb sont collectés. Un compte sans annonce Airbnb obtient une liste vide, jamais une erreur. Les trois routes et le webhook review.received servent exactement le même objet, décrit sous GET /reviews.
Liste paginée des avis, du plus récent au plus ancien (date de l’avis, pas d’import). Tous les filtres sont optionnels et cumulables.
| Filtre | Format | Usage |
|---|---|---|
updated_since | ISO 8601 — mêmes 3 formats que sur GET /reservations | Synchro incrémentale — ne récupérer que ce qui a changé |
rental_id | string | Un seul hébergement. Un id hors périmètre renvoie une liste vide, jamais 404 |
platform | airbnb · booking · direct | Accepté par l’API, mais seul airbnb remonte des avis |
status | draft · answered | draft = sans réponse — le filtre de la file à traiter |
sentiment | critical · neutral · positive | Tonalité calculée à l’ingestion |
page / per_page | int | max 100, défaut 25 |
Exemple — les avis critiques encore sans réponse
Réponse — un objet par avis
API publique V212 / 22Champs d’un avis
| Champ | Type | Description |
|---|---|---|
id · rental_id · rental_name | int · int · string|null | Identifiants et nom de l’hébergement noté |
platform · external_id | enum · string|null | Plateforme d’origine et identifiant de l’avis chez elle — airbnb en pratique |
reservation_confirmation_code | string|null | Code de confirmation du séjour (ex. HMSRRNCTT8) — pas l’id SuperHote de la réservation |
guest_name | string | Nom du voyageur affiché par l’avis |
rating | float | Note toujours ramenée sur 5, quelle que soit la plateforme — c’est celle à comparer d’une plateforme à l’autre |
native_rating · native_scale | float · int | Note telle que la plateforme la publie et son barème (5 ou 10), pour réafficher l’original sans reconversion |
sentiment · urgent | enum · bool | critical · neutral · positive, et signalement d’un avis à traiter en priorité |
text · pros · cons | string|null | Corps de l’avis, points positifs et points négatifs quand la plateforme les sépare |
criteria · criteria_ratings | array | Critères et sous-notes tels que fournis par la plateforme — structure libre, [] quand elle n’en fournit pas |
status · response | enum · string|null | draft tant qu’aucune réponse n’a été postée, answered ensuite — response porte alors son texte |
reviewed_at · answered_at · updated_at | ISO 8601|null | Date de l’avis (celle qui donne le tri), date de la réponse, dernière modification — updated_at est la borne de updated_since |
Détail d’un avis par son ID — mêmes champs que la liste. 404 s’il n’existe pas ou n’appartient pas au compte du token.
Publie une réponse à un avis. Elle est enregistrée dans SuperHote puis, sur Airbnb uniquement, publiée sur la plateforme sous l’identité de l’hôte. Renvoie l’avis complet mis à jour (status: answered, response et answered_at renseignés).
| Champ | Type | Requis | Contraintes |
|---|---|---|---|
response | string | ✓ | De 2 à 5 000 caractères — seul champ accepté |
La réponse part telle quelle, et ne se reprend pas. Trois conséquences à traiter côté intégration :
status avant de poster.200 ne garantit pas la publication.Sur Booking ou une réservation directe, la réponse est enregistrée dans SuperHote sans être publiée — la publication automatique n’existe pas encore sur ces plateformes. La réponse reste un 200, le message de l’enveloppe le précise : lisez-le plutôt que de supposer.
Exemple — répondre à un avis
Réponse — 200, l’avis mis à jour
API publique V213 / 22Rental (hébergement)| Champ | Type | Description |
|---|---|---|
id | string | Identifiant unique |
name | string | Nom de l’hébergement |
address · city · zip_code · country | string|null | Adresse complète |
latitude · longitude | float|null | Géolocalisation |
capacity · bathrooms | int|null | Voyageurs maximum · nombre de salles de bain |
min_nights · max_nights | int|null | Règles par défaut (hors restrictions calendrier) |
check_in_time · check_out_time | string|null | Heures, ex. "16:00" |
currency_id · currency | int|null · string|null | Devise de l’hébergement : id interne + code ISO (ex. EUR) — table complète via GET /reference |
timezone | string|null | Fuseau horaire |
enabled | bool | Hébergement actif |
country_id | int|null | Identifiant interne du pays, à côté du country textuel |
unit_type · parent_id | string|null · string|null | Place de l’hébergement dans une hiérarchie (logement autonome, lot parent, chambre rattachée) et identifiant du parent le cas échéant. Valeurs de unit_type mappées via GET /reference → rental_unit_types |
owner_id | string|null | Propriétaire rattaché. Renseigné uniquement pour les intégrations qui y ont accès — null sinon, la clé restant toujours présente |
created_at · updated_at | ISO 8601 | Horodatages |
CalendarDay (une nuit)| Champ | Type | Défaut | Description |
|---|---|---|---|
date | string | — | YYYY-MM-DD |
available | bool | true | Nuit ouverte à la réservation |
price | number|null | null | Prix de la nuitée |
min_nights · max_nights | int|null | null | Restrictions de séjour |
no_checkin · no_checkout | bool | false | Arrivée / départ bloqués |
reservation_id | string|null | null | Réservation occupant la nuit |
API publique V214 / 22Reservation| Champ | Type | Description |
|---|---|---|
id · rental_id | string | Identifiants |
status | int | Statut numérique — table de correspondance en 7.4 |
status_label | enum|null | Libellé stable du statut, ex. CONFIRMED, NO_SHOW (table 7.4) |
platform · platform_name | int|null · string|null | Plateforme source : id interne + nom lisible (Airbnb.com, Booking.com, Direct…) — liste complète via GET /reference |
checkin · checkout | string | YYYY-MM-DD |
checkin_time · checkout_time | string|null | Heures d’arrivée et de départ effectives, HH:mm, heure locale du logement |
nights · guests_count | int | Nombre de nuits · total voyageurs (guests_count = adultes + enfants) |
adults_count · children_count | int|null | Détail adultes / enfants |
guest_first_name · guest_last_name | string|null | Identité du voyageur |
guest_email · guest_phone | null | Clés toujours présentes, toujours à null — voir l’encart Données personnelles ci-dessous |
total_price | float | Montant total payé par le voyageur (montant réellement encaissé si la réservation est annulée) |
fare_accommodation | float | Part nuitées du montant du séjour |
host_payout | float | Montant net reversé à l’hôte — c’est celui à rapprocher d’un virement reçu, une fois les host_fees et les taxes déduits |
payment_status | enum | Statut de règlement du séjour : UNPAID · PARTIALLY_PAID · PAID · PAID_MANUALLY · OVERDUE · CANCELED · REFUNDED · MANAGED_BY_PLATFORM · NOT_IMPORTED_FROM_PLATFORM · PRE_AUTHORIZED — libellés via GET /reference → payment_statuses |
price_details | array | Détail des lignes de prix voyageur (nuitées, ménage, taxe de séjour, suppléments, réductions…) — structure en 7.5 |
host_fees | array | Frais retenus côté hôte (commission plateforme, frais de service hôte, TVA hôte, taxe de séjour reversée, frais Airbnb hôte…) — jamais facturés au voyageur, distincts de price_details. Même structure que PriceDetail (7.5), montants généralement négatifs |
currency_id · currency | int|null · string|null | Devise du séjour (celle de l’hébergement) : id interne + code ISO, ex. EUR |
external_id | string|null | ID côté plateforme d’origine |
booked_at | ISO 8601|null | Date de la réservation côté plateforme (≠ created_at = date d’import dans SuperHote) |
canceled_at | ISO 8601|null | Date d’annulation — null si la réservation n’est pas annulée |
created_at · updated_at | ISO 8601 | Pour la synchro incrémentale |
infants_count est accepté à l’écriture par POST /reservations et PATCH /reservations/{id} mais ne figure pas dans l’objet Reservation : vous ne pourrez pas le relire. Les bébés ne sont pas non plus comptés dans guests_count.
Données personnelles (RGPD). Les clés guest_email et guest_phone sont toujours présentes dans le payload, mais valent null : aucun des 12 scopes proposés à la création d’un token n’ouvre l’accès aux coordonnées du voyageur. Avec ces scopes, seuls le prénom et le nom (guest_first_name / guest_last_name) sont renseignés.
API publique V215 / 22| status | status_label | Signification |
|---|---|---|
| 0 | CANCELED | Annulée (par l’hôte) |
| 1 | CONFIRMED | Confirmée |
| 2 | UNCONFIRMED | Non confirmée (en attente côté plateforme) |
| 3 | NO_SHOW | Voyageur non présenté |
| 4 | REQUEST | Demande de réservation en attente |
| 5 | CANCELED_BY_TRAVELER | Annulée par le voyageur |
| 6 | PRE_APPROVED | Pré-approuvée |
| 7 | REQUEST_INFORMATION | Demande d’information |
Ces valeurs sont figées (contrat d’API) et également exposées par GET /reference. Pour les plateformes et devises, les identifiants dépendent de l’environnement : toujours les résoudre via GET /reference ou les champs platform_name / currency des payloads.
PriceDetail (ligne de prix d’une réservation)Chaque élément de price_details représente une ligne facturée au voyageur. Les frais côté hôte (commission plateforme, frais de service hôte, TVA hôte…) ne sont pas inclus ici : ils figurent dans le tableau séparé host_fees (même structure, voir ci-dessous). Les lignes à 0 sont omises — les réductions restent présentes (montant négatif).
La liste des type ci-dessous n’est pas exhaustive. La correspondance complète type → libellé (valable pour price_details et host_fees) est fournie par GET /reference → price_detail_types (section 4).
| Champ | Type | Description |
|---|---|---|
type | string | Nature de la ligne : night (nuitées), city_tax (taxe de séjour), cleaning_fee (ménage), linen_fee / bed_linens_fee (linge), additional_guests_total_price (voyageurs supplémentaires), pets_fees (animaux), infant_bed_fees (lit bébé), discount_amount (réduction, négatif), other… |
label | string | Libellé affichable de la ligne |
quantity | int|null | Quantité (ex. nombre de nuits pour la ligne night) |
unit_amount | float|null | Montant unitaire |
vat_rate | float|null | Taux de TVA appliqué (%) |
total | float|null | Total TTC de la ligne (négatif pour une réduction) |
Exemple — price_details d’un séjour de 4 nuits
host_fees (frais retenus côté hôte)Tableau séparé de price_details, présent sur chaque réservation. Il liste les montants retenus sur le versement à l’hôte (commission de la plateforme, frais de service hôte, TVA hôte, taxe de séjour reversée par l’hôte, frais Airbnb hôte…) — ce ne sont jamais des lignes facturées au voyageur. Chaque élément suit exactement la même structure qu’une ligne PriceDetail (champs type, label, quantity, unit_amount, vat_rate, total), avec des montants généralement négatifs (ils diminuent le versement). Les type se résolvent via la même table GET /reference → price_detail_types.
Exemple — host_fees d’une réservation Airbnb
price_details vs host_fees. price_details = ce que paie le voyageur ; host_fees = ce qui est retenu à l’hôte. Ne les additionnez pas : ce sont deux vues distinctes. Pour reconstituer le net versé à l’hôte, partez de total_price et appliquez les lignes de host_fees.
API publique V216 / 22| Symptôme | Cause probable | Solution |
|---|---|---|
401 Unauthenticated | Token mal copié, espace parasite, ou expiré | Re-copier le token ; en générer un nouveau si expiré |
403 sur un seul endpoint | Le token n’a pas le scope de cet endpoint | Créer un token en cochant le scope manquant (les scopes d’un token existant ne se modifient pas) |
404 sur un rental qui existe | Le rental appartient à un autre compte | Vérifier que le token vient du bon compte SuperHote |
422 sur PATCH calendar | Aucun champ modifiable fourni, ou min > max | Fournir au moins 1 champ ; vérifier les bornes |
Tableau rentals vide | Aucun hébergement actif sur le compte | Vérifier côté dashboard SuperHote |
| Prix non répercuté sur Airbnb | Latence de synchro plateforme | La propagation est automatique mais asynchrone (quelques minutes) |
429 Too Many Requests | Limite de 120 requêtes/minute dépassée (section 9) | Attendre le délai du header Retry-After puis réessayer — prévoir un backoff dans votre client |
| Réponse HTML au lieu de JSON | Ancienne version de l’API (avant juillet 2026) | Corrigé : toutes les réponses (succès et erreurs) sont désormais en JSON, avec ou sans en-tête Accept |
L’API accepte 120 requêtes par minute et par compte (tous tokens du compte confondus). Chaque réponse indique où vous en êtes :
| En-tête | Description |
|---|---|
X-RateLimit-Limit | Nombre maximal de requêtes par minute (120) |
X-RateLimit-Remaining | Requêtes restantes dans la fenêtre courante |
Retry-After | Présent sur un 429 : secondes à attendre avant de réessayer |
Réponse 429 — limite dépassée
À 120 req/min, un import initial paginé reste rapide : 10 000 réservations en pages de 100 = 100 requêtes, soit moins d’une minute. Pour la synchro de routine, préférez updated_since toutes les 5–15 min — 1 requête suffit.
429 + Retry-Afterupdated_since (5–15 min)success avant de lire resultX-RateLimit-Remaining et ralentir avant d’atteindre 0
API publique V217 / 22Plutôt que d’interroger l’API en boucle, abonnez une URL : SuperHote y poste un JSON signé à chaque événement. Les webhooks complètent la synchro par updated_since sans la remplacer — gardez un passage périodique comme filet si une livraison se perd.
Abonne une URL à un ou plusieurs événements. Le secret de signature (préfixe whsec_) n’est renvoyé qu’à la création — stockez-le immédiatement, aucun listing ne le réaffiche.
| Champ | Type | Requis | Contraintes |
|---|---|---|---|
url | string | ✓ | http ou https, 2 048 caractères max — une IP privée ou réservée est refusée (422) |
events | string[] | ✓ | Au moins une valeur de la table ci-dessous |
Exemple
Réponse — 201, le secret n’apparaît qu’ici
| Événement | Déclencheur | Contenu de data |
|---|---|---|
message.received | Nouveau message entrant du voyageur, tous canaux confondus (Airbnb, Booking, page voyageur…). Les messages sortants de l’hôte relèvent de message.sent, ci-dessous. | message + reservation_id + rental_id |
message.sent | Message sortant de l’hôte : envoi manuel, message automatique ou réponse de l’assistant (sender = user, service ou cohost). Événement distinct : message.received reste réservé à l’entrant voyageur et n’a pas changé. | Identique à message.received, avec direction: outbound |
reservation.created | Nouvelle réservation, tous les chemins : directe, Airbnb, Booking, iCal | reservation — l’objet exact de GET /reservations/{id} (section 7.3) |
reservation.updated | Réservation modifiée | Idem reservation.created |
reservation.canceled | Réservation annulée depuis l’application ou par la plateforme | Idem reservation.created |
review.received | Nouvel avis voyageur collecté depuis la plateforme (Airbnb uniquement). Émis à la première ingestion de l’avis — une re-synchro ne le rejoue pas. | review seul — l’objet exact de GET /reviews (section 6) |
Une annulation faite par l’API ne lève pas reservation.canceled. Un PATCH /reservations/{id} avec status: CANCELED émet reservation.updated portant status_label: CANCELED. Pour attraper toutes les annulations, abonnez-vous aux deux événements et testez status_label.
API publique V218 / 22Corps d’une livraison — message.received
Corps d’une livraison — review.received, un data à une seule clé
data ne porte que les clés propres à l’événement : review seul ici, contre message + reservation_id + rental_id pour les événements de messagerie. L’hébergement et le séjour d’un avis se lisent à l’intérieur de l’objet (rental_id, reservation_confirmation_code).
| En-tête | Description |
|---|---|
X-Superhote-Signature | sha256=<HMAC-SHA256(corps, secret)> — à vérifier sur les octets bruts du corps |
X-Superhote-Event | Type d’événement, ex. message.received |
X-Superhote-Delivery | UUID de la livraison, identique sur les nouvelles tentatives — votre clé d’idempotence |
Vérifiez la signature avant tout parsing. Calculez le HMAC sur le corps tel qu’il arrive — un JSON ré-encodé (ordre des clés, espaces) produit une signature différente et vous rejetterez des livraisons valides. Sans cette vérification, n’importe qui connaissant votre URL peut vous injecter de fausses réservations.
2xx tout de suite et traitez en asynchrone.2xx → 2 nouvelles tentatives (à 1 min puis 5 min), ensuite la livraison est abandonnée.422.Liste vos webhooks (id, url, events, is_active, created_at). Le secret n’y figure jamais : si vous l’avez perdu, supprimez le webhook et recréez-le.
Supprime un webhook — les livraisons s’arrêtent immédiatement. 404 si l’ID n’existe pas ou appartient à un autre compte.
updated_since + stockage de l'horodatageBesoin d'aide ? Support intégrateurs : support@superhote.com — précisez « API publique V2 » en objet, avec votre error_code et l'horodatage de la requête.
API publique V219 / 22Quelques lignes de configuration suffisent pour que Claude, Cursor ou n’importe quel assistant compatible travaille directement sur vos hébergements, votre calendrier et vos réservations.
Le MCP (Model Context Protocol) est la prise standard entre un assistant IA et une application. Branchez le vôtre sur SuperHote : il pourra consulter vos hébergements, votre calendrier et vos réservations, et répondre à vos voyageurs — dans la limite des permissions de votre clé API.
Ce n’est pas un accès à votre compte. Votre assistant ne se connecte jamais à votre session SuperHote : il s’authentifie avec une clé API, exactement comme un partenaire externe — que vous l’ayez collée à la main ou accordée en un clic. C’est la clé — et elle seule — qui décide de ce qu’il peut voir et faire. Une clé en lecture seule donne une IA en lecture seule.
Ces assistants se branchent avec la seule adresse du serveur, sans clé à copier : dans leurs réglages, ajoutez un connecteur personnalisé et collez l’adresse ci-dessous.
Adresse du serveur
claude.ai ou chatgpt.com), puis cochez les permissions que vous acceptez de lui confier.L’accès accordé apparaît dans l’onglet Clés & accès sous le nom de l’application, avec la mention OAuth. Il se renouvelle seul ; le révoquer depuis cet onglet coupe l’assistant immédiatement.
API publique V2 · Serveur MCP20 / 22Rendez-vous dans l’onglet Clés & accès (SuperHote → Plateformes → API), créez une clé et cochez les permissions que vous acceptez de confier à votre assistant. Ce sont exactement les mêmes clés que celles de l’API REST, avec les mêmes portées.
La clé n’est affichée qu’une seule fois, juste après sa création. Copiez-la immédiatement et conservez-la dans un gestionnaire de mots de passe : elle sera collée dans la configuration de votre client IA, et SuperHote ne pourra plus vous la réafficher.
Deux informations suffisent : l’adresse du serveur et votre clé. Le transport est Streamable HTTP.
Adresse du serveur
En-tête d’authentification
Dans tous les exemples ci-dessous, remplacez VOTRE_CLE_API par la clé copiée à l’étape 2, en conservant le mot Bearer devant.
Le plus simple est le connecteur personnalisé de la section 1, sans clé à copier. Le pont mcp-remote ci-dessous reste utile pour brancher Claude Desktop sur une clé que vous gérez vous-même.
claude_desktop_config.json
Ouvrez ce fichier depuis Réglages → Développeur → Modifier la configuration, collez le bloc ci-dessus, enregistrez, puis redémarrez Claude : le serveur « superhote » apparaît alors dans la liste de vos outils.
Éditez ~/.cursor/mcp.json (ou passez par Réglages → MCP), puis rechargez la fenêtre.
~/.cursor/mcp.json
Une seule commande à lancer dans votre terminal :
Tout client compatible MCP Streamable HTTP fonctionne avec les deux informations du haut de section : l’URL du serveur et l’en-tête Authorization. La forme de Cursor (3.2) — url + headers — est celle attendue par la plupart d’entre eux ; les clients qui ne savent gérer qu’un serveur local passent par le pont mcp-remote de 3.1. Ceux qui savent se connecter en OAuth se branchent aussi comme en section 1, avec l’adresse seule.
API publique V2 · Serveur MCP21 / 22Les cases cochées à la création de votre clé déterminent directement ce que votre assistant sait faire : un outil dont la permission n’a pas été accordée n’est pas utilisable, et la tentative se solde par une erreur de permission.
| Outil | Ce qu’il fait | Permission requise |
|---|---|---|
get_reference | Table de correspondance statuts / plateformes / devises | public-api:* |
list_rentals | Liste des hébergements | public-api:rentals.read |
get_rental | Détail d’un hébergement | public-api:rentals.read |
update_rental | Modifier un hébergement | public-api:rentals.write |
get_rental_calendar | Calendrier nuit par nuit | public-api:calendar.read |
update_rental_calendar | Modifier dispo / prix / restrictions | public-api:calendar.write |
list_reservations | Liste des réservations | public-api:reservations.read |
get_reservation | Détail d’une réservation | public-api:reservations.read |
create_reservation | Créer une réservation, après votre confirmation | public-api:reservations.create |
update_reservation | Modifier une réservation | public-api:reservations.write |
list_reservation_messages | Conversation voyageur | public-api:messages.read |
send_reservation_message | Envoyer un message au voyageur | public-api:messages.write |
list_webhooks | Liste des webhooks | public-api:webhooks.manage |
create_webhook | Créer un webhook | public-api:webhooks.manage |
delete_webhook | Supprimer un webhook | public-api:webhooks.manage |
public-api:* signifie que n’importe laquelle des permissions ci-dessus suffit : get_reference répond à toute clé valide.
Les outils d’écriture agissent sur vos vraies données. send_reservation_message envoie un message à un vrai voyageur, update_rental_calendar modifie des prix propagés à vos plateformes. Ne cochez les permissions .write que si vous acceptez que votre assistant agisse sans validation de votre part.
La création de réservation demande toujours votre accord. create_reservation ne crée rien au premier appel : l’assistant reçoit un aperçu (logement, dates, voyageurs, paiement) qu’il doit vous présenter, et la réservation n’est créée qu’au second appel, avec ces valeurs exactes.
Le quota est partagé avec l’API REST. Les appels MCP comptent dans la même limite de 120 requêtes par minute et par compte. Si un channel manager consomme déjà l’API sur ce compte, un assistant très bavard peut le faire basculer en 429.
Besoin d’aide ? Support intégrateurs : support@superhote.com — précisez « API publique V2 » ou « MCP » en objet.
API publique V2 · Serveur MCP22 / 22