Documentation développeur

API REST TapTime

Lisez et mettez à jour les réservations de tables et les rendez-vous, lisez les commandes et les cartes de fidélité, interrogez le flux d’événements ordonné et recevez des webhooks signés — depuis votre propre CRM, votre caisse, votre entrepôt de données ou une plateforme d’automatisation. Cette page est la référence complète ; le guide du suivi des conversions explique pourquoi l’utiliser.

URL de basehttps://api.tapti.me AuthentificationBearer token FormatJSON Pourquoi l’utiliser

Chaque requête nécessite une clé API de l’entreprise (Intégrations → Webhooks et API dans le panneau de gestion), envoyée sous la forme Authorization: Bearer tt_live_…. Les réponses et les erreurs sont au format JSON.

Réservations confirmées modifiées depuis une date
curl "https://api.tapti.me/v1/company/reservations?status=confirmed&updatedSince=2026-09-01T00:00:00Z" \
  -H "Authorization: Bearer tt_live_…"

Authentification

Chaque requête transporte une clé API de l’entreprise sous forme de jeton Bearer. Créez-en une depuis le panneau de gestion — Intégrations → Webhooks et API → Clés API REST — où elle n’est affichée qu’une seule fois et n’est conservée côté serveur que sous forme de hachage SHA-256 ; une clé perdue est révoquée et remplacée, jamais récupérée. Une entreprise peut détenir jusqu’à 10 clés actives.

  • Les clés en lecture seule peuvent appeler tous les endpoints GET, ainsi qu’abonner et désabonner des webhooks — un abonnement ne transmet rien que la clé ne pourrait déjà lire.
  • Les clés en lecture-écriture peuvent en outre envoyer un changement de statut de réservation en POST ; une clé en lecture seule reçoit 403 Forbidden sur ces routes.
  • Une clé appartient à une seule entreprise — chaque liste et chaque consultation y sont déjà restreintes, il n’existe pas de paramètre companyId.

Limites de débit

50 requêtes par minute et par clé, sur une fenêtre glissante, partagées entre tous les endpoints. Un dépassement renvoie 429 Too Many Requests ; patientez et réessayez plutôt que d’interroger plus vite — ou abonnez un webhook et cessez d’interroger.

Endpoints

GET /v1/company Lecture seule ou lecture-écriture

Obtenir l’entreprise courante

L’entreprise à laquelle appartient la clé, et ce que la clé elle-même peut faire.

GET /v1/company/reservations Lecture seule ou lecture-écriture

Lister les réservations

Les réservations de tables de l’entreprise, de l’heure de début la plus ancienne à la plus récente — ou, lorsque updatedSince est défini, de la mise à jour la plus ancienne à la plus récente.

ParamètreTypeSignification
status chaîne Séparés par des virgules : pending, confirmed, seated, completed, no_show, cancelled. cancelled correspond aux deux motifs d’annulation.
branchId entier Restreindre à un établissement.
from date et heure ISO 8601 Uniquement les réservations commençant à cette heure ou après (UTC si aucun décalage n’est indiqué).
to date et heure ISO 8601 Uniquement les réservations commençant avant cette heure.
updatedSince date et heure ISO 8601 Uniquement les réservations modifiées depuis cette heure ; trie par updatedAt croissant, pour la synchronisation.
limit entier Taille de page, 1–100. Par défaut 50.
page entier Numéro de page, à partir de 1. Par défaut 1.
GET /v1/company/appointments Lecture seule ou lecture-écriture

Lister les rendez-vous

Même format et mêmes filtres que les réservations, pour le module Rendez-vous.

ParamètreTypeSignification
status chaîne Séparés par des virgules : pending, confirmed, completed, no_show, cancelled.
branchId entier Restreindre à un établissement.
from date et heure ISO 8601 Uniquement les réservations commençant à cette heure ou après.
to date et heure ISO 8601 Uniquement les réservations commençant avant cette heure.
updatedSince date et heure ISO 8601 Uniquement les réservations modifiées depuis cette heure ; trie par updatedAt croissant.
limit entier Taille de page, 1–100. Par défaut 50.
page entier Numéro de page, à partir de 1. Par défaut 1.
GET /v1/company/reservations/{id} Lecture seule ou lecture-écriture

Obtenir une réservation

Une réservation, au même format que celui des webhooks, avec son attribution. 404 lorsque l’id n’appartient pas à l’entreprise de la clé.

GET /v1/company/appointments/{id} Lecture seule ou lecture-écriture

Obtenir un rendez-vous

Un rendez-vous, avec le même format et les mêmes règles que la consultation d’une réservation.

POST /v1/company/reservations/{id}/status Lecture-écriture uniquement

Modifier le statut d’une réservation

Confirmer, installer, terminer, marquer comme non-présentation, annuler ou rouvrir — déclenche les mêmes webhooks et conversions qu’une modification sur le tableau. Corps JSON : {"status": "..."}.

ParamètreTypeSignification
status chaîne, obligatoire L’une des valeurs : pending, confirmed, seated, completed, no_show, cancelled (canceled et canceled_by_venue sont également acceptés).
POST /v1/company/appointments/{id}/status Lecture-écriture uniquement

Modifier le statut d’un rendez-vous

Identique à l’endpoint des réservations, sans l’état seated.

ParamètreTypeSignification
status chaîne, obligatoire L’une des valeurs : pending, confirmed, completed, no_show, cancelled (canceled et canceled_by_venue sont également acceptés).
GET /v1/company/events Lecture seule ou lecture-écriture

Interroger le flux d’événements

Chaque événement de réservation, de commande et de fidélité, du plus ancien au plus récent — le flux même dont sont issus les webhooks. Passez le dernier curseur reçu dans after pour ne récupérer que les nouveautés, et type pour ne récupérer que certaines catégories.

ParamètreTypeSignification
after curseur entier Le curseur du dernier événement traité. Omettez-le pour commencer depuis le début.
type chaîne Types ou familles d’événements séparés par des virgules : booking.confirmed,order.placed, ou order, loyalty.*. Omettez-le pour recevoir tous les événements.
limit entier Taille de page, 1–100. Par défaut 50.
GET /v1/company/orders Lecture seule ou lecture-écriture

Lister les commandes

Les commandes des clients à table, à emporter et en livraison, ainsi que chaque vente enregistrée en caisse, de la plus ancienne à la plus récente — ou, lorsque paidSince est défini, dans l’ordre de leur paiement. Une commande encore en attente de son paiement préalable est exclue.

ParamètreTypeSignification
status chaîne Séparés par des virgules : open, paid.
source chaîne customer (passée par le client) ou staff (enregistrée par le personnel).
fulfilment chaîne Séparés par des virgules : dine_in, takeaway, delivery.
branchId entier Restreindre à un établissement.
from date et heure ISO 8601 Uniquement les commandes créées à cette heure ou après.
to date et heure ISO 8601 Uniquement les commandes créées avant cette heure.
paidSince date et heure ISO 8601 Uniquement les commandes payées depuis cette heure ; trie par paidAt croissant, pour synchroniser les ventes.
limit entier Taille de page, 1–100. Par défaut 50.
page entier Numéro de page, à partir de 1. Par défaut 1.
GET /v1/company/orders/{id} Lecture seule ou lecture-écriture

Obtenir une commande

Une commande avec ses lignes, ses totaux et son attribution, au format des webhooks de commande.

GET /v1/company/loyalty/programs Lecture seule ou lecture-écriture

Lister les programmes de fidélité

Chaque programme de carte à tampons : nom, statut, nombre de tampons requis, récompense et lieux où il s’applique.

GET /v1/company/loyalty/cards Lecture seule ou lecture-écriture

Lister les cartes de fidélité

Les cartes des membres, au format de l’objet fidélité. Un membre qui a rempli une carte la voit passer à completed, avec une nouvelle carte active à côté ; customer.id désigne le membre.

ParamètreTypeSignification
programId entier Restreindre à un programme.
customerId entier Restreindre à un membre.
status chaîne Séparés par des virgules : active, completed.
updatedSince date et heure ISO 8601 Uniquement les cartes tamponnées ou complétées depuis cette heure ; trie par updatedAt croissant.
limit entier Taille de page, 1–100. Par défaut 50.
page entier Numéro de page, à partir de 1. Par défaut 1.
GET /v1/company/loyalty/rewards Lecture seule ou lecture-écriture

Lister les récompenses de fidélité

Les récompenses obtenues en complétant une carte, avec leur code, leur date d’expiration et l’indication de leur utilisation.

ParamètreTypeSignification
programId entier Restreindre à un programme.
customerId entier Restreindre à un membre.
status chaîne Séparés par des virgules : issued, redeemed, expired.
from date et heure ISO 8601 Uniquement les récompenses émises à cette heure ou après.
to date et heure ISO 8601 Uniquement les récompenses émises avant cette heure.
limit entier Taille de page, 1–100. Par défaut 50.
page entier Numéro de page, à partir de 1. Par défaut 1.
GET /v1/company/webhooks Lecture seule ou lecture-écriture

Lister les abonnements webhook

Les abonnements créés par cette clé. Les webhooks ajoutés dans le panneau de gestion n’y figurent pas.

POST /v1/company/webhooks Lecture seule ou lecture-écriture

Abonner un webhook

Commence à envoyer des événements à une URL — c’est ce qu’appelle l’application d’une plateforme d’automatisation lorsqu’un utilisateur active un déclencheur. Renvoie l’abonnement et son secret de signature, une seule fois. Corps JSON : {"url": "…", "events": ["order.placed"]} ; le format de Zapier {"target_url": "…", "event": "…"} est également accepté.

ParamètreTypeSignification
url chaîne, obligatoire L’adresse https de destination (target_url est également accepté).
events tableau de chaînes, obligatoire Types d’événements, familles telles que order.* ou loyalty, ou * pour tout recevoir (event est également accepté, pour un seul).
description chaîne Un nom affiché dans le panneau de gestion. Par défaut, la plateforme et le nom de la clé.
DELETE /v1/company/webhooks/{id} Lecture seule ou lecture-écriture

Désabonner un webhook

Cesse l’envoi vers un abonnement créé par cette clé. Renvoie 204. La révocation de la clé supprime également tous ses abonnements.

L’objet réservation

Une réservation de table et un rendez-vous sont renvoyés dans un format commun : kind, id, status, source, guestInitiated, startsAt/endsAt/timezone (le fuseau horaire propre à l’établissement), currency, company, branch, guest, attribution, conversionId, createdAt/updatedAt — plus partySize et table pour une réservation, service et specialist pour un rendez-vous. C’est exactement ce que livre un webhook : un récepteur qui gère l’un gère l’autre.

GET /v1/company/reservations/4821 → data
{
  "data": {
    "kind": "reservation",
    "id": 4821,
    "status": "confirmed",
    "source": "online",
    "guestInitiated": true,
    "startsAt": "2026-09-12T20:00:00+03:00",
    "endsAt": "2026-09-12T21:30:00+03:00",
    "timezone": "Asia/Baku",
    "currency": "AZN",
    "company": { "id": 12, "name": "Cafe Aroma", "slug": "cafe-aroma", "country": "AZ" },
    "branch": { "id": 3, "name": "Nizami st." },
    "partySize": 4,
    "table": { "id": 9, "label": "T3" },
    "guest": { "name": "Maria K.", "phone": "…", "email": "…" },
    "locale": "en",
    "note": null,
    "conversionId": "tt3f9c…",
    "createdAt": "2026-09-10T08:12:04+00:00",
    "updatedAt": "2026-09-12T20:00:03+00:00",
    "attribution": { "channel": "widget", "utmSource": "instagram", "gclid": null, "fbclid": "IwAR2…" }
  }
}

L’objet commande

Une commande se présente sous un format unique où que vous la rencontriez — l’API REST, les webhooks de commande, le flux d’événements : kind ("order"), id, number (le numéro de ticket annoncé par le personnel), status (open ou paid), source (customer ou staff), guestInitiated, fulfilment, table, label, deliveryAddress, note, currency, timezone, company, branch, customer (le membre fidélité, lorsque le personnel l’a identifié), items (name, variant, quantity, unitPriceCents, subtotalCents), itemCount, subtotalCents, discountCents, deliveryFeeCents, tipCents, totalCents, valueCents (la valeur de la commande hors pourboire — le montant que rapportent les conversions), paymentMethod, servedBy, conversionId, createdAt, paidAt et attribution. Les montants sont toujours exprimés en unités mineures.

GET /v1/company/orders/9170 → data
{
  "data": {
    "kind": "order",
    "id": 9170,
    "number": 42,
    "status": "paid",
    "source": "customer",
    "guestInitiated": true,
    "fulfilment": "takeaway",
    "table": null,
    "label": "Ana",
    "currency": "EUR",
    "branch": { "id": 3, "name": "Vitosha Blvd" },
    "customer": { "id": 311, "name": "Ana", "phone": "…" },
    "items": [
      { "menuItemId": 88, "name": "Flat white", "variant": "Large",
        "quantity": 2, "unitPriceCents": 450, "subtotalCents": 900 }
    ],
    "itemCount": 2,
    "subtotalCents": 900,
    "discountCents": 0,
    "deliveryFeeCents": 0,
    "tipCents": 100,
    "totalCents": 1000,
    "valueCents": 900,
    "paymentMethod": "online",
    "conversionId": "tt81ad…",
    "createdAt": "2026-09-12T12:04:10+03:00",
    "paidAt": "2026-09-12T12:05:02+03:00",
    "attribution": { "channel": "web", "utmSource": "google", "gclid": "Cj0K…" }
  }
}

L’objet fidélité

Chaque événement, carte et récompense de fidélité partage un format unique : kind ("loyalty"), id (la carte), timezone, company, branch (le lieu de l’événement, s’il y en a un), program (id, name, stampsRequired, rewardTitle), customer (id, name, phone, locale), card (id, status, stampsCount, stampsRequired, stampsToReward, createdAt), stamp (pour un tampon : source, issuedBy, createdAt) et reward (pour une récompense : code, title, status, expiresAt, redeemedAt, redeemedBy), plus conversionId, l’identifiant sous lequel une inscription au programme de fidélité est rapportée.

GET /v1/company/loyalty/cards → data[0]
{
  "kind": "loyalty",
  "id": 5120,
  "program": { "id": 4, "name": "Coffee card", "stampsRequired": 8, "rewardTitle": "Free coffee" },
  "customer": { "id": 311, "name": "Ana", "phone": "…", "locale": "bg" },
  "card": { "id": 5120, "status": "active", "stampsCount": 5,
            "stampsRequired": 8, "stampsToReward": 3 },
  "branch": { "id": 3, "name": "Vitosha Blvd" },
  "stamp": { "source": "qr_scan", "issuedBy": "Ivan", "createdAt": "…" },
  "reward": null,
  "conversionId": "tt5c02…"
}

Flux d’événements

Chaque ligne a la forme { id, cursor, type, createdAt, previousStatus, data }. data contient le sujet sous la clé indiquée par le préfixe de l’événement : data.booking, data.order ou data.loyalty. Conservez le cursor le plus élevé que vous avez traité et renvoyez-le dans after — il ne saute ni ne répète jamais une ligne, vous pouvez donc reprendre sans risque après une panne. Ignorez les types que vous ne gérez pas : de nouveaux types peuvent être ajoutés.

Type d’événementSignification
booking.requestedUn client a demandé une réservation qui attend votre confirmation.
booking.confirmedUne réservation est confirmée — créée directement confirmée, ou confirmée ultérieurement par le personnel.
booking.cancelledAnnulée par le client ou par l’établissement ; status indique lequel.
booking.no_showLe client ne s’est pas présenté.
booking.completedLa visite est terminée.
order.placedLa commande d’un client est arrivée à l’établissement — depuis la page, le code QR d’une table, à emporter ou en livraison ; après le paiement lorsque l’établissement l’encaisse d’avance.
order.paidToute commande réglée, y compris les ventes enregistrées en caisse.
loyalty.member_joinedUn client a reçu son premier tampon dans un programme.
loyalty.stamp_addedUn tampon a été ajouté à une carte.
loyalty.reward_issuedUne carte a été complétée et sa récompense émise.
loyalty.reward_redeemedUne récompense a été remise.
Restez synchronisé avec le flux d’événements
curl "https://api.tapti.me/v1/company/events?after=998&limit=100" \
  -H "Authorization: Bearer tt_live_…"

Webhooks

Créez un endpoint dans Intégrations → Webhooks et API — ou connectez Zapier, Make, n8n ou Pipedream dans Intégrations → Automatisation — pour que TapTime envoie en POST un événement JSON signé dès qu’une réservation, une commande ou une carte de fidélité change. Vous choisissez les événements pour chaque endpoint. Une entreprise peut disposer au total de 50 webhooks, postbacks, chats et connexions d’automatisation.

En-têteSignification
TapTime-EventLe type d’événement, par ex. booking.confirmed.
TapTime-Event-IdIdentifiant stable de l’événement — utilisez-le pour dédoublonner une livraison réessayée.
TapTime-DeliveryIdentifiant de cette tentative de livraison précise.
TapTime-Signaturet=<unix time>,v1=<hex HMAC-SHA256 de "t.rawBody">, signé avec le secret propre à l’endpoint.
  • Toute réponse 2xx est considérée comme livrée ; une réponse non 2xx ou un délai dépassé est réessayé avec un intervalle croissant (1 min, 5 min, 15 min, 1 h, 3 h, 6 h, 12 h) jusqu’à 8 tentatives — une réponse 410 arrête les nouvelles tentatives.
  • Les redirections ne sont pas suivies.
  • L’URL doit être en HTTPS en production et ne peut pas pointer vers une adresse privée ou de bouclage.
  • La livraison est garantie au moins une fois : vérifiez toujours la signature et dédoublonnez sur TapTime-Event-Id.
POST · application/json · booking.confirmed
{
  "id": "evt_9f3c2a7e1b",
  "type": "booking.confirmed",
  "createdAt": "2026-09-12T19:02:11+03:00",
  "test": false,
  "data": { "booking": { "kind": "reservation", "id": 4821, "status": "confirmed", "…": "…" } }
}
Vérifier la signature (Node.js)
const [t, v1] = req.headers["taptime-signature"]
  .split(",").map(part => part.split("=")[1]);
const expected = crypto
  .createHmac("sha256", process.env.TAPTIME_WEBHOOK_SECRET)
  .update(`${t}.${rawBody}`)
  .digest("hex");
const valid = crypto.timingSafeEqual(
  Buffer.from(expected), Buffer.from(v1));

Abonnements webhook

Les plateformes d’automatisation activent et désactivent les déclencheurs via l’API au lieu de demander à l’utilisateur de coller une URL (« REST hooks ») : envoyez en POST l’URL propre à la plateforme avec les événements souhaités, conservez l’id renvoyé, et supprimez-le avec DELETE lorsque le déclencheur est désactivé. Un abonnement est un webhook signé ordinaire — il apparaît dans le panneau de gestion, marqué de la clé qui l’a créé.

  • Une clé ne voit et ne supprime que les abonnements qu’elle a créés ; la révocation de la clé les supprime tous.
  • Les adresses sur hooks.zapier.com, make.com et pipedream.net sont reconnues et affichées avec le nom de la plateforme ; toute autre adresse https est un webhook classique.
  • Le secret de signature est renvoyé une seule fois, dans la réponse au POST ; le propriétaire peut l’afficher à nouveau dans le panneau de gestion.
Abonner une URL aux nouvelles commandes
curl -X POST "https://api.tapti.me/v1/company/webhooks" \
  -H "Authorization: Bearer tt_live_…" -H "Content-Type: application/json" \
  -d '{"url": "https://hooks.zapier.com/hooks/catch/123/abc/", "events": ["order.placed"]}'

Postbacks

Une requête GET ou POST vers l’URL de votre propre outil de suivi avec les macros remplies, pour les plateformes qui utilisent des postbacks par chaîne de requête plutôt que des webhooks JSON. Pour une commande, {value} correspond à la valeur de la commande hors pourboire et {order_id} à son identifiant.

URL de postback avec variables · GET ou POST
https://tracker.example/postback
  ?cid={click_id}&event={event}&status={status}
  &payout={value}&cur={currency}

Variables disponibles

  • {event}
  • {event_id}
  • {status}
  • {booking_id}
  • {booking_type}
  • {order_id}
  • {customer_id}
  • {conversion_id}
  • {value}
  • {currency}
  • {party_size}
  • {branch_id}
  • {timestamp}
  • {utm_source}
  • {utm_medium}
  • {utm_campaign}
  • {utm_term}
  • {utm_content}
  • {gclid}
  • {fbclid}
  • {msclkid}
  • {ttclid}
  • {click_id}

Erreurs

Chaque erreur est renvoyée en JSON : { "error": "<code>", "message": "<texte lisible>" }.

StatuterreurSignification
401 unauthorized L’en-tête Authorization est absent, ou la clé est invalide ou révoquée.
403 forbidden Une clé en lecture seule a appelé un endpoint d’écriture (un changement de statut).
404 not_found Aucune réservation portant cet id n’appartient à l’entreprise de la clé.
409 conflict Le changement de statut provoquerait une double réservation de la table ou du créneau ; rien n’a été modifié.
422 invalid_status La valeur status du corps ne fait pas partie des valeurs acceptées pour ce type de réservation.
422 invalid_type Le paramètre type du flux d’événements ne désigne aucun type ni aucune famille d’événements.
422 invalid_url L’URL d’un abonnement n’est pas une adresse https publique.
429 rate_limited Plus de 50 requêtes en une minute pour cette clé. Ralentissez et réessayez.
Besoin d’une clé ?

L’accès à l’API, les webhooks ainsi que les intégrations d’automatisation et de chat sont inclus avec chaque module — sans frais supplémentaires ni formule développeur distincte.

Commencer l’essai gratuit