API et webhooks
Relier votre caisse ou votre logiciel à Apilow Réservation
Lisez les réservations d'un établissement, marquez les arrivées et recevez chaque événement en temps réel. Disponible avec le plan Premium ; clés et webhooks dans Paramètres › API et webhooks.
Authentification
Chaque requête porte une clé d'établissement dans l'en-tête Authorization: Bearer apk_…. Une clé « Lecture » lit ; une clé « Lecture et statut » peut aussi changer le statut d'une réservation. Limite : 120 requêtes par minute et par clé (réponse 429 au-delà).
curl https://reservation.apilow.com/api/v1/bookings?from=2026-10-16&to=2026-10-16 \
-H "Authorization: Bearer apk_…"Erreurs : { "error": { "code": "NOT_FOUND", "message": "…" } } avec le statut HTTP correspondant (400, 401, 403, 404, 409, 429).
Routes
Base : https://reservation.apilow.com/api/v1
| GET | /establishment | L'établissement de la clé (nom, adresse de la page, mode, fuseau horaire). |
| GET | /offerings | Les offres : prestations, services, séances, locations. |
| GET | /bookings?from=AAAA-MM-JJ&to=AAAA-MM-JJ | Réservations d'une période (31 jours au plus), par date et heure. Filtre facultatif : status=confirmed,arrived. |
| GET | /bookings?updatedSince=<ISO 8601> | Réservations créées ou modifiées depuis une date : synchronisation d'une caisse. limit=1 à 200 (100 par défaut) ; hasMore=true : relancez avec le dernier updatedAt reçu. |
| GET | /bookings/<id> | Une réservation. |
| POST | /bookings/<id>/status | Changer le statut (clé « Lecture et statut ») : {"status": "arrived" | "no_show" | "completed" | "confirmed"}. Mêmes règles que le cahier. |
L'objet réservation
- id, reference
- Identifiant et référence affichée au client.
- status
- requested, awaiting_payment, confirmed, arrived, completed, no_show, cancelled, declined, expired.
- start, end, serviceDate, time
- Début et fin (UTC, ISO 8601), date et heure locales.
- partySize, offeringId, resourceIds, noPreference
- Personnes, offre, collaborateur ou ressource.
- contact
- firstName, lastName, email, phone (E.164).
- customerNote, internalNote, answers
- Message du client, note interne, réponses au formulaire.
- source, channel
- online, widget, phone, walk_in… et origine précise (google, qr…).
- payment
- Empreinte ou acompte : kind, status, montants en centimes.
- group
- Panier ou rendez-vous à plusieurs prestations : reference, index, size.
- cancellation, createdAt, updatedAt
- Annulation (date, par qui, motif) et horodatages.
Webhooks
Apilow envoie un POST JSON à votre adresse (HTTPS) pour les événements choisis :
- booking.created
- booking.updated
- booking.cancelled
- booking.status_changed
Corps : { "id": "evt_…", "type": "booking.created", "created": "…", "establishmentId": "…", "data": { "booking": { … } } }. En-têtes : Apilow-Event, Apilow-Delivery (identifiant d'envoi, pour ignorer un doublon) et Apilow-Signature.
Répondez par un statut 2xx en moins de 10 secondes. Sinon, Apilow réessaie après 1 min, 5 min, 30 min, 2 h, 6 h, 12 h, puis abandonne après 7 tentatives (renvoi possible depuis Paramètres).
Vérifier la signature
Calculez un HMAC-SHA256 du texte <t>.<corps brut> avec le secret de l'adresse et comparez-le à v1 ; refusez un horodatage de plus de 5 minutes.
import crypto from "node:crypto";
// En-tête Apilow-Signature : "t=1760000000,v1=5f2b…"
function verify(secret, rawBody, header) {
const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
const expected = crypto.createHmac("sha256", secret).update(`${parts.t}.${rawBody}`).digest("hex");
const fresh = Math.abs(Date.now() / 1000 - Number(parts.t)) < 300;
return fresh && crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1));
}