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 :
| Environnement | Modèle d'hôte API |
|---|---|
| Développement | https://<tenant>.api.omnilab-dev.21-digital.com |
| Préproduction (UAT) | https://<tenant>.api.omnilab-uat.21-digital.com |
| Production | https://<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.
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"
}'{
"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é
| Identifiant | De quoi il s'agit | Qui 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éservation | Signification |
|---|---|
CONFIRMED | La réservation est confirmée. |
WAITLIST | Le contact est sur liste d'attente pour un créneau complet. |
CANCELLED | La réservation a été annulée. |
Endpoints
Lister les réservations d'un contact
GET /v1/interactions:fetchContactBookingsRenvoie toutes les réservations d'un contact, avec pagination et filtres optionnels.
Paramètres de requête
| Paramètre | Requis | Description |
|---|---|---|
external_id | Oui | L'identifiant externe du contact dans votre système. |
public_keys | Non | Restreindre à une seule campagne par sa clé publique. Une seule valeur est prise en charge. Ne peut pas être combiné avec interactions. |
interactions | Non | Restreindre à 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.from | Non | Borne inférieure de l'heure de début du créneau, RFC 3339 (par exemple 2024-12-10T12:30:00Z). |
slot_date_range.to | Non | Borne supérieure de l'heure de début du créneau, RFC 3339. |
booking_status | Non | Filtrer par statut. Répétez le paramètre pour combiner les valeurs (CONFIRMED, WAITLIST, CANCELLED). |
language | Non | Code de langue utilisé pour traduire le texte de la campagne dans la réponse. |
page_size | Non | Résultats par page. Valeur par défaut 50. |
page_number | Non | Page à 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.
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
| Champ | Type | Description |
|---|---|---|
bookings | tableau | Les réservations du contact pour cette page. |
page_number | nombre | La page renvoyée. |
page_size | nombre | Résultats par page. |
total_count | nombre | Total 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.
| Champ | Type | Description |
|---|---|---|
activity | objet | Le touchpoint réservé, avec id (l'identifiant du touchpoint), title (nom localisé) et location_hint (texte de lieu localisé). |
interaction | objet | La campagne, avec public_key et timezone (nom IANA, par exemple Europe/London). |
group | objet | La collection à laquelle appartient la campagne, avec unique_key et display_name. |
slot_starting_at | chaîne | Heure de début du créneau, RFC 3339 en UTC (se termine par Z). |
slot_duration_in_minutes | entier | Durée du créneau en minutes. Absent lorsque le créneau n'a pas de durée définie — voir ci-dessous. |
booking_status | chaîne | CONFIRMED, WAITLIST ou CANCELLED. |
booked_at | chaîne | Date du statut actuel de la réservation (confirmation, liste d'attente ou annulation), RFC 3339 en UTC. |
ticket_type | objet | Le billet réservé, avec display_name et has_limited_capacity. |
host | objet | L'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. |
booking | chaîne | L'identifiant unique de la réservation (un UUID). À transmettre tel quel à l'endpoint d'annulation. |
{
"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
| Champ | Format et comportement |
|---|---|
slot_starting_at | Horodatage RFC 3339 en UTC, se terminant par Z (par exemple 2024-12-10T12:30:00Z). |
slot_duration_in_minutes | Minutes (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_at | Horodatage RFC 3339 en UTC. Contient la date du statut actuel : confirmation pour CONFIRMED, liste d'attente pour WAITLIST, annulation pour CANCELLED. |
booking_status | Une valeur parmi CONFIRMED, WAITLIST ou CANCELLED. |
interaction.timezone | Nom 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_hint | Chaî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:cancelInteractionBookingAnnule une réservation et ses billets. Transmettez la valeur booking renvoyée par l'appel de récupération, telle quelle.
| Champ | Requis | Description |
|---|---|---|
booking | Oui | L'identifiant de la réservation, exactement tel que renvoyé dans le champ booking de fetchContactBookings (un UUID, sans préfixe). |
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_inou après un401. - 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
bookingsvide — un contact peut n'avoir aucune réservation.
Articles liés
Authentification
Demandez et réutilisez le jeton d'accès machine à machine.
URL de base et environnements
Gardez les hôtes et identifiants de préproduction et de production séparés.
Patterns d'intégration courants
Voyez comment le flux de réservation s'intègre aux patterns CRM et analytics.
Accéder aux réservations et aux billets
Gérez les mêmes réservations depuis le Studio OmniLab.