API REST v1
Actualizado o 18 de outubro de 2026
A API REST de AccessTime é a mesma que usa a nosa app móbil: todo o que fai a app pasa por aquí. Tamén podes usala para pequenas integracións propias, por exemplo consultar as fichaxes do día desde un script ou solicitar unha ausencia desde outra ferramenta.
A URL base é https://oteudominio/api/v1, todas as peticións e respostas
son JSON e as rutas protexidas requiren a cabeceira
Authorization: Bearer {token}.
1. Consegue un token
A autenticación usa tokens persoais (Laravel Sanctum), sen cookies nin sesión. O token obtense co email e o contrasinal do empregado, os mesmos cos que entra no panel web:
curl -X POST https://oteudominio/api/v1/login \
-H "Content-Type: application/json" \
-d '{ "email": "empleado@empresademo.com", "password": "********" }'
A resposta inclúe o token e os datos básicos do usuario:
{
"token": "1|abcdef...",
"user": { "id": 1, "name": "...", "email": "...", "role": "empleado", "company_id": 2 }
}
Garda o token nun lugar seguro e non o compartas: dá acceso aos datos desa persoa. Se as credenciais non son válidas recibirás un
422, e o endpoint está limitado a 10 intentos por minuto.
Para pechar sesión, POST /api/v1/logout (autenticado) revoga o token actual.
Os tokens caducan aos 90 días: a resposta do login trae a data en
token_expires_at e, pasada esta, a API responde 401 e hai que volver pedir un. Se
envías device_name no login («iPhone de Ana»), o token aparece con ese nome en
Perfil → Dispositivos con acceso, desde onde a persoa pode revogalo.
2. Endpoints dispoñibles
| Método | Ruta | Que fai |
|---|---|---|
| POST | /login |
Devolve un token a partir do email e o contrasinal (coa verificación en dous pasos activada, un reto) |
| POST | /login/two-factor |
Troca o reto e o código de verificación polo token |
| POST | /logout |
Revoga o token actual |
| GET | /config |
Hora do servidor, zona horaria, xeolocalización da empresa e o que pode facer a persoa |
| POST | /fichar |
Rexistra unha fichaxe (entrada ou saída) |
| GET | /fichajes/hoy |
Fichaxes do día actual |
| GET | /fichajes/semana |
Fichaxes da semana actual |
| GET | /resumen/mensual?month=YYYY-MM |
Resumo mensual de horas traballadas |
| GET | /ausencias |
Últimas 50 ausencias do usuario |
| POST | /ausencias |
Solicita unha ausencia |
| DELETE | /ausencias/{id} |
Anula unha ausencia propia, coas regras do panel |
| GET | /ausencias/tipos |
Tipos de ausencia activos da empresa |
| GET | /ausencias/saldo?year=YYYY |
Saldo anual de vacacións |
| GET | /historial-cambios |
Quen cambiou os datos da persoa, cando e con que rol |
| POST · DELETE | /devices |
Rexistra ou retira o móbil para as notificacións push |
Todos os endpoints operan sobre o usuario autenticado: cada persoa ve só
as súas fichaxes, as súas ausencias e o seu saldo. As mensaxes (message)
chegan no idioma da persoa, e cada 403 leva un code que di que pasa:
solo_lectura, empresa_bloqueada, cuenta_desactivada,
email_no_verificado ou sin_empresa.
3. Fichar desde a API
Cada fichaxe leva un client_uuid: un UUID que xeras unha vez, antes do
primeiro intento, e repites en cada reintento. Así, se se corta a rede e
volves tentalo, a fichaxe nunca se duplica (sen el, 422). Manda tamén type
(in ou out); se o omites, alterna segundo a última fichaxe, igual que o
botón do panel (como funciona a fichaxe).
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" }'
Resposta 201 coa fichaxe (status, id, type, happened_at…). Un
reintento co mesmo client_uuid devolve 200 e o mesmo corpo.
- A hora é a do servidor. O capturado sen conexión reenvíase con
offline: true,captured_at(a hora do móbil ao premer) esent_at(a do móbil ao enviar): o servidor corrixe o desfase do reloxo. Se chega máis de 72 horas despois, queda como incidencia pendente de revisión (202): non se perde. Se o primeiro que consta despois da súa hora, a menos de 5 minutos, é unha fichaxe do mesmo tipo (a persoa repetiuna no quiosco ou no panel mentres agardaba na cola), é a mesma fichaxe repetida:200con"duplicate": truee a que consta. Se esa fichaxe está pendente de revisión, é un202con"duplicate": truee esa incidencia. E se o que consta a menos de 5 minutos é unha fichaxe do mesmo tipo rexistrada a man despois de que se premese (un esquecemento aprobado ou unha corrección aceptada antes de que chegase a cola): no mesmo minuto, o200trae esa; noutro, conta o envío: o rexistrado a man anúlase (segue á vista) e o200con"duplicate": truetrae a fichaxe rexistrada coclient_uuidenviado. - Localización (
latitude,longitude,accuracy): só se a empresa a ten activada (geolocation_modeen/config); se non, descártase. Conobligatoria, unha fichaxe no momento sen localización recibe422. - Verificación no móbil (
verification, opcional): só o resultado da que fixo o propio teléfono, nunca datos biométricos:{"method": "biometric_local" | "pin" | "none", "verified": true | false, "os_auth_type": "face" | "fingerprint" | "credential" | null}. É o que declara a túa aplicación: o servidor non o pode comprobar. Recórtanse os espazos e un texto baleiro conta comonull. Se non cumpre ese formato, descártase: a fichaxe rexístrase igual e a resposta trae"verification_discarded": true(nunca422); outras claves ignóranse. Queda na fichaxe e a persoa vea en «O meu rexistro». known_ms(opcional): a hora en milisegundos da última fichaxe que coñecía a túa aplicación ao premer, a do servidor (a de/configou a da última resposta), non a do móbil. Se despois consta outra do mesmo tipo que o servidor xa tiña ao premer (por exemplo, no quiosco) ou que a túa aplicación mandou antes desde a súa cola sen conexión, rexístrase a que toca, como fai o botón do panel, salvo que esa fichaxe sexa de hai menos de 5 minutos e non veña desa cola: é a mesma fichaxe repetida e a resposta é200con"duplicate": truee a que consta. Senknown_mspasa o mesmo se esa fichaxe do mesmo tipo, de hai menos de 5 minutos, se fixo por outra canle (o quiosco ou o panel); pero o botón desfasado de máis tempo non se corrixe, así que mándao sempre.- Erros:
422é definitivo (amosa o motivo);401,429,5xxou sen rede, conserva a fichaxe e volve tentalo co mesmoclient_uuid.
As fichaxes gárdanse en UTC e as consultas de "hoxe" e "semana" usan a zona horaria da túa empresa. O resumo mensual calcúlase a partir das xornadas consolidadas cada noite, as mesmas que alimentan os informes.
Se a proba gratuíta da empresa rematou sen subscrición, a conta está en só lectura e
POST /ficharresponde403(solo_lectura). Os endpoints de consulta seguen funcionando (plans e facturación).
4. Ausencias desde a API
Podes consultar os tipos dispoñibles, o saldo e solicitar unha ausencia:
curl -X POST https://oteudominio/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": "Vacacións" }'
A API aplica as mesmas validacións ca o panel: solapamentos con outras
ausencias propias, saldo dispoñible nos tipos que descontan e que o rango
conteña días laborables (desconta fins de semana e festivos). Se o tipo
require aprobación, a solicitude entra no
fluxo de aprobacións con estado pending; se non, queda
aprobada directamente. Máis detalle en ausencias e vacacións.
Os tipos de ausencia que esixen xustificante non se poden solicitar por API: a petición devolve un erro e hai que facela desde o panel web, onde si se pode achegar o documento.
E agora que?
- Se aínda non tes a conta montada, empeza polos primeiros pasos.
- Para fichar nunha tableta compartida non necesitas a API: usa o quiosco QR.
Non atopas o que buscas?
Escríbenos desde a páxina de contacto e axudámosche directamente.
Ir a contacto