Guide Node · API publique

Branchez Node à vos outils

Lisez votre parc et vos réservations, écrivez vos disponibilités et vos tarifs, recevez les événements en temps réel. Depuis Make, n8n, votre CRM ou vos propres scripts.

23 appels 13 événements 18 autorisations Inclus au Pack 2
Vous codez avec une IA ?

Donnez-lui la référence complète — chaque appel, chaque champ, chaque erreur, les recettes et les pièges, en un seul fichier. Elle aura tout pour construire votre intégration sans deviner.

curl -s https://docs.nodegroupe.com/reference.md

Cette page suffit pour démarrer. Le détail exhaustif est dans la référence, et la spécification machine sur openapi.json — importable telle quelle dans Postman.

1. Démarrer en 3 minutes

1Réglages → API & MCPDans Node, ouvrez l'onglet.
2Cochez les autorisationsUniquement ce dont votre outil a besoin.
3Copiez la cléElle ne s'affiche qu'une seule fois
Les autorisations sont votre protection

Une clé ne peut faire que ce que vous avez coché. Si vous confiez une clé à un prestataire pour alimenter un tableau de bord, ne cochez que la lecture : il ne pourra rien modifier, même par erreur.

Votre premier appel

Il ne touche à aucune donnée — il vous dit seulement si la clé fonctionne et ce qu'elle a le droit de faire.

curl https://app.nodegroupe.com/api/v1/me \
  -H "Authorization: Bearer node_sk_..."

Faites-le avant d'écrire votre intégration : découvrir une autorisation manquante en pleine boucle de traitement coûte bien plus cher.

L'API est incluse au Pack 2

Un compte Pack 1 ne peut pas créer de nouvelle clé — l'écran vous le dit, le bouton est désactivé. Les clés créées avant le 1er septembre 2026 restent valables quel que soit votre pack : une décision de tarification ne coupe pas une intégration déjà en service.

Une clé marquée « accès complet » ?

Elle a été créée avant les autorisations et peut tout faire sur votre compte, y compris supprimer des réservations. Cochez ce dont elle a besoin, puis Restreindre : la clé reste valable, vous n'avez rien à reconfigurer.

2. Les 3 règles à connaître

Elles expliquent la quasi-totalité des intégrations qui coincent.

① Écrire un prix ou une disponibilité répond 202, pas 200

Vous recevez un job_id. À cet instant, rien n'est encore parti chez Airbnb ou Booking.

Node ne parle pas directement aux plateformes : il passe par un gestionnaire de canaux dont le débit est partagé entre tous les clients de Node. Une écriture immédiate depuis l'extérieur ralentirait la synchronisation de tout le monde. Vos modifications sont donc mises en file et poussées par lots, en quelques minutes.

# Suivez l'avancement — toutes les 10 à 30 secondes, pas plus souvent
GET /api/v1/jobs/{job_id}
# status : pending → processing → completed | failed

Un seul échec parmi les opérations marque le travail failed : annoncer « terminé » alors qu'une partie des dates n'est pas partie serait le pire des mensonges pour un calendrier.

② Écrivez par lot, jamais date par date

// ✅ UN appel, plusieurs plages — jusqu'à 60
PUT /api/v1/rates
{
  "property_id": "…",
  "ranges": [
    { "from": "2027-07-01", "to": "2027-08-31", "price": "180.00", "min_stay": 5 },
    { "from": "2027-09-01", "to": "2027-10-31", "price": "120.00" }
  ]
}

// ✅ Les mêmes plages sur PLUSIEURS logements — jusqu'à 50 par appel
PUT /api/v1/availability
{
  "property_ids": ["…", "…", "…"],
  "ranges": [ { "from": "2027-12-20", "to": "2027-12-27", "available": false } ]
}
// → 202 + "jobs": [{ "property_id", "job_id" }, …] — un suivi par logement

// ❌ JAMAIS ça : quota épuisé en secondes, envois rejetés
for (const date of dates) PUT /api/v1/rates { ranges: [{ from: date, to: date }] }
Une plage qui commence dans le passé est refusée EN ENTIER

Partie future comprise. Ce n'est pas une coquetterie : les plateformes rejettent la plage complète, et laisser passer vous donnerait un calendrier que vous croyez à jour alors qu'il ne l'est pas — c'est comme ça qu'on se retrouve en surréservation. Découpez à partir d'aujourd'hui.

③ Faites-vous prévenir, n'interrogez pas en boucle

Pour savoir qu'une réservation est arrivée, déclarez un point de réception : Node vous appelle. Le paramètre updated_since sert au rattrapage après une panne de votre côté, pas à la détection continue.

3. Tous les appels

Le détail de chacun — paramètres, réponse, erreurs, recommandations — est dans la référence complète.

AppelCe que ça faitAutorisation
GET /v1/meVérifier la clé et ses autorisationsaucune
GET /v1/me/modulesModules allumés pour ce compte (navigation d'un espace marque blanche)aucune
GET /v1/propertiesLister les logements — filtres ids, updated_since, statusproperties:read
POST /v1/propertiesCréer un logementproperties:write
GET /v1/properties/{id}Détail d'un logementproperties:read
PATCH /v1/properties/{id}Modifier un logementproperties:write
GET /v1/ownersLister les propriétairesowners:read
POST /v1/ownersCréer un propriétaireowners:write
GET /v1/reservationsLister les réservations — filtres updated_since, property_ids, arrival_from/to, departure_from/to, status, channelreservations:read
GET /v1/reservations/{id}Une réservation — à appeler après un webhookreservations:read
POST /v1/reservationsRéservation directe ou blocagereservations:write
GET /v1/channelsValeurs possibles du canal d'une réservationreservations.planning:read
GET /v1/calendarDisponibilités + tarifs de 50 logements × 400 jours en un appelavailability:read rates:read
GET /v1/availabilityLire le calendrieravailability:read
PUT /v1/availability202Ouvrir ou fermer des dates — 1 à 50 logements, 60 plagesavailability:write
GET /v1/ratesLire prix et restrictionsrates:read
PUT /v1/rates202Écrire prix et restrictions — 1 à 50 logements, 60 plagesrates:write
GET /v1/jobs/{id}Suivre une écriture asynchroneaucune
GET /v1/cleaning/missionsLister les missions de ménagecleaning:read
POST /v1/cleaning/missionsCréer une missioncleaning:write
GET /v1/incidentsLister les incidents (lecture seule)cleaning:read
GET /v1/invoicesFactures propriétaire — lecture seulebilling:read
GET /v1/messagesConversations et messagesmessages:read
POST /v1/messagesÉcrire à un voyageurmessages:send
GET /v1/webhooksPoints de réception + catalogue d'événementswebhooks:manage
POST /v1/webhooksDéclarer un point de réceptionwebhooks:manage
POST /v1/catalogue/propositionsProposer une extension de son espace au catalogue Nodecatalogue:propose
GET /v1/espace/donneesInventaire des données de l'espaceespace.donnees:read
GET /v1/espace/donnees/{collection}Lister les documents d'une collectionespace.donnees:read
POST /v1/espace/donnees/{collection}Créer un documentespace.donnees:write
GET /v1/espace/donnees/{collection}/{id}Lire, modifier (PATCH) ou supprimer (DELETE) un documentespace.donnees:write
GET /v1/espace/secrets/{nom}Lire une clé confiée par la conciergerie à son espace (coffre à secrets)espace.secrets:read
GET /v1/espace/domainesDomaines externes que l'espace peut joindreespace.secrets:read
GET /v1/espace/automatisationsAutomatisations de l'espace, état et journalespace.automatisations:write
POST /v1/espace/automatisations/journalInscrire le résultat d'une exécutionespace.automatisations:write
POST /v1/envois/emailEnvoyer un e-mail au nom de la conciergerie (200 par jour)envois.email:send
GET /v1/webhooks/{id}État + 20 dernières livraisonswebhooks:manage
PATCH /v1/webhooks/{id}Changer les événements, la description, réactiver (même secret)webhooks:manage
DELETE /v1/webhooks/{id}Retirer un point de réceptionwebhooks:manage
GET /v1/prospection/leadsLister les dossiers propriétairesprospection:read
POST /v1/prospection/leadsCréer un dossier (site web, campagne publicitaire)prospection:write
GET /v1/prospection/leads/{id}Lire un dossierprospection:read
PATCH /v1/prospection/leads/{id}Compléter ce qu'on a apprisprospection:write
POST /v1/prospection/leads/{id}/advanceDemander une avancée d'étapeprospection:write
GET /v1/validationsActes régulés en attente de validation (carte G)validations:read
GET /v1/validations/{id}Le détail d'un acte : avant / après, champ par champvalidations:read
POST /v1/validations/{id}/decisionApprouver ou refuser à la place du propriétairevalidations:decide
Faire remonter vos leads depuis un site ou une campagne

Créez une clé qui ne coche que prospection:write : elle crée des dossiers, elle n'en lit aucun. Si elle fuite, elle ne donne accès à rien.

Ne mettez jamais la clé dans la page. Tout ce qui part dans le navigateur est lisible par le visiteur : une clé posée dans le JavaScript d'un formulaire est publique dès la première visite. Le formulaire envoie à votre serveur, qui relaie à Node — ou passez par un connecteur (Zapier, Make, n8n) qui garde le secret de son côté. C'est aussi la seule méthode possible depuis un formulaire publicitaire Meta ou Google, qui ne sait pas appeler une API protégée.

L'étape ne s'écrit pas, elle se demande. stage est calculée à partir de ce qui est réellement renseigné ; l'envoyer ne produit aucune erreur, le champ est simplement ignoré. Pour faire avancer un dossier : POST /v1/prospection/leads/{id}/advance, qui répond en nommant le verrou qui retient.

Les doublons sont rattrapés. Un même e-mail ou téléphone déjà présent sur 30 jours renvoie 200 avec le dossier existant et deduplicated: true — pas une erreur. Les numéros sont comparés sur leurs neuf derniers chiffres, +33 6… et 06… étant le même.

Deux conventions qui évitent des surprises

Pagination par curseur, jamais par numéro de page : ?limit=100 puis ?cursor=… tant que has_more est vrai. Un offset dérive dès qu'une ligne s'insère pendant votre boucle — vous sauteriez des enregistrements sans le savoir.

Un en-tête Idempotency-Key sur tout POST : rejouer la même clé sous 24 h renvoie la première réponse au lieu de créer un doublon.

3 bis. Synchroniser en masse

Pour un outil qui tient sa propre copie des données — gestion des revenus, comptabilité, reporting : importer une fois, puis ne relire que ce qui a changé.

Le schéma en trois temps

ÉtapeAppels
Import initial
à l'arrivée d'un client
GET /v1/properties (paginé)
GET /v1/reservations?property_ids=…&departure_from=2024-01-01&departure_to=2028-12-31
GET /v1/calendar?property_ids=…&from=…&to=… (fenêtres de 400 jours)
Synchronisation quotidienne
ou à chaque webhook
GET /v1/properties?updated_since=…
GET /v1/reservations?updated_since=…
GET /v1/calendar?property_ids=…&from=…&to=…&updated_since=…
Rapprochement
ponctuel
Relire les identifiants sur une période (GET /v1/properties, GET /v1/reservations?departure_from=…) et comparer : une réservation annulée reste visible avec status: "cancelled" et cancelled_at — rien ne disparaît sans trace.

Gardez la date du début de votre synchronisation précédente comme prochain updated_since (pas celle de la fin) : un enregistrement modifié pendant votre passage serait sinon perdu.

Le calendrier en un appel

GET /v1/calendar réunit disponibilités et tarifs : jusqu'à 50 logements × 400 jours. Par jour : available, booked, blocked, price, currency, min_stay, max_stay, closed_to_arrival, closed_to_departure, stop_sell, updated_at. Les valeurs du jour sont celles du plan tarifaire principal ; include_rate_plans=true ajoute le détail par plan.

updated_since sur le calendrier est large, pas exact

Le calendrier est relu régulièrement auprès du gestionnaire de canaux : un jour relu sans changement peut réapparaître. Vous ne manquerez aucun changement, mais dédoublonnez de votre côté.

Le détail tarifaire d'une réservation

Avec reservations:read, chaque réservation porte un objet pricing : currency, accommodation (séjour seul), ota_commission, tourist_tax, cleaning_fee, net_owner, et fees — les frais détaillés transmis par la plateforme (linge, animaux, personne supplémentaire…, surtout Airbnb). S'y ajoutent booked_at (date de réservation réelle), status_detail (blocked pour un blocage) et is_block.

Les valeurs possibles de channel sont renvoyées par GET /v1/channels : de quoi construire votre table de correspondance une fois pour toutes.

Vos prix ne sont pas écrasés

Un prix écrit par PUT /v1/rates est inscrit comme fixé à la main : le moteur de tarification de Node ne le réécrit pas. La conciergerie le voit dans « Règles enregistrées » et peut le réinitialiser.

Accès et quotas

AccèsLectures / minÉcritures / minÉcritures calendrier / min
Clé de la conciergerie (node_sk_…, Paramètres → API & MCP)6006010
Application partenaire OAuth2 (node_at_…, une connexion par client)3 00030030
  • Les quotas sont par clé : chaque client a les siens, synchronisez-les en parallèle.
  • Chaque réponse porte RateLimit-Limit, RateLimit-Remaining et RateLimit-Reset ; un 429 porte Retry-After.
  • OAuth2 : code d'autorisation + PKCE, jeton d'accès de 2 h, jeton de renouvellement de 90 jours. Pour obtenir une application partenaire, écrivez au support avec votre URL de redirection.
  • Une écriture calendrier couvre 60 plages × 50 logements : 10 appels par minute suffisent largement.

4. Être prévenu — les webhooks

Sans eux, savoir qu'une réservation est arrivée impose d'interroger l'API en boucle. Et vous ne serez jamais prévenu plus tôt qu'avec un webhook.

POST /api/v1/webhooks
{
  "url": "https://mon-service.fr/hooks/node",
  "events": ["reservation.created", "reservation.cancelled"]
}

23 événements : réservations, arrivées et départs, messages voyageur, missions de ménage, factures, logements, calendrier et prix, incidents, validations. Le catalogue complet est renvoyé par GET /v1/webhooks : vous pouvez construire votre écran d'abonnement à partir de cette seule réponse.

Calendrier et prix

Pour garder un site de réservation à jour sans interroger l'API en boucle :

ÉvénementQuandCorps (data)Portée
availability.updatedDates ouvertes, fermées ou réservées, sur n'importe quel canalproperty_id, start_date, end_dateavailability:read
rates.updatedPrix par nuit ou règle de séjour modifié, sur n'importe quel plan tarifaireproperty_id, start_date, end_daterates:read
property.deletedLogement suppriméproperty_idproperties:read
  • L'événement est un signal : relisez GET /v1/availability et GET /v1/rates sur la plage reçue (dates incluses).
  • Regroupé par logement : 30 modifications d'affilée donnent un seul événement, envoyé 30 secondes après la dernière (5 minutes au plus après la première), dont la plage couvre toutes les dates touchées.
  • Un changement fait directement dans l'extranet de l'OTA ou dans Channex n'émet rien tant que Node ne l'a pas relu. Gardez une synchronisation quotidienne en filet de sécurité.

Modifier un abonnement

PATCH /api/v1/webhooks/{id}
{
  "events": ["reservation.created", "availability.updated", "rates.updated"]
}

events remplace la liste entière : pour ajouter un événement, renvoyez la liste actuelle plus le nouveau. Le secret ne change pas, rien à redéployer chez vous. enabled: true réactive un point de réception coupé. L'URL et le secret ne se modifient pas : pour en changer, créez un nouveau point de réception. Un jeton ne modifie que les points de réception qu'il a créés.

Vérifiez toujours la signature

Votre URL est publique : elle finit dans des logs, des captures d'écran, des tickets. La signature Node-Signature est la seule chose qui distingue un événement de Node d'un événement fabriqué. Le code de vérification, en JavaScript et en Python, est dans la référence.

⚠️ Signez le corps brut, avant tout parsing : un JSON.parse puis JSON.stringify réordonne les clés et invalide la signature.

GarantieCe que ça implique pour vous
Au moins une livraison, jamais exactement uneDédoublonnez sur l'en-tête Node-Event-Id, stable entre les tentatives
Reprises espacées : 1 min, 5, 30, 2 h, 6 h, 24 hUne panne courte de votre côté ne perd rien
20 échecs consécutifs coupent le point de réceptionAucun e-mail n'est envoyé : surveillez disabled_at sur GET /v1/webhooks/{id}. Réactivez-le avec PATCH /v1/webhooks/{id} et {"enabled": true} : le compteur repart de zéro
Réponse attendue en moins de 10 secondesRépondez 2xx tout de suite, traitez en tâche de fond

GET /v1/webhooks/{id} renvoie les 20 dernières livraisons avec code de réponse et message d'erreur. C'est la première chose à regarder avant d'ouvrir un ticket « je ne reçois rien ».

5. Quand ça ne marche pas

RéponseSignificationQue faire
400Paramètre absent ou mal forméLe champ field dit lequel
401Clé absente, mal copiée, expirée ou révoquéeVérifier la clé
403 scope_missingL'autorisation n'est pas cochéeLe message nomme la portée manquante
403 PACK2_REQUIREDL'API est incluse au Pack 2Votre compte est au Pack 1
404Introuvable — ou hors du périmètre de votre cléVérifier l'identifiant
422Valide mais inapplicableEx. logement non connecté aux canaux
429Trop d'appelsRespectez Retry-After — réessayer tout de suite aggrave la situation
Le réflexe qui fait gagner une heure

Chaque réponse porte un en-tête Node-Request-Id. Citez-le dans votre demande au support : il retrouve votre appel exact, à la seconde près.

6. Ce que l'API ne fait pas

Chaque refus a une raison, et la voici.

Pas possiblePourquoi
Supprimer une réservation ou un logementLa suppression libère les dates chez les plateformes sans laisser de trace. Passez le statut à cancelled : c'est tracé et réversible.
Modifier une réservation Airbnb, Booking ou d'une autre plateformeElle appartient à la plateforme : une modification faite ailleurs serait écrasée au prochain échange. Seules les réservations directes et les blocages s'écrivent ici.
Donner frais de gestion, TVA, commission voyageur, remboursements, promotions ou frais de paiement d'une réservationNode ne les reçoit pas de façon fiable des plateformes. Plutôt que des montants inventés, ces lignes sont absentes de pricing.
Écrire sur la facturation ou les paiementsCommissions, TVA et taxe de séjour s'y croisent : une erreur d'intégration deviendrait une erreur comptable. Lecture seule.
Lire les identifiants de vos comptes OTANi les vôtres, ni ceux de personne. Leur fuite compromettrait vos comptes sur les plateformes.
Accéder aux données d'un autre compteAucune portée d'administration, aucun accès inter-comptes.
Utiliser une clé depuis un navigateurUn secret dans une page est un secret public. L'API est serveur à serveur.

7. Support

Ouvrez un ticket depuis Node en citant :

  1. le Node-Request-Id de la réponse (ou le Node-Event-Id pour un webhook) ;
  2. l'horodatage ;
  3. le début de votre clé (node_sk_AbC1…) — jamais le secret complet.

Ces trois éléments suffisent à retrouver votre appel exact dans le journal.