cmonblaze · pointage NFC
API pointage (v1)
Lecture seule des données d'un compte de pointage : points, agents, clients finaux, registre des passages, présences (arrivée / départ) et totaux d'heures. Elle sert à relier le registre à un logiciel de paie, de facturation, de planning ou à un outil comme Make, Zapier ou Power Automate.
Des webhooks préviennent aussi un logiciel en direct, et des modèles pas à pas montrent les usages courants (Google Sheets, facture Pennylane, alerte SMS).
L'API ne modifie rien et ne facture rien : elle fournit des heures et des passages, le calcul d'une facture ou d'une paie reste dans le logiciel du client.
Clé d'accès
Le titulaire du compte crée la clé dans son espace client (cmonblaze.com/mon-espace, carte « API »). Elle n'est affichée qu'une fois : en cas de perte, en créer une nouvelle (l'ancienne cesse aussitôt de fonctionner).
Chaque appel l'envoie dans un en-tête, jamais dans l'adresse :
Authorization: Bearer cmb_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Variante acceptée : X-Api-Key: …. Une clé donne accès à tout le compte : la garder côté serveur, jamais dans une page web ou une appli mobile.
Appels
Adresse de base : https://cmonblaze.com/api-pointage/v1 · méthode GET · réponses JSON en UTF-8 · dates ISO 8601 à l'heure de Paris (2026-10-30T08:02:00+01:00).
curl -H "Authorization: Bearer $CLE" "https://cmonblaze.com/api-pointage/v1/heures?mois=precedent"
GET/compte
Nom, offre (pro ou maison), fin du registre, heures actives ou non, nombre de points.
GET/points
Points de pointage : code, nom, actif, compte_les_heures, clients_finaux (noms).
GET/agents
Agents ou intervenants : id, nom, actif, compte_ses_heures. Les codes personnels des agents ne sont jamais transmis.
GET/clients
Clients finaux d'un prestataire : id, nom, points (codes).
GET/passages
Registre brut, du plus ancien au plus récent : id (unique, pour éviter les doublons), le, point, point_nom, clients_finaux, agent_id, agent, type (nfc / qr), sans_reseau et recu_le (pointé hors connexion, envoyé plus tard), saisi_a_la_main ; avec la vérification sur place (GPS) : position (sur_place, a_distance, non_fournie, imprecise, position_du_point_prise, point_sans_position, en_attente ; null sans vérification), distance_m (écart avec le point, jamais la position de l'agent) et autre_telephone. 20 000 passages au plus par appel (tronque: true au-delà : réduire la période).
GET/presences
Une ligne par présence (le premier passage est l'arrivée, le suivant le départ) : agent, point, clients_finaux, arrivee, depart, duree_minutes, heures (décimal : 3.25 = 3 h 15), etat (termine, en_cours, depart_non_pointe, arrivee_non_pointee), depart_saisi_a_la_main. Vide si le compte ne compte pas les heures.
GET/heures
Totaux de la période : nom, presences, heures, departs_non_pointes. Par client final (défaut quand le compte en a) ou par=agents. Un point partagé par plusieurs clients finaux compte pour chacun.
Paramètres
| Paramètre | Ressources | Effet |
|---|---|---|
du + au | passages, presences, heures | Dates AAAA-MM-JJ incluses, un an au plus. |
periode | idem | semaine (lundi-dimanche en cours) ou semaine-precedente. |
mois | idem | AAAA-MM ou precedent. Sans aucun de ces paramètres : mois en cours. |
point | passages, presences, heures | Code d'un point. |
agent | passages, presences, heures | Id d'un agent. |
par | heures | clients (défaut) ou agents. |
Une présence appartient à la période où elle commence. Les données d'une journée peuvent encore changer : départ saisi à la main par le gérant, passage pointé sans réseau et reçu plus tard.
Exemple de réponse
GET /heures?mois=2026-10
{
"periode": {"du": "2026-10-01", "au": "2026-10-31"},
"par": "clients",
"donnees": [
{"nom": "Résidence Les Tilleuls", "presences": 22, "heures": 53.25, "departs_non_pointes": 1},
{"nom": "Cabinet Martin", "presences": 9, "heures": 18.5, "departs_non_pointes": 0}
]
}
Webhooks
Au lieu d'interroger l'API, un logiciel peut être prévenu en direct. Le titulaire du compte ajoute jusqu'à 3 adresses https:// dans son espace (carte « API », bloc « Webhooks ») et choisit les événements. Chaque événement est envoyé en POST JSON, en général quelques secondes après le pointage.
| Événement | Quand | donnees |
|---|---|---|
passage | Chaque passage (y compris pointé sans réseau, à sa réception) | Un passage, comme /passages, plus sens : arrivee, depart ou null (point qui ne compte pas les heures). |
depart | Chaque départ, pointé ou saisi à la main par le gérant | Une présence, comme /presences. |
depart_oublie | Arrivée restée sans départ 16 h après (signalée une fois, entre 8 h et 21 h) | Une présence avec etat: "depart_non_pointe". |
mois_termine | Le 1er du mois vers 7 h, pour le mois précédent | mois, periode, passages (nombre), heures_actives, par_clients et par_agents (comme /heures). |
Le bouton « Envoyer un test » de l'espace envoie un exemple fictif de chaque événement coché, avec "test": true (les vrais envois ont "test": false) : Make, Zapier ou n8n y apprennent la forme des données. Filtrer ensuite sur test pour ne rien créer avec ces exemples. Pas à pas : modèles Make / Zapier.
POST https://hook.exemple.com/…
Content-Type: application/json; charset=utf-8
X-Evenement: depart
X-Signature: sha256=5d41402abc4b2a76b9719d911017c592…
{
"id": "evt_8f3a1c0d9b2e4f6a7c81",
"evenement": "depart",
"test": false,
"cree_le": "2026-10-30T17:32:05+01:00",
"compte": "ABC234",
"donnees": {
"agent_id": 12, "agent": "Karim B.", "point": "XK7P2M", "point_nom": "Entrée résidence",
"clients_finaux": ["Résidence Les Tilleuls"],
"arrivee": "2026-10-30T08:02:00+01:00", "depart": "2026-10-30T17:32:00+01:00",
"duree_minutes": 570, "heures": 9.5, "etat": "termine", "depart_saisi_a_la_main": false
}
}
Vérifier la signature
X-Signature vaut sha256= suivi du HMAC-SHA256 du corps brut, avec le secret du webhook (affiché dans l'espace, whsec_…). Comparer avant de traiter :
// PHP
$corps = file_get_contents('php://input');
$attendu = 'sha256=' . hash_hmac('sha256', $corps, $secret);
if (!hash_equals($attendu, $_SERVER['HTTP_X_SIGNATURE'] ?? '')) { http_response_code(401); exit; }
// Node.js
const attendu = 'sha256=' + crypto.createHmac('sha256', secret).update(corpsBrut).digest('hex');
if (!crypto.timingSafeEqual(Buffer.from(attendu), Buffer.from(req.get('X-Signature') || ''))) return res.sendStatus(401);
Make, Zapier ou n8n reçoivent les webhooks sans cette vérification ; elle reste conseillée dès qu'on écrit dans un logiciel de paie ou de facturation.
Réponse et nouveaux essais
Répondre un code 2xx en moins de 5 secondes (traiter ensuite si c'est long). Sinon, nouvel essai après 1 min, 5 min, 30 min, 2 h et 6 h, puis abandon. Après 200 échecs de suite, le webhook est mis en pause : le titulaire le réactive dans son espace. Les redirections ne sont pas suivies.
Un même événement peut arriver deux fois (réponse perdue, nouvel essai) : utiliser id pour ignorer les doublons. L'ordre d'arrivée n'est pas garanti. En cas de doute, l'API fait foi : un agent peut corriger le sens de son passage dans les 30 minutes, et le gérant saisir un départ oublié.
Erreurs et limites
| Code | Sens |
|---|---|
| 400 | Paramètre invalide (point inconnu pour ce compte). |
| 401 | Clé manquante, inconnue ou supprimée. |
| 404 | Ressource inconnue. |
| 405 | Méthode autre que GET. |
| 429 | Trop d'appels : 60 par minute au plus. Une interrogation toutes les 5 à 15 minutes suffit. |
Réponse d'erreur : {"erreur": "…"}. La v1 ne change pas de forme ; de nouveaux champs peuvent s'ajouter, à ignorer s'ils ne servent pas.
Données personnelles : les noms des agents et des clients finaux sont des données du client. L'outil qui les reçoit doit être sous son contrôle.
Question technique : contact@cmonblaze.com.