Aller au contenu
AccessTime

API REST v1

Mis à jour le 18 octobre 2026

L'API REST d'AccessTime est la même que celle utilisée par notre application mobile : tout ce que fait l'application passe par ici. Vous pouvez aussi l'utiliser pour de petites intégrations maison, par exemple consulter les pointages du jour depuis un script ou demander une absence depuis un autre outil.

L'URL de base est https://votredomaine/api/v1, toutes les requêtes et réponses sont en JSON et les routes protégées exigent l'en-tête Authorization: Bearer {token}.

1. Obtenez un jeton

L'authentification utilise des jetons personnels (Laravel Sanctum), sans cookies ni session. Le jeton s'obtient avec l'e-mail et le mot de passe du salarié, les mêmes qu'il utilise pour accéder au panneau web :

curl -X POST https://votredomaine/api/v1/login \
  -H "Content-Type: application/json" \
  -d '{ "email": "empleado@empresademo.com", "password": "********" }'

La réponse inclut le jeton et les données de base de l'utilisateur :

{
  "token": "1|abcdef...",
  "user": { "id": 1, "name": "...", "email": "...", "role": "empleado", "company_id": 2 }
}

Conservez le jeton en lieu sûr et ne le partagez pas : il donne accès aux données de cette personne. Si les identifiants ne sont pas valides, vous recevrez un 422, et l'endpoint est limité à 10 tentatives par minute.

Pour se déconnecter, POST /api/v1/logout (authentifié) révoque le jeton actuel.

Les jetons expirent au bout de 90 jours : la réponse du login indique la date dans token_expires_at et, une fois passée, l'API répond 401 et il faut en redemander un. Si vous envoyez device_name lors du login (« iPhone d'Ana »), le jeton apparaît sous ce nom dans Profil → Appareils ayant accès, d'où la personne peut le révoquer.

2. Endpoints disponibles

Méthode Route Ce qu'elle fait
POST /login Renvoie un jeton à partir de l'e-mail et du mot de passe (avec la vérification en deux étapes activée, un défi)
POST /login/two-factor Échange le défi et le code de vérification contre le jeton
POST /logout Révoque le jeton actuel
GET /config Heure du serveur, fuseau horaire, géolocalisation de l'entreprise et ce que la personne peut faire
POST /fichar Enregistre un pointage (entrée ou sortie)
GET /fichajes/hoy Pointages du jour
GET /fichajes/semana Pointages de la semaine
GET /resumen/mensual?month=YYYY-MM Récapitulatif mensuel des heures travaillées
GET /ausencias Les 50 dernières absences de l'utilisateur
POST /ausencias Demande une absence
DELETE /ausencias/{id} Annule une de ses absences, avec les règles du panneau
GET /ausencias/tipos Types d'absence actifs de l'entreprise
GET /ausencias/saldo?year=YYYY Solde annuel de congés
GET /historial-cambios Qui a modifié les données de la personne, quand et avec quel rôle
POST · DELETE /devices Enregistre ou retire le téléphone pour les notifications push

Tous les endpoints agissent sur l'utilisateur authentifié : chaque personne ne voit que ses pointages, ses absences et son solde. Les messages (message) arrivent dans la langue de la personne, et chaque 403 porte un code qui indique ce qui se passe : solo_lectura, empresa_bloqueada, cuenta_desactivada, email_no_verificado ou sin_empresa.

3. Pointer via l'API

Chaque pointage porte un client_uuid : un UUID que vous générez une fois, avant la première tentative, et que vous répétez à chaque nouvel essai. Ainsi, si le réseau coupe et que vous réessayez, le pointage n'est jamais dupliqué (sans lui, 422). Envoyez aussi type (in ou out) ; si vous l'omettez, il alterne selon le dernier pointage, comme le bouton du panneau (fonctionnement du pointage).

curl -X POST https://tudominio/api/v1/fichar \
  -H "Authorization: Bearer 1|abcdef..." \
  -H "Content-Type: application/json" \
  -d '{ "client_uuid": "3f2504e0-4f89-41d3-9a0c-0305e82c3301", "type": "in" }'

Réponse 201 avec le pointage (status, id, type, happened_at…). Un nouvel essai avec le même client_uuid renvoie 200 et le même corps.

  • L'heure est celle du serveur. Ce qui a été saisi hors connexion est renvoyé avec offline: true, captured_at (l'heure du téléphone à l'appui) et sent_at (celle du téléphone à l'envoi) : le serveur corrige le décalage de l'horloge. S'il arrive plus de 72 heures après, il devient un incident en attente de révision (202) : il n'est pas perdu. Si le premier pointage enregistré après son heure, à moins de 5 minutes, est du même type (la personne l'a refait sur le kiosque ou dans le tableau de bord pendant qu'il attendait dans la file), c'est le même pointage répété : 200 avec "duplicate": true et celui qui est enregistré. Si ce pointage est en attente de révision, c'est un 202 avec "duplicate": true et cet incident. Et si ce qui est enregistré à moins de 5 minutes est un pointage du même type saisi à la main après l'appui (un oubli approuvé ou une correction acceptée avant l'arrivée de la file) : dans la même minute, le 200 renvoie celui-ci ; dans une autre, c'est l'envoi qui compte : le pointage saisi à la main est annulé (il reste visible) et le 200 avec "duplicate": true renvoie le pointage enregistré avec le client_uuid envoyé.
  • Position (latitude, longitude, accuracy) : uniquement si l'entreprise l'a activée (geolocation_mode dans /config) ; sinon, elle est ignorée. Avec obligatoria, un pointage sur le moment sans position reçoit 422.
  • Vérification sur le téléphone (verification, facultative) : seulement le résultat de celle faite par le téléphone lui-même, jamais de données biométriques : {"method": "biometric_local" | "pin" | "none", "verified": true | false, "os_auth_type": "face" | "fingerprint" | "credential" | null}. C'est ce que déclare votre application : le serveur ne peut pas le vérifier. Les espaces sont supprimés et un texte vide vaut null. Si elle ne respecte pas ce format, elle est écartée : le pointage est enregistré quand même et la réponse porte "verification_discarded": true (jamais 422) ; les autres clés sont ignorées. Elle reste avec le pointage et la personne la voit dans « Mon registre ».
  • known_ms (facultatif) : l'heure en millisecondes du dernier pointage que votre application connaissait au moment de l'appui, celle du serveur (celle de /config ou de la dernière réponse), pas celle du téléphone. Si un autre du même type est enregistré après et que le serveur l'avait déjà au moment de l'appui (par exemple, à la borne) ou que votre application l'a envoyé avant depuis sa file hors connexion, c'est le bon type qui est enregistré, comme le fait le bouton du tableau de bord, sauf si ce pointage date de moins de 5 minutes et ne vient pas de cette file : c'est le même pointage répété, et la réponse est 200 avec "duplicate": true et celui déjà enregistré. Sans known_ms, il en va de même si ce pointage du même type, datant de moins de 5 minutes, a été fait par un autre canal (la borne ou le tableau de bord) ; mais un bouton décalé depuis plus longtemps n'est pas corrigé : envoyez-le donc toujours.
  • Erreurs : 422 est définitif (affichez le motif) ; 401, 429, 5xx ou pas de réseau, conservez le pointage et réessayez avec le même client_uuid.

Les pointages sont stockés en UTC et les requêtes « aujourd'hui » et « semaine » utilisent le fuseau horaire de votre entreprise. Le récapitulatif mensuel est calculé à partir des journées consolidées chaque nuit, les mêmes qui alimentent les rapports.

Si l'essai gratuit de l'entreprise s'est terminé sans abonnement, le compte est en lecture seule et POST /fichar répond 403 (solo_lectura). Les endpoints de consultation continuent de fonctionner (plans et facturation).

4. Les absences via l'API

Vous pouvez consulter les types disponibles, le solde et demander une absence :

curl -X POST https://votredomaine/api/v1/ausencias \
  -H "Authorization: Bearer 1|abcdef..." \
  -H "Content-Type: application/json" \
  -d '{ "absence_type_id": 1, "starts_on": "2026-08-03", "ends_on": "2026-08-07", "reason": "Vacaciones" }'

L'API applique les mêmes validations que le panneau : chevauchements avec vos autres absences, solde disponible pour les types qui décomptent, et présence de jours ouvrés dans la plage (les week-ends et jours fériés sont déduits). Si le type requiert une approbation, la demande entre dans le flux d'approbations avec le statut pending ; sinon, elle est approuvée directement. Plus de détails dans absences et congés.

Les types d'absence qui exigent un justificatif ne peuvent pas être demandés via l'API : la requête renvoie une erreur et il faut passer par le panneau web, où le document peut être joint.

Et maintenant ?

  • Si votre compte n'est pas encore configuré, commencez par les premiers pas.
  • Pour pointer sur une tablette partagée, l'API n'est pas nécessaire : utilisez la borne QR.

Vous ne trouvez pas ce que vous cherchez ?

Écrivez-nous depuis la page de contact et nous vous aidons directement.

Aller à la page de contact