Aller au contenu
edoobox Docs
Essayer gratuitement 7 jours d’essai sans engagement
Menu
Essayer gratuitement 7 jours d’essai sans engagement

API : Synchroniser les réservations avec un CRM et d'autres systèmes

Une synchronisation REST régulière maintient les réservations à jour dans un CRM, une vue interne ou un reporting. Elle convient également comme synchronisation supplémentaire aux Webhooks. Ce guide montre comment récupérer complètement de nouvelles réservations, maîtriser le traitement répété et tenir compte des modifications ultérieures de réservations déjà connues.

Préparer la synchronisation

  1. Configurez une clé API propre avec des droits de lecture pour les ressources nécessaires. Utilisez API : Premiers pas pour l'authentification et les en-têtes.
  2. Déterminez les données nécessaires au système cible : l’ID de réservation, l’offre, la personne qui réserve, le statut de liste d’attente et le statut d’annulation constituent un point de départ possible.
  3. Enregistrez l'association entre la réservation edoobox et l'enregistrement cible ainsi que la dernière période entièrement traitée de manière permanente dans votre intégration.
  4. Définissez deux exécutions : une récupération fréquente de nouvelles réservations et une synchronisation régulière des réservations déjà connues.

Les requêtes suivantes utilisent GET /v2/booking/list. L’hôte, la clé API, le jeton et l’edid doivent correspondre au même environnement et au compte sélectionné. La référence de l’API v2 contient les points de terminaison et le fichier OpenAPI téléchargeable.

Distinguer la réservation, les participants et l'horodatage

ChampUtilisation dans la synchronisation
idAssociation stable de la réservation dans le compte sélectionné. Enregistrez cette valeur opaque sans la modifier ; n’en déduisez aucun numéro interne de base de données.
timeMoment de la réservation. Vous pouvez ainsi limiter les réservations selon leur moment de création.
offerRéférence à l'offre réservée.
ownerRéférence à la personne réservante. Une réservation peut contenir d'autres participants.
canceledIndicateur d'annulation de la réservation. Reprendre la valeur actuelle livrée dans le système cible.
waiting_listIndicateur de liste d'attente. À prendre en compte séparément de l'indicateur d'annulation pour l'évaluation.

time n’est pas un horodatage de modification. Une ancienne réservation modifiée ou annulée aujourd’hui ne sera pas automatiquement trouvée par un filtre portant sur les réservations créées aujourd’hui. L’heure de réservation ne désigne pas non plus le début de l’offre réservée.

Pour les listes de participants ou les positions individuelles, la personne réservante seule ne suffit pas. Chargez au besoin les participants associés ou les détails de réservation avec les ressources prévues à cet effet. La distinction fonctionnelle est expliquée par Détail de réservation.

Choisir une fenêtre temporelle fixe pour les nouvelles réservations

Utilisez pour chaque exécution une limite inférieure et supérieure fixe. Un exemple est time >= 2026-10-16T00:00:00Z et time < 2026-10-17T00:00:00Z. Ainsi, il est clair quelle exécution traite une réservation à la limite de jour. Transmettez les valeurs de date comme chaîne ISO-8601 avec fuseau horaire, par exemple Z pour UTC ou un décalage explicite. Convertissez les valeurs de date renvoyées pour les comparaisons dans le même fuseau horaire.

Le filtre temporel est défini avec filter, le champ time et expression. Les opérateurs utilisés ici sont >= et <. Les paramètres généralement visibles from et to ne sont pas un substitut au filtre de champ montré pour cette liste de réservations.

Faites chevaucher légèrement les récupérations successives si nécessaire, par exemple de cinq minutes. C'est une décision de votre intégration. Les réservations lues à nouveau doivent être mises à jour en fonction de leur identifiant. Un chevauchement ne remplace pas la synchronisation des réservations plus anciennes.

Requêter la première page avec filtre, champs et tri

L'exemple de JavaScript côté serveur suivant construit une requête de lecture pour la fenêtre temporelle fixe. edid et accessToken proviennent de votre authentification réussie. URLSearchParams prend en charge l'encodage URL des paramètres JSON.

const url = new URL('https://app2.edoobox.com/v2/booking/list');
url.searchParams.set('fields', JSON.stringify([
  'id', 'time', 'offer', 'owner', 'canceled', 'waiting_list'
]));
url.searchParams.set('filter', JSON.stringify([
  { property: 'time', expression: '>=', value: '2026-10-16T00:00:00Z' },
  { property: 'time', expression: '<', value: '2026-10-17T00:00:00Z' }
]));
url.searchParams.set('order', JSON.stringify([
  { property: 'time', value: 'ASC' },
  { property: 'id', value: 'ASC' }
]));
url.searchParams.set('limit', JSON.stringify({ start: 0, reply: 100 }));
url.searchParams.set('response_type', 'array');

const response = await fetch(url, {
  headers: { edid, Authorization: `Bearer ${accessToken}` }
});
if (!response.ok) throw new Error('Impossible de charger la page de réservations');
const page = await response.json();
if (page.error || !Array.isArray(page.data) || !page.limit) {
  throw new Error('Réponse de réservation non valide ou rejetée');
}
// Traiter page.data dans le système cible seulement à ce stade.
// Lire les pages suivantes avec le même filtre et un limit.start adapté.

fields est une liste de noms de champs JSON, filter une liste de conditions JSON et order une liste de champs de tri JSON. Le sens du tri est dans value. Plusieurs conditions de cette liste de filtres simple sont combinées avec ET. Maintenez le filtre et le tri lors du changement de page.

Le tri par time puis id ordonne également de manière unique les réservations avec le même horodatage. Sans tri explicite, la liste générale utilise l'identifiant en ordre croissant.

Traiter toutes les pages jusqu'au résultat complet

Une requête de liste fournit par défaut au maximum 100 entrées ; la taille de page maximale demandée est de 2000. limit.start est une position de départ à partir de 0, limit.reply la taille de page. Pour la deuxième page avec 100 entrées, utilisez {"start":100,"reply":100}.

  1. Vérifiez pour chaque page le statut HTTP, error, la plage de données attendue et les données de page.
  2. Traitez les réservations de data. Avec response_type=array, vous obtenez une liste ; par défaut, la plage de données est un objet avec les identifiants de réservation comme clés.
  3. Lisez les valeurs confirmées limit.start, limit.reply et limit.total de la réponse. total se rapporte à l'ensemble des résultats de la requête actuelle.
  4. Calculez la position suivante à partir de start + reply. Demandez-la avec les mêmes filtres tant qu'elle est inférieure à total.
  5. Si vous obtenez inattendument une page vide alors que des résultats supplémentaires sont signalés, ou des données de page contradictoires, interrompez l'exécution pour vérification.

L’échec de récupération d’une page ne constitue pas une fin réussie. Les données de pagination décrivent chaque requête ; une succession de requêtes ne garantit pas un instantané immuable. Conservez donc la fenêtre temporelle fixe, un ordre de tri non ambigu, la possibilité de répéter le traitement et la synchronisation complémentaire des données existantes.

Maîtriser le traitement en double et les interruptions

Enregistrez par environnement, compte et identifiant de réservation exactement une association à l'enregistrement cible. Si la même réservation est relue, mettez à jour cet enregistrement. Utilisez pour cela une association unique dans le système cible afin que deux traitements arrivant simultanément ne créent pas une deuxième réservation.

  1. Lisez l'état de traitement entièrement terminé le plus récent de votre propre base de données.
  2. Fixez la limite temporelle supérieure pour la nouvelle exécution une seule fois et utilisez-la sur toutes les pages.
  3. Lisez et traitez toutes les pages. Enregistrez la progression et les erreurs de manière à ce qu'une exécution interrompue puisse être répétée en toute sécurité.
  4. Ne déplacez le repère de traitement terminé enregistré vers la borne supérieure qu’après le traitement réussi de toutes les pages et de toutes les importations.

Si la page 3 échoue, par exemple, conservez le dernier repère de traitement terminé. Relancez l’exécution avec les mêmes bornes ; les enregistrements dont les identifiants ont déjà été importés sont actualisés. Organisez l’importation dans le système cible pour qu’une nouvelle récupération n’envoie pas une seconde confirmation, ne crée pas une seconde activité CRM et ne répète pas d’autres effets.

Synchroniser les modifications et annulations de réservations plus anciennes

Planifiez en plus une synchronisation régulière du stock dont votre système cible a encore besoin. Rechargez les identifiants de réservation stockés via GET /v2/booking/{id} ou lisez le stock nécessaire entièrement via la liste de réservations paginée. Reprenez les champs actuels au lieu de simplement ajouter de nouveaux identifiants.

N'excluez pas catégoriquement les réservations annulées lors de la synchronisation : un filtre sur les réservations exclusivement actives peut sinon empêcher qu'un enregistrement cible auparavant actif soit passé en annulé. Séparez également le statut de réservation, la liste d'attente, les positions de participants individuelles et les paiements sur le plan fonctionnel. L'indicateur d'annulation seul ne prouve pas un remboursement terminé.

Si une réservation précédemment connue est manquante, vérifiez le compte, les droits, les filtres et la récupération individuelle ciblée avant de déclencher une suppression ou une annulation dans le système cible. Notez les cas incertains pour traitement. La fréquence et le stock pris en compte dépendent de votre besoin fonctionnel et des capacités API disponibles.

Combiner les Webhooks avec la synchronisation REST

Le guide pour la configuration et l'exploitation des Webhooks vous guide à travers l'accès API, les sujets, la réception, la vérification de signature, le contrôle ultérieur et la désactivation. Utilisez-le conjointement avec la synchronisation REST décrite ici.

Pour les réservations, il existe par exemple les sujets post_Booking pour la création et put_Booking pour les modifications de réservation. Vérifiez pour votre processus les sujets réellement configurés et les événements reçus. Cela n'implique pas un engagement que chaque changement de statut fonctionnel imaginable génère un événement spécifique.

Faites aboutir le traitement des Webhooks et la synchronisation REST sur la même association de réservation stockée. Un événement peut déclencher une récupération ciblée de la réservation concernée. Traitez les mises à jour du même identifiant de manière coordonnée et lisez son état actuel afin qu'un événement plus ancien traité ultérieurement n'écrase pas un état plus récent.

Planifiez la synchronisation également pour les notifications en double, tardives ou absentes. Une livraison strictement unique, des intervalles de répétition fixes ou un ordre de livraison spécifique ne sont pas garantis par ce guide. La synchronisation de stock régulière reste partie de votre logique d'intégration.

Exemple d'application : Vue des réservations dans le CRM

Une organisation souhaite afficher de nouvelles réservations de cours dans le CRM et reprendre les annulations ultérieures. L'intégration effectue par exemple toutes les 15 minutes une récupération de nouvelles réservations. Elle démarre cinq minutes avant le dernier état de traitement terminé et utilise une limite supérieure fixée au début de l'exécution. Les deux intervalles sont des valeurs d'exploitation librement choisies.

  1. La première configuration lit le stock historique de réservations prévu sur toutes les pages et enregistre chaque identifiant de réservation avec son association CRM.
  2. Les fenêtres temporelles en cours ajoutent de nouvelles réservations. Les chevauchements mettent à jour les associations existantes.
  3. Un webhook approprié déclenche une récupération ciblée et la même mise à jour dans le CRM.
  4. Une réconciliation quotidienne du stock relit les réservations plus anciennes encore nécessaires. Ainsi, un enregistrement annulé aujourd'hui est également pris en compte, même si le moment de la réservation remonte à plusieurs semaines.
  5. L’échec d’une exécution génère une erreur à traiter, accompagnée du moment et de l’étape concernés. Le repère de traitement terminé n’est avancé qu’après une nouvelle exécution réussie.

Le résultat est une vue d'ensemble des réservations à jour avec un état de réconciliation traçable. Cette intégration ne génère ni une nouvelle réservation dans edoobox ni un remboursement par la lecture. Pour les rapprochements de paiement, sélectionnez également les ressources de facturation et de transaction appropriées.

Identifier les erreurs de réconciliation fréquentes

ObservationVérification
Toujours seulement 100 réservationsÉvaluer les données de page et lire d'autres positions de départ ; la première page n'est qu'un extrait.
Des annulations anciennes manquentVérifier le filtre de date de création et relire les réservations déjà connues.
Enregistrements CRM en doubleVérifier l'attribution unique à partir de l'environnement, du compte et de l'identifiant de réservation, ainsi que le traitement simultané.
Des réservations à la limite de la journée manquentVérifier les fuseaux horaires, la borne inférieure incluse, la borne supérieure exclue et le dernier repère de traitement entièrement terminé.
La plage de données ne peut pas être traitée comme une listeComparer response_type et le format de réponse attendu ; l'objet standard est organisé par identifiants.
L'accès est interrompu pendant l'exécutionVérifier la durée de vie du jeton, l'état de la clé et les droits de lecture ; corriger les erreurs et répéter à partir de l'état sauvegardé.

Tenez un journal de l'exécution, de la fenêtre temporelle, de la position de page et de la catégorie d'erreur. Les jetons, les clés secrètes et les réponses de réservation complètes contenant des données personnelles ne doivent pas figurer dans les journaux librement accessibles.

Guides associés