Référence API

API de réservation

Listez et annulez les réservations d'un contact avec les endpoints de réservation OmniLab.

L'API de réservation permet à votre backend de lire et de gérer les réservations qu'un contact a effectuées sur une campagne OmniLab — par exemple pour alimenter une page de compte qui affiche les réservations à venir d'un client et lui permet de les annuler.

Tous les endpoints sont en serveur à serveur : demandez un jeton d'accès depuis votre propre backend, puis appelez OmniLab avec un jeton bearer. N'exposez jamais le secret client dans un navigateur, une page kiosque ou un bundle d'application mobile.

Les identifiants sont fournis par votre Customer Success Manager

Le client_id, le client_secret, l'audience et l'hôte API exact de chaque environnement ne sont pas en libre-service. Demandez-les à votre Customer Success Manager OmniLab et confirmez quels endpoints sont activés pour votre tenant.

URL de base et environnements

Chaque appel utilise le chemin de base /v1/ sur un hôte propre au tenant. L'hôte suit ce modèle, où <tenant> est la clé de votre tenant et <env> l'environnement :

EnvironnementModèle d'hôte API
Développementhttps://<tenant>.api.omnilab-dev.21-digital.com
Préproduction (UAT)https://<tenant>.api.omnilab-uat.21-digital.com
Productionhttps://<tenant>.api.omnilab-prod.21-digital.com

Gardez les identifiants de préproduction et de production séparés, et développez puis testez d'abord en préproduction. Voir URL de base et environnements pour les règles plus générales.

S'authentifier

Obtenez un jeton avec le flux client-credentials, puis envoyez-le en tant que Authorization: Bearer <token> sur chaque appel de l'API de réservation.

Demander un jeton d'accès
curl -X POST "https://<api-host>/v1/oauth:token" \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": "YOUR_CLIENT_ID",
    "client_secret": "YOUR_CLIENT_SECRET",
    "audience": "YOUR_AUDIENCE",
    "grant_type": "client_credentials"
  }'
Réponse du jeton
{
  "access_token": "YOUR_ACCESS_TOKEN",
  "token_type": "Bearer",
  "expires_in": 3600
}

Considérez expires_in comme la durée de vie du jeton en secondes : mettez le jeton en cache sur votre backend et renouvelez-le avant son expiration, ou après une réponse 401. Toutes les consignes sur les jetons figurent dans Authentification.

Concepts clés

Avant la référence des endpoints, trois notions expliquent comment les identifiants s'articulent.

Comment un contact est identifié

IdentifiantDe quoi il s'agitQui l'utilise
Identifiant externe (external_id)L'identifiant que votre propre système utilise déjà pour ce client. Vous le transmettez à OmniLab pour récupérer les réservations.Vous — c'est votre référence pour le contact.
Identifiant de contact (contacts/<uuid>)L'identifiant interne d'OmniLab pour cette même personne. OmniLab le résout à partir de votre identifiant externe.OmniLab en interne. Vous ne l'envoyez normalement jamais.
Clé publique (public_key)La clé publique d'une campagne (interaction). Elle apparaît dans les URL d'expérience et permet de restreindre une recherche à une seule campagne.Identifie la campagne, pas la personne.

En résumé : l'identifiant externe identifie la personne, et la clé publique identifie la campagne. Vous n'avez besoin de stocker que l'identifiant externe que vous possédez déjà.

Campagnes, touchpoints et identifiant d'activité

Une campagne dans OmniLab est une interaction, identifiée par sa public_key. Une interaction peut contenir une ou plusieurs activités réservables — aussi appelées touchpoints. Chaque réservation de la réponse porte un objet activity avec son propre id. Cet activity.id est l'identifiant du touchpoint, et c'est la clé pour distinguer les réservations lorsqu'une campagne comporte plusieurs activités réservables.

activity.id est unique au sein d'une campagne, pas entre campagnes — le même id peut apparaître sous deux campagnes différentes. Pour identifier un touchpoint de façon unique, utilisez activity.id avec la interaction.public_key de la campagne. Les deux cas d'usage ci-dessous le montrent en pratique.

L'identifiant de réservation et les statuts

Chaque réservation est identifiée par le champ booking — un identifiant unique (un UUID). Renvoyez cette valeur exacte pour annuler la réservation ; n'ajoutez pas de préfixe et ne la transformez pas.

Statut de réservationSignification
CONFIRMEDLa réservation est confirmée.
WAITLISTLe contact est sur liste d'attente pour un créneau complet.
CANCELLEDLa réservation a été annulée.

Endpoints

Lister les réservations d'un contact

GET /v1/interactions:fetchContactBookings

Renvoie toutes les réservations d'un contact, avec pagination et filtres optionnels.

Paramètres de requête

ParamètreRequisDescription
external_idOuiL'identifiant externe du contact dans votre système.
public_keysNonRestreindre à une seule campagne par sa clé publique. Une seule valeur est prise en charge. Ne peut pas être combiné avec interactions.
interactionsNonRestreindre à une seule campagne par son nom de ressource (interactions/<uuid>). Une seule valeur est prise en charge. Ne peut pas être combiné avec public_keys.
slot_date_range.fromNonBorne inférieure de l'heure de début du créneau, RFC 3339 (par exemple 2024-12-10T12:30:00Z).
slot_date_range.toNonBorne supérieure de l'heure de début du créneau, RFC 3339.
booking_statusNonFiltrer par statut. Répétez le paramètre pour combiner les valeurs (CONFIRMED, WAITLIST, CANCELLED).
languageNonCode de langue utilisé pour traduire le texte de la campagne dans la réponse.
page_sizeNonRésultats par page. Valeur par défaut 50.
page_numberNonPage à renvoyer, à partir de 1. Valeur par défaut 1.

Filtrer une campagne à la fois

Vous pouvez restreindre les résultats à une seule campagne avec public_keys ou interactions, mais pas les deux, et une seule valeur chacun. Omettez les deux pour renvoyer les réservations du contact sur toutes les campagnes.

Récupérer les réservations confirmées d'un contact
curl -X GET "https://<api-host>/v1/interactions:fetchContactBookings?external_id=9b33d8c1-64bd-4eff-b0e4-d2fb29ecbe83&booking_status=CONFIRMED&page_size=50&page_number=1" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Réponse

ChampTypeDescription
bookingstableauLes réservations du contact pour cette page.
page_numbernombreLa page renvoyée.
page_sizenombreRésultats par page.
total_countnombreTotal des réservations correspondant aux filtres.

Chaque réservation de bookings contient les champs ci-dessous. Consultez Formats et conventions des champs pour le format exact de chacun.

ChampTypeDescription
activityobjetLe touchpoint réservé, avec id (l'identifiant du touchpoint), title (nom localisé) et location_hint (texte de lieu localisé).
interactionobjetLa campagne, avec public_key et timezone (nom IANA, par exemple Europe/London).
groupobjetLa collection à laquelle appartient la campagne, avec unique_key et display_name.
slot_starting_atchaîneHeure de début du créneau, RFC 3339 en UTC (se termine par Z).
slot_duration_in_minutesentierDurée du créneau en minutes. Absent lorsque le créneau n'a pas de durée définie — voir ci-dessous.
booking_statuschaîneCONFIRMED, WAITLIST ou CANCELLED.
booked_atchaîneDate du statut actuel de la réservation (confirmation, liste d'attente ou annulation), RFC 3339 en UTC.
ticket_typeobjetLe billet réservé, avec display_name et has_limited_capacity.
hostobjetL'hôte précis avec lequel le contact a réservé, lorsque l'activité propose un choix d'hôtes (par exemple un poste ou un membre du personnel nommé), avec display_name. Le lieu figure dans activity.location_hint.
bookingchaîneL'identifiant unique de la réservation (un UUID). À transmettre tel quel à l'endpoint d'annulation.
Exemple de réponse (une réservation)
{
  "bookings": [
    {
      "activity": {
        "id": "b8b2a0e2-1f3c-4a7d-9c52-0c8f2d1a6e44",
        "title": "Santa Photo Experience",
        "location_hint": "Niveau 1, près de la fontaine"
      },
      "interaction": {
        "public_key": "winter-festival",
        "timezone": "Europe/London"
      },
      "group": {
        "unique_key": "example-brand",
        "display_name": "Example Brand"
      },
      "slot_starting_at": "2024-12-10T12:30:00Z",
      "slot_duration_in_minutes": 30,
      "booking_status": "CONFIRMED",
      "booked_at": "2024-12-01T09:15:00Z",
      "ticket_type": {
        "display_name": "Entrée standard",
        "has_limited_capacity": true
      },
      "host": {
        "display_name": "Photo Station 2"
      },
      "booking": "2394d604-afcc-4f7f-98c1-ef3676c20d6b"
    }
  ],
  "page_number": 1,
  "page_size": 50,
  "total_count": 1
}

Formats et conventions des champs

ChampFormat et comportement
slot_starting_atHorodatage RFC 3339 en UTC, se terminant par Z (par exemple 2024-12-10T12:30:00Z).
slot_duration_in_minutesMinutes (entier), issues de la configuration du créneau réservé (la durée de l'hôte choisi, ou celle de l'activité s'il n'y a pas de choix d'hôte). Absent de la réponse lorsque le créneau n'a pas de durée définie — jamais fixée à 60 par défaut, typez-le donc comme optionnel.
booked_atHorodatage RFC 3339 en UTC. Contient la date du statut actuel : confirmation pour CONFIRMED, liste d'attente pour WAITLIST, annulation pour CANCELLED.
booking_statusUne valeur parmi CONFIRMED, WAITLIST ou CANCELLED.
interaction.timezoneNom de fuseau IANA (par exemple Europe/London), pas un décalage. Convertissez-y les heures de créneau UTC pour afficher au contact son heure locale.
activity.title, activity.location_hintChaînes localisées dans la langue résolue de la campagne. Cas limite : lorsque la langue choisie ou la langue par défaut n'a pas de valeur pour ce champ, vous pouvez recevoir à la place une map de langues sérialisée en chaîne, par exemple {"fr":"…"}. Parsez de façon défensive — si la valeur se parse comme un objet JSON, prenez l'entrée de votre langue ou la première disponible.
language (paramètre de requête)Code de langue de base comme en ou fr (les sous-balises régionales comme fr-CA sont réduites à fr). Omettez-le, ou passez une langue que la campagne ne propose pas, et OmniLab renvoie la langue par défaut de la campagne.

Envoyez aussi les filtres slot_date_range.from et slot_date_range.to en RFC 3339, en UTC.

Annuler une réservation

POST /v1/interactions:cancelInteractionBooking

Annule une réservation et ses billets. Transmettez la valeur booking renvoyée par l'appel de récupération, telle quelle.

ChampRequisDescription
bookingOuiL'identifiant de la réservation, exactement tel que renvoyé dans le champ booking de fetchContactBookings (un UUID, sans préfixe).
Annuler une réservation
curl -X POST "https://<api-host>/v1/interactions:cancelInteractionBooking" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "booking": "82ce03a0-939e-423f-811d-0345eacdc137"
  }'

Une annulation réussie renvoie un objet JSON vide ({}).

Cas d'usage

Campagne avec un seul touchpoint d'activité

Lorsqu'une campagne n'a qu'une seule activité réservable, toutes les réservations de la réponse partagent le même activity.id. Vous pouvez lister les réservations directement sans regroupement — chaque ligne est simplement un créneau que le contact a réservé pour cette activité.

Campagne avec plusieurs touchpoints d'activité

Lorsqu'une campagne propose plusieurs activités réservables (par exemple une photo avec le Père Noël et un atelier créatif dans la même campagne d'hiver), chaque réservation porte l'activity.id du touchpoint auquel elle appartient. Utilisez activity.id pour regrouper ou étiqueter les réservations par activité, afin que le client voie « Santa Photo Experience » et « Atelier créatif » comme des lignes distinctes plutôt qu'une liste à plat. Le champ activity.title fournit une étiquette prête à l'emploi pour chaque groupe.

Afficher les réservations sur une page de compte

Un flux typique de page de compte :

Récupérer les réservations confirmées du contact

Sur votre backend, appelez fetchContactBookings avec l'external_id du client et booking_status=CONFIRMED. Parcourez les pages si total_count dépasse votre page_size.

Regrouper et afficher la liste

Regroupez les réservations par campagne (interaction.public_key) et par touchpoint (activity.id) — rappelez-vous que activity.id se répète entre campagnes. Affichez chaque créneau avec slot_starting_at, slot_duration_in_minutes, ticket_type.display_name et host.display_name, et affichez chaque heure dans interaction.timezone.

Proposer « Annuler »

Demandez au client de confirmer, appelez cancelInteractionBooking avec la valeur booking, puis rafraîchissez la liste pour que le créneau annulé disparaisse.

Collections Postman

OmniLab maintient une collection Postman par environnement (Développement, Préproduction/UAT et Production) couvrant tous les endpoints ci-dessus. Demandez la collection de votre environnement à votre Customer Success Manager.

Ne jamais committer d'identifiants

Les collections sont livrées avec des identifiants fictifs uniquement. Utilisez le client_id, le client_secret et l'audience que votre Customer Success Manager vous fournit, stockez-les dans un gestionnaire de secrets, et tenez-les hors du contrôle de version et des liens partagés.

Bonnes pratiques

  • Effectuez l'échange de jeton sur votre backend et appelez l'API de réservation en serveur à serveur.
  • Mettez le jeton d'accès en cache et renouvelez-le avant l'écoulement de expires_in ou après un 401.
  • Envoyez les filtres de date (slot_date_range.from / slot_date_range.to) en UTC.
  • Affichez les heures de créneau dans interaction.timezone, qui est un nom de fuseau IANA.
  • Demandez confirmation au client avant d'annuler, puis rafraîchissez la liste.
  • Gérez sereinement un tableau bookings vide — un contact peut n'avoir aucune réservation.

Articles liés

Cette page vous a-t-elle aidé ?

Un commentaire optionnel nous aide à améliorer cette page pour les prochains auteurs et lecteurs.

Sur cette page