API caisse
Votre logiciel de caisse crée le numéro du client avec le n° de facture, puis le marque « prêt » : le téléphone du client sonne, l'écran TV l'annonce. Aucune intégration n'est nécessaire pour commencer (le QR du comptoir suffit).
1. Authentification
Dans Tableau de bord → 5. API, cliquez « Khle9 clé API ». La clé (3ey_…) n'est affichée qu'une fois. Envoyez-la dans chaque requête, côté serveur uniquement :
Authorization: Bearer 3ey_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
2. Créer un numéro
external_ref (facultatif, 1–64 caractères) = votre n° de facture. Si un ticket en cours a déjà cette référence, il est renvoyé tel quel (created: false) : vous pouvez réessayer sans créer de doublon.
curl -X POST https://3eyetlia.com/api/v1/tickets \
-H "Authorization: Bearer $CLE" -H "Content-Type: application/json" \
-d '{"external_ref": "F-1042"}'
→ 201
{ "created": true,
"data": { "id": "…", "number": 27, "status": "waiting", "external_ref": "F-1042",
"url": "https://3eyetlia.com/t/…", … } }Donnez data.url au client (QR imprimé sur le ticket de caisse, SMS, WhatsApp…) : c'est sa page avec son numéro et le bouton d'alerte.
3. Changer le statut
{ref} = l'id du ticket ou votre external_ref.
POST /api/v1/tickets/{ref}/ready # prêt : le téléphone sonne
POST /api/v1/tickets/{ref}/undo # annuler « prêt » (erreur)
POST /api/v1/tickets/{ref}/done # remis au client
POST /api/v1/tickets/{ref}/cancel # annulé
curl -X POST https://3eyetlia.com/api/v1/tickets/F-1042/ready -H "Authorization: Bearer $CLE"GET /api/v1/tickets # tickets en cours (waiting / ready)
GET /api/v1/tickets/{ref} # un ticket4. Webhooks
Indiquez une URL https dans le tableau de bord. Nous envoyons un POST JSON à chaque événement :
ticket.created,ticket.ready,ticket.waiting,ticket.done,ticket.cancelledticket.seen: le client a vu « prêt » sur son téléphoneticket.seen: la page du client était affichée après « prêt » (ne prouve pas une lecture)ticket.acked: le client a touché « Compris, j'arrive » (confirmation volontaire)test: bouton « Tester le webhook »
{ "id": "6f1c…", "event": "ticket.ready", "created_at": "2026-10-14T12:00:00Z",
"data": { "id": "…", "number": 27, "status": "ready", "external_ref": "F-1042", … } }Vérifiez la signature avec le secret affiché dans le tableau de bord (whsec_…). En-tête : X-3eyetlia-Signature: t=<horodatage>,v1=<hmac>, où hmac = HMAC-SHA256(secret, t + "." + corps brut).
// Node.js : refuse proprement un en-tête absent, malformé ou trop vieux, sans jamais lever d'exception
const crypto = require("crypto");
function verify(rawBody, header, secret) {
if (typeof header !== "string" || header.length > 300) return false;
const parts = Object.fromEntries(header.split(",").map((p) => p.trim().split("=", 2)).filter((kv) => kv.length === 2));
const t = Number(parts.t), v1 = parts.v1;
if (!Number.isInteger(t) || !/^[0-9a-f]{64}$/.test(v1 || "")) return false;
if (Math.abs(Date.now() / 1000 - t) > 300) return false; // 5 min max (anti-rejeu)
const expected = crypto.createHmac("sha256", secret).update(t + "." + rawBody).digest();
const got = Buffer.from(v1, "hex");
return got.length === expected.length && crypto.timingSafeEqual(expected, got);
}Délai de réponse : 5 s max, répondez 2xx. Les redirections ne sont pas suivies.
Livraison au moins une fois : en cas d'échec, le même événement (même id, en-tête X-3eyetlia-Event-Id) est renvoyé après 1 min, 5 min, 30 min, 2 h puis 12 h. Ignorez un id déjà traité. L'ordre d'arrivée n'est pas garanti : fiez-vous à data.status et à created_at. Les démos n'envoient jamais de webhooks.
5. Erreurs et limites
{ "error": { "code": "not_found", "message": "Ticket introuvable" } }
401 unauthorized · 400 invalid_external_ref / invalid_action · 404 not_found
409 invalid_transition (ex. « ready » sur un ticket déjà servi ou annulé)
429 rate_limited (60 nouveaux numéros / minute / commerce) · 500 server_errorTransitions : ready depuis waiting · undo depuis ready · done et cancel depuis waiting ou ready. done et cancelled sont définitifs. Refaire la même action renvoie 200 avec "unchanged": true, sans nouvelle notification ni webhook.
Les numéros repartent de 1 chaque jour à 5 h (heure locale du commerce).