Saltar al contenido
El Registro de Jornada .com

Portal del desarrollador · en preparación

Referencia de rutas

Las 24 rutas de lectura de la API y los dos puntos de OAuth, tal como las describe el contrato.

Integridad

POST/verificacion

Verificación pública de un asiento

Sin clave de API: es un punto del protocolo OAuth.

Sin clave de API ni sesión. Quien verifica presenta el recibo firmado (recibo, el texto que se le entregó al fichar) o el asiento completo (asiento), uno solo. No se busca por un identificador suelto ni por posición: sin el contenido o la firma no hay respuesta, así que recorrer posiciones no descubre qué asientos existen. Responde siempre 200 y la misma forma, exista o no el asiento. integro: coincide con el guardado (devuelve su posición y su resumen, que ya tenías); alterado: el asiento presentado no cuadra con su propio resumen; no_consta: cuadra, pero no hay uno igual en la cadena (no se distingue «no existió» de «existió con otro contenido»); recibo_invalido: el recibo no verifica (firma, algoritmo distinto de EdDSA, clave desconocida o emitido en el futuro). El recibo no caduca. Se comprueba contra todas las claves públicas publicadas, las antiguas incluidas (/.well-known/jwks.json). No devuelve ningún dato personal (art. 5.1.c del RGPD, minimización). Límite: 30 peticiones por minuto y por IP (429 con Retry-After). CORS: orígenes de la web y de la app; desde un servidor, sin restricción de origen.

Respuestas de POST /verificacion
EstadoQué devuelve
200Veredicto. Cuerpo: VerificacionRespuesta.
400Error con la forma de RFC 9457 (type, title, status, detail, code, request_id). Se envía con Content-Type: application/json y con la cabecera X-Request-Id. Programa contra code. Códigos: metodo_no_permitido (405, con Allow: GET, OPTIONS; en /cumplimiento/validar, Allow: POST, OPTIONS; en /fichajes, /ausencias, /modificaciones e /informes, Allow: GET, POST, OPTIONS), clave_ausente, clave_invalida, clave_revocada, clave_caducada (401), clave_ip_no_permitida, ambito_insuficiente, empresa_inactiva, complemento_no_contratado (403, solo si se activa el cobro del complemento, hoy apagado), recurso_no_encontrado, persona_no_encontrada, centro_no_encontrado, modificacion_no_encontrada, informe_no_encontrado (404), parametro_invalido, cursor_invalido, cuerpo_invalido (400), rango_demasiado_amplio (422), limite_por_minuto_excedido, limite_mensual_excedido, demasiados_fallos_de_autenticacion (429, con Retry-After) y flujo_sin_configurar (503). Los errores que se producen antes de llegar a la API (capa HTTP) tienen otra forma: ver ErrorHttp.
429Error con la forma de RFC 9457 (type, title, status, detail, code, request_id). Se envía con Content-Type: application/json y con la cabecera X-Request-Id. Programa contra code. Códigos: metodo_no_permitido (405, con Allow: GET, OPTIONS; en /cumplimiento/validar, Allow: POST, OPTIONS; en /fichajes, /ausencias, /modificaciones e /informes, Allow: GET, POST, OPTIONS), clave_ausente, clave_invalida, clave_revocada, clave_caducada (401), clave_ip_no_permitida, ambito_insuficiente, empresa_inactiva, complemento_no_contratado (403, solo si se activa el cobro del complemento, hoy apagado), recurso_no_encontrado, persona_no_encontrada, centro_no_encontrado, modificacion_no_encontrada, informe_no_encontrado (404), parametro_invalido, cursor_invalido, cuerpo_invalido (400), rango_demasiado_amplio (422), limite_por_minuto_excedido, limite_mensual_excedido, demasiados_fallos_de_autenticacion (429, con Retry-After) y flujo_sin_configurar (503). Los errores que se producen antes de llegar a la API (capa HTTP) tienen otra forma: ver ErrorHttp.
Otro errorError con cuerpo Problema: ver límites y errores.

GET/integridad

Estado de integridad de la cadena de asientos

Ámbito: integridad:leer

Recalcula la cadena de asientos que se conserva y dice si es íntegra, cuál es su cabeza (la guardada y si coincide con el último asiento conservado), cuántas roturas hay y dónde está la primera (secuencia y motivo), y el último sello diario y corte por retención. No devuelve ningún asiento.

Respuestas de GET /integridad
EstadoQué devuelve
200Resultado de la verificación. Cuerpo: Integridad.
Otro errorError con cuerpo Problema: ver límites y errores.
curl -H "Authorization: Bearer $ERJ_CLAVE" \
  "https://app.elregistrodejornada.com/api/v1/integridad"

OAuth

POST/oauth/token

Canjear un código o refrescar un token

Sin clave de API: es un punto del protocolo OAuth.

Sin autenticación de cliente (cliente público con PKCE S256). Se llama desde el servidor de la aplicación: los navegadores de otros orígenes no pueden. Todo error cuenta como fallo del origen y tras 10 se responde 429. El código vale 60 segundos y un solo uso (se gasta en el primer intento, acierte o no). Refrescar entrega un par nuevo e invalida el anterior; presentar un refresco ya usado revoca toda la autorización. Solo lectura: los ámbitos que se pueden conceder son los …:leer y personas:nif.

Respuestas de POST /oauth/token
EstadoQué devuelve
200Par de tokens. Cuerpo: OauthToken.
400Error de OAuth (RFC 6749 §5.2).
429Demasiados fallos desde este origen.
503OAuth no está configurado en el servidor.

POST/oauth/revoke

Revocar una autorización (RFC 7009)

Sin clave de API: es un punto del protocolo OAuth.

Revoca toda la autorización a la que pertenece el token. Responde 200 aunque el token no exista o sea de otro cliente.

Respuestas de POST /oauth/revoke
EstadoQué devuelve
200Hecho.
429Demasiados fallos desde este origen.

Personas

GET/personas

Listar personas

Ámbito: personas:leer

El NIF sale enmascarado (***5678Z) salvo con personas:nif.

Parámetros de GET /personas
ParámetroTipoDescripción
limitconsulta, opcionalinteger, de 1 a 200, por defecto 50Elementos por página (por defecto 50, de 1 a 200; fuera de rango da 400 parametro_invalido).
cursorconsulta, opcionalstringCursor opaco devuelto como siguiente por la página anterior. Solo vale con los mismos filtros (400 cursor_invalido).
centroconsulta, opcionalstring, hasta 128 caracteres
estadoconsulta, opcionalalta | baja
fieldsconsulta, opcionalstringCampos a devolver, separados por comas (id va siempre). Válidos: id, nombre, nif, centroId, estado, altaEn, bajaEn. Otro nombre da 400 parametro_invalido.
Respuestas de GET /personas
EstadoQué devuelve
200Una página de personas (con fields, solo esos campos). Cuerpo: Pagina de PersonaParcial.
Otro errorError con cuerpo Problema: ver límites y errores.
curl -H "Authorization: Bearer $ERJ_CLAVE" \
  "https://app.elregistrodejornada.com/api/v1/personas"

GET/personas/{personaId}

Obtener una persona

Ámbito: personas:leer

Parámetros de GET /personas/{personaId}
ParámetroTipoDescripción
personaIdruta, obligatoriostring
Respuestas de GET /personas/{personaId}
EstadoQué devuelve
200La persona. Cuerpo: Persona.
404No existe esa persona en la empresa (persona_no_encontrada).
Otro errorError con cuerpo Problema: ver límites y errores.
curl -H "Authorization: Bearer $ERJ_CLAVE" \
  "https://app.elregistrodejornada.com/api/v1/personas/<personaId>"

Centros

GET/centros

Listar los centros de trabajo

Ámbito: empresa:leer

Cuelga de empresa:leer: los ámbitos centros:leer no existen como ámbito de clave.

Parámetros de GET /centros
ParámetroTipoDescripción
limitconsulta, opcionalinteger, de 1 a 200, por defecto 50Elementos por página (por defecto 50, de 1 a 200; fuera de rango da 400 parametro_invalido).
cursorconsulta, opcionalstringCursor opaco devuelto como siguiente por la página anterior. Solo vale con los mismos filtros (400 cursor_invalido).
Respuestas de GET /centros
EstadoQué devuelve
200Centros. Cuerpo: Pagina de Centro.
Otro errorError con cuerpo Problema: ver límites y errores.
curl -H "Authorization: Bearer $ERJ_CLAVE" \
  "https://app.elregistrodejornada.com/api/v1/centros"

GET/centros/{centroId}

Obtener un centro de trabajo

Ámbito: empresa:leer

Cuelga de empresa:leer, como la lista. Un centro de otra empresa o inexistente da el mismo 404 centro_no_encontrado.

Parámetros de GET /centros/{centroId}
ParámetroTipoDescripción
centroIdruta, obligatoriostring
Respuestas de GET /centros/{centroId}
EstadoQué devuelve
200El centro. Cuerpo: Centro.
404No existe ese centro en la empresa (centro_no_encontrado).
Otro errorError con cuerpo Problema: ver límites y errores.
curl -H "Authorization: Bearer $ERJ_CLAVE" \
  "https://app.elregistrodejornada.com/api/v1/centros/<centroId>"

Fichajes

GET/fichajes

Listar fichajes

Ámbito: fichajes:leer

Orden estable por secuencia de la cadena. El intervalo es [desde, hasta) sobre el instante sellado; sin parámetros, los últimos 7 días. Como mucho 31 días por llamada (422 rango_demasiado_amplio): para más, varias llamadas. Los campos posicion y nota solo se devuelven si la clave tiene además el ámbito delicado fichajes:posicion (no se puede conceder por OAuth); sin él, los fichajes salen sin esos campos.

Esta lista es una proyección de lectura: no trae todos los campos que entran en el resumen criptográfico del asiento, así que no sirve como entrada del verificador abierto (ver docs/VERIFICADOR.md).

Parámetros de GET /fichajes
ParámetroTipoDescripción
limitconsulta, opcionalinteger, de 1 a 200, por defecto 50Elementos por página (por defecto 50, de 1 a 200; fuera de rango da 400 parametro_invalido).
cursorconsulta, opcionalstringCursor opaco devuelto como siguiente por la página anterior. Solo vale con los mismos filtros (400 cursor_invalido).
personaconsulta, opcionalstring, hasta 128 caracteres
desdeconsulta, opcionalstringFecha (AAAA-MM-DD, medianoche UTC) o fecha-hora ISO 8601 con zona (incluida).
hastaconsulta, opcionalstringFecha (AAAA-MM-DD, medianoche UTC) o fecha-hora ISO 8601 con zona (excluida).
Respuestas de GET /fichajes
EstadoQué devuelve
200Una página de fichajes. Cuerpo: Pagina de Fichaje.
422Rango de más de 31 días (rango_demasiado_amplio).
Otro errorError con cuerpo Problema: ver límites y errores.
curl -H "Authorization: Bearer $ERJ_CLAVE" \
  "https://app.elregistrodejornada.com/api/v1/fichajes"

POST/fichajes

Añadir un fichaje de entrada o salida (requiere habilitar la escritura)

Requiere habilitar la escritura: apagada por defecto en cada empresa

Ámbito: fichajes:escribir

Requiere habilitar la escritura. Está apagada por defecto en todas las empresas: sin la opción de empresa «Escritura por API (fichajes)» activada por su administración, responde 403 escritura_no_habilitada. Además la clave necesita el ámbito fichajes:escribir (403 ambito_insuficiente sin él), que no se concede por defecto a ninguna clave y no existe en OAuth. Una clave de pruebas erj_test_ no escribe (403 escritura_no_disponible_en_pruebas).

Añade UN asiento de entrada o salida a una persona de la empresa de la clave (la empresa sale siempre de la clave; no hay parámetro de empresa). El asiento lo sella el servidor con la misma lógica que el fichaje de la aplicación y del quiosco: solo se añade (no existe ninguna ruta para modificar ni borrar un asiento), entra en la cadena de integridad, con su secuencia y sus huellas, y se rechaza si el mes está cerrado. La hora la pone el servidor: el cuerpo no admite ocurridoEn, ni autor, ni secuencia, ni huellas, ni ningún otro campo (400). Las correcciones de un fichaje ya sellado no se hacen por aquí.

Idempotency-Key es obligatoria. Usa un valor único por intento de fichaje (por ejemplo, un UUID) y repítelo al reintentar tras un corte: con la misma clave y los mismos datos (persona, tipo y posición) se devuelve el mismo asiento, con la cabecera Idempotent-Replayed: true, sin duplicar nada. Con la misma clave y datos distintos, 409 idempotency_key_reutilizada. La clave se acota a la clave de API que la usó.

Posición. posicion es opcional y solo se guarda si la empresa tiene activa la ubicación al fichar; es el sello del instante del fichaje, nunca un seguimiento (400 posicion_no_activada si no está activa). La respuesta no la devuelve. No hay biometría: la persona se identifica por su personaId y el sistema que llama es responsable de haberla identificado.

Códigos propios de esta operación: escritura_no_habilitada, plan_sin_escritura (403, la escritura solo está en el plan Ampliada de la API), ambito_insuficiente y escritura_no_disponible_en_pruebas (403), empresa_inactiva (403), idempotency_key_requerida, idempotency_key_invalida, datos_invalidos y posicion_no_activada (400), persona_no_encontrada (404), idempotency_key_reutilizada y conflicto_de_cadena (409; en el segundo, reintenta con la misma Idempotency-Key), mes_cerrado, hora_futura y persona_de_baja (422). Además los generales de la respuesta Error. Cuenta contra los mismos límites de uso que las lecturas.

Parámetros de POST /fichajes
ParámetroTipoDescripción
Idempotency-Keycabecera, obligatoriostring, hasta 128 caracteresIdentificador único del intento de escritura (de 1 a 128 caracteres entre letras, cifras, _, ., : y -). Repetirlo con los mismos datos devuelve el mismo resultado sin duplicar.
Respuestas de POST /fichajes
EstadoQué devuelve
201El asiento sellado (sin posicion ni nota). Un reenvío con la misma Idempotency-Key y los mismos datos devuelve el mismo asiento con la cabecera Idempotent-Replayed: true. Cuerpo: Fichaje.
400Falta o es inválida la Idempotency-Key, o el cuerpo no es válido (idempotency_key_requerida, idempotency_key_invalida, datos_invalidos, posicion_no_activada).
403Escritura no habilitada en la empresa (escritura_no_habilitada), plan sin escritura (plan_sin_escritura: solo el plan Ampliada), ámbito ausente (ambito_insuficiente) o clave de pruebas (escritura_no_disponible_en_pruebas).
404La persona no existe en la empresa de la clave (persona_no_encontrada).
409Idempotency-Key ya usada con otros datos (idempotency_key_reutilizada) o cadena ocupada (conflicto_de_cadena).
422Mes cerrado (mes_cerrado), hora futura (hora_futura) o persona de baja (persona_de_baja).
Otro errorError con cuerpo Problema: ver límites y errores.

Ausencias

GET/ausencias

Listar ausencias y vacaciones

Ámbito: ausencias:leer

El tipo se expone; el motivo médico nunca (una baja médica sale como baja).

Parámetros de GET /ausencias
ParámetroTipoDescripción
limitconsulta, opcionalinteger, de 1 a 200, por defecto 50Elementos por página (por defecto 50, de 1 a 200; fuera de rango da 400 parametro_invalido).
cursorconsulta, opcionalstringCursor opaco devuelto como siguiente por la página anterior. Solo vale con los mismos filtros (400 cursor_invalido).
personaconsulta, opcionalstring, hasta 128 caracteres
estadoconsulta, opcionalpendiente | aprobada | rechazada | cancelada
desdeconsulta, opcionalstring (date)
hastaconsulta, opcionalstring (date)
Respuestas de GET /ausencias
EstadoQué devuelve
200Una página de ausencias. Cuerpo: Pagina de Ausencia.
Otro errorError con cuerpo Problema: ver límites y errores.
curl -H "Authorization: Bearer $ERJ_CLAVE" \
  "https://app.elregistrodejornada.com/api/v1/ausencias"

POST/ausencias

Solicitar una ausencia o vacaciones (requiere habilitar la escritura)

Requiere habilitar la escritura: apagada por defecto en cada empresa

Ámbito: ausencias:escribir

Requiere habilitar la escritura. Está apagada por defecto en todas las empresas: sin la opción de empresa «Solicitar ausencias por API» activada por su administración, responde 403 escritura_no_habilitada (activar la escritura de fichajes no basta: son opciones independientes). Además la clave necesita el ámbito ausencias:escribir (403 ambito_insuficiente sin él), que no se concede por defecto a ninguna clave y no existe en OAuth. Una clave de pruebas erj_test_ no escribe (403 escritura_no_disponible_en_pruebas).

Crea UNA solicitud de ausencia a nombre de una persona de la empresa de la clave (la empresa sale siempre de la clave; no hay parámetro de empresa). Nunca la aprueba: nace siempre en estado pendiente, con un único evento en su historial (el de la clave), y la administración la resuelve desde la aplicación como cualquier otra solicitud. No existe ninguna ruta para aprobar, rechazar ni modificar una ausencia; lo único que se puede hacer después es retirar la propia solicitud mientras siga pendiente (POST /ausencias/{ausenciaId}/cancelar). El cuerpo no admite estado, historial, motivo, empresa ni ningún otro campo (400).

Tipos admitidos: vacaciones, permiso_retribuido y asuntos_propios. Las bajas médicas no se registran por API (dato de salud): las registra la administración. Un rango no puede abarcar más de 366 días. Se rechaza si el rango toca un mes cerrado (422 mes_cerrado) o se solapa con otra solicitud pendiente o aprobada de la misma persona (422 ausencia_solapada). No comprueba el saldo de vacaciones: quien aprueba lo ve en la aplicación.

Idempotency-Key es obligatoria. Usa un valor único por solicitud (por ejemplo, un UUID) y repítelo al reintentar tras un corte: con la misma clave y los mismos datos (persona, tipo y fechas) se devuelve la misma solicitud, con la cabecera Idempotent-Replayed: true, sin duplicar nada. Con la misma clave y datos distintos, 409 idempotency_key_reutilizada. La clave se acota a la clave de API que la usó.

Códigos propios de esta operación: escritura_no_habilitada, plan_sin_escritura (403, la escritura solo está en el plan Ampliada de la API), ambito_insuficiente y escritura_no_disponible_en_pruebas (403), empresa_inactiva (403), sin_permiso (403), idempotency_key_requerida, idempotency_key_invalida y datos_invalidos (400), persona_no_encontrada (404), idempotency_key_reutilizada y conflicto_al_guardar (409; en el segundo, reintenta con la misma Idempotency-Key), mes_cerrado, ausencia_solapada y persona_de_baja (422). Además los generales de la respuesta Error. Cuenta contra los mismos límites de uso que las lecturas.

Parámetros de POST /ausencias
ParámetroTipoDescripción
Idempotency-Keycabecera, obligatoriostring, hasta 128 caracteresIdentificador único del intento de escritura (de 1 a 128 caracteres entre letras, cifras, _, ., : y -). Repetirlo con los mismos datos devuelve el mismo resultado sin duplicar.
Respuestas de POST /ausencias
EstadoQué devuelve
201La solicitud creada, en estado pendiente. Un reenvío con la misma Idempotency-Key y los mismos datos devuelve la misma solicitud con la cabecera Idempotent-Replayed: true. Cuerpo: Ausencia.
400Falta o es inválida la Idempotency-Key, o el cuerpo no es válido (idempotency_key_requerida, idempotency_key_invalida, datos_invalidos).
403Escritura no habilitada en la empresa (escritura_no_habilitada), plan sin escritura (plan_sin_escritura: solo el plan Ampliada), ámbito ausente (ambito_insuficiente) o clave de pruebas (escritura_no_disponible_en_pruebas).
404La persona no existe en la empresa de la clave (persona_no_encontrada).
409Idempotency-Key ya usada con otros datos (idempotency_key_reutilizada) o no se pudo guardar (conflicto_al_guardar).
422Mes cerrado (mes_cerrado), solape con otra ausencia de la persona (ausencia_solapada) o persona de baja (persona_de_baja).
Otro errorError con cuerpo Problema: ver límites y errores.

POST/ausencias/{ausenciaId}/cancelar

Retirar una solicitud de ausencia propia (requiere habilitar la escritura)

Requiere habilitar la escritura: apagada por defecto en cada empresa

Ámbito: ausencias:escribir

Requiere habilitar la escritura. Misma doble llave que POST /ausencias, sin ninguna llave nueva: la opción de empresa «Solicitar ausencias por API» (403 escritura_no_habilitada sin ella) y el ámbito ausencias:escribir (403 ambito_insuficiente). Una clave de pruebas erj_test_ no escribe (403 escritura_no_disponible_en_pruebas).

Retira (pasa a cancelada) una solicitud que creó esta misma clave y que sigue pendiente. Nunca una aprobada o rechazada (409 ausencia_no_cancelable), ni una creada por otra clave, por la aplicación o por otra empresa: en esos casos, y si el identificador no existe, la respuesta es la misma 404 ausencia_no_encontrada, para no revelar qué solicitudes existen. Respeta las reglas de la aplicación: una ausencia que ya ha empezado no se retira (422 ausencia_ya_iniciada) ni una cuyo rango toca un mes cerrado (422 mes_cerrado). La solicitud no se borra: el historial conserva la petición y la retirada. No lleva cuerpo ni Idempotency-Key: repetir la retirada de la propia solicitud ya cancelada por esta clave devuelve lo mismo con Idempotent-Replayed: true.

Códigos propios de esta operación: escritura_no_habilitada, plan_sin_escritura (403, la escritura solo está en el plan Ampliada de la API), ambito_insuficiente y escritura_no_disponible_en_pruebas (403), empresa_inactiva (403), sin_permiso (403), ausencia_no_encontrada (404), ausencia_no_cancelable (409), ausencia_ya_iniciada y mes_cerrado (422). Además los generales de la respuesta Error. Cuenta contra los mismos límites de uso que las lecturas.

Parámetros de POST /ausencias/{ausenciaId}/cancelar
ParámetroTipoDescripción
ausenciaIdruta, obligatoriostring
Respuestas de POST /ausencias/{ausenciaId}/cancelar
EstadoQué devuelve
200La ausencia, ya en estado cancelada. Si ya la había retirado esta misma clave, la misma respuesta con la cabecera Idempotent-Replayed: true. Cuerpo: Ausencia.
403Escritura no habilitada en la empresa (escritura_no_habilitada), plan sin escritura (plan_sin_escritura: solo el plan Ampliada), ámbito ausente (ambito_insuficiente) o clave de pruebas (escritura_no_disponible_en_pruebas).
404No existe, o no la creó esta clave (ausencia_no_encontrada; la misma respuesta en ambos casos).
409La solicitud ya no está pendiente (ausencia_no_cancelable).
422La ausencia ya ha empezado (ausencia_ya_iniciada) o toca un mes cerrado (mes_cerrado).
Otro errorError con cuerpo Problema: ver límites y errores.

Modificaciones

GET/modificaciones

Listar los expedientes de modificación de fichajes

Ámbito: modificaciones:leer

Ámbito propio modificaciones:leer (el de proponer no sirve para leer). Expedientes de corrección de fichajes de la empresa de la clave (art. 34.9 ET; la propuesta y la respuesta de la otra parte), abiertos desde la aplicación o desde POST /modificaciones, en cualquier estado: pendiente (con esperaA, la parte que tiene que responder), aceptada (el servidor ya selló un fichaje nuevo que apunta al original), discrepancia (la otra parte no la aceptó) o retirada. Solo sale la propuesta (tipo, hora y día laboral) y las fechas de apertura y resolución: nunca el motivo, las notas de cada paso, quién respondió ni la versión de la persona si discrepa (texto libre que puede contener datos personales). Un expediente guardado con una forma inesperada no sale. desde y hasta filtran por el día laboral propuesto. Orden estable por fecha de apertura.

Parámetros de GET /modificaciones
ParámetroTipoDescripción
limitconsulta, opcionalinteger, de 1 a 200, por defecto 50Elementos por página (por defecto 50, de 1 a 200; fuera de rango da 400 parametro_invalido).
cursorconsulta, opcionalstringCursor opaco devuelto como siguiente por la página anterior. Solo vale con los mismos filtros (400 cursor_invalido).
personaconsulta, opcionalstring, hasta 128 caracteres
estadoconsulta, opcionalpendiente | aceptada | discrepancia | retirada
desdeconsulta, opcionalstring (date)Día laboral propuesto inicial (incluido).
hastaconsulta, opcionalstring (date)Día laboral propuesto final (incluido).
Respuestas de GET /modificaciones
EstadoQué devuelve
200Una página de expedientes. Cuerpo: Pagina de ModificacionLeida.
Otro errorError con cuerpo Problema: ver límites y errores.
curl -H "Authorization: Bearer $ERJ_CLAVE" \
  "https://app.elregistrodejornada.com/api/v1/modificaciones"

POST/modificaciones

Proponer la corrección de un fichaje (requiere habilitar la escritura)

Requiere habilitar la escritura: apagada por defecto en cada empresa

Ámbito: modificaciones:escribir

Requiere habilitar la escritura. Está apagada por defecto en todas las empresas: sin la opción de empresa «Proponer correcciones de fichajes por API» activada por su administración, responde 403 escritura_no_habilitada (activar la escritura de fichajes o la de ausencias no basta: son opciones independientes). Además la clave necesita el ámbito modificaciones:escribir (403 ambito_insuficiente sin él), que no se concede por defecto a ninguna clave y no existe en OAuth. Una clave de pruebas erj_test_ no escribe (403 escritura_no_disponible_en_pruebas).

ABRE una propuesta para corregir la hora o el tipo de UN fichaje existente de una persona de la empresa de la clave (la empresa sale siempre de la clave; no hay parámetro de empresa). Nunca la aplica: nace siempre en estado pendiente, abierta en nombre de la empresa, y espera la respuesta de la PERSONA afectada, que la acepta o la rechaza desde la aplicación como cualquier otra. Al aceptarla, el servidor sella un fichaje NUEVO con origen correccion que apunta al original (corrigeA); el original no se modifica ni se borra. No existe ninguna ruta para aceptar, rechazar, retirar ni modificar una propuesta. El cuerpo no admite estado, parte, historial ni empresa (400).

El fichaje se identifica con asientoId y secuencia (ambos salen de GET /fichajes). Hay que indicar ocurridoEn (instante ISO 8601 con zona), tipo (entrada, salida, inicio_pausa o fin_pausa) o ambos, y que algo cambie respecto al fichaje. El motivo es obligatorio (hasta 1000 caracteres): no se corrige un fichaje sin dejar constancia de por qué. Se rechaza una hora futura (422 hora_futura), un fichaje que ya es una corrección o de un tipo no corregible (422 asiento_no_corregible), si el mes del fichaje o el de la hora propuesta está cerrado (422 mes_cerrado; la aplicación sí admite abrir una modificación sobre un mes cerrado, la API no) y si ese fichaje ya tiene una propuesta pendiente (409 modificacion_pendiente). Un fichaje que no existe, que es de otra persona o de otra empresa da el mismo 404 asiento_no_encontrado.

Idempotency-Key es obligatoria. Usa un valor único por propuesta (por ejemplo, un UUID) y repítelo al reintentar tras un corte: con la misma clave y los mismos datos (persona, fichaje, hora, tipo y motivo) se devuelve la misma propuesta, con la cabecera Idempotent-Replayed: true, sin duplicar nada. Con la misma clave y datos distintos, 409 idempotency_key_reutilizada. La clave se acota a la clave de API que la usó.

Códigos propios de esta operación: escritura_no_habilitada, plan_sin_escritura (403, la escritura solo está en el plan Ampliada de la API), ambito_insuficiente y escritura_no_disponible_en_pruebas (403), empresa_inactiva (403), idempotency_key_requerida, idempotency_key_invalida y datos_invalidos (400), persona_no_encontrada y asiento_no_encontrado (404), idempotency_key_reutilizada, modificacion_pendiente y conflicto_al_guardar (409; en el último, reintenta con la misma Idempotency-Key), mes_cerrado, hora_futura, asiento_no_corregible y persona_de_baja (422). Además los generales de la respuesta Error. Cuenta contra los mismos límites de uso que las lecturas. Emite el evento modificacion.propuesta (solo identificadores) la primera vez, no en un reenvío.

Parámetros de POST /modificaciones
ParámetroTipoDescripción
Idempotency-Keycabecera, obligatoriostring, hasta 128 caracteresIdentificador único del intento de escritura (de 1 a 128 caracteres entre letras, cifras, _, ., : y -). Repetirlo con los mismos datos devuelve el mismo resultado sin duplicar.
Respuestas de POST /modificaciones
EstadoQué devuelve
201La propuesta creada, en estado pendiente y a la espera de la persona. Un reenvío con la misma Idempotency-Key y los mismos datos devuelve la misma propuesta con la cabecera Idempotent-Replayed: true. Cuerpo: Modificacion.
400Falta o es inválida la Idempotency-Key, o el cuerpo no es válido (idempotency_key_requerida, idempotency_key_invalida, datos_invalidos).
403Escritura no habilitada en la empresa (escritura_no_habilitada), plan sin escritura (plan_sin_escritura: solo el plan Ampliada), ámbito ausente (ambito_insuficiente), empresa inactiva (empresa_inactiva) o clave de pruebas (escritura_no_disponible_en_pruebas).
404La persona no existe en la empresa de la clave (persona_no_encontrada) o el fichaje no existe para esa persona en esa empresa (asiento_no_encontrado).
409Idempotency-Key ya usada con otros datos (idempotency_key_reutilizada), fichaje con una propuesta pendiente (modificacion_pendiente) o no se pudo guardar (conflicto_al_guardar).
422Mes cerrado (mes_cerrado), hora futura (hora_futura), fichaje no corregible (asiento_no_corregible) o persona de baja (persona_de_baja).
Otro errorError con cuerpo Problema: ver límites y errores.

GET/modificaciones/{modificacionId}

Obtener un expediente de modificación

Ámbito: modificaciones:leer

Mismo contenido que en la lista (sin motivo ni notas). Uno de otra empresa, inexistente o guardado con una forma inesperada da el mismo 404 modificacion_no_encontrada. Sirve para seguir una propuesta abierta con POST /modificaciones.

Parámetros de GET /modificaciones/{modificacionId}
ParámetroTipoDescripción
modificacionIdruta, obligatoriostring
Respuestas de GET /modificaciones/{modificacionId}
EstadoQué devuelve
200El expediente. Cuerpo: ModificacionLeida.
404No existe ese expediente en la empresa (modificacion_no_encontrada).
Otro errorError con cuerpo Problema: ver límites y errores.
curl -H "Authorization: Bearer $ERJ_CLAVE" \
  "https://app.elregistrodejornada.com/api/v1/modificaciones/<modificacionId>"

Bolsa

GET/bolsa

Movimientos de la bolsa de horas

Ámbito: bolsa:leer

Ámbito propio bolsa:leer. Movimientos de la bolsa de horas de la empresa (art. 34.2 ET): cada uno es la diferencia de un día de una persona, en minutos con signo (positivo, a favor de la persona; negativo, en contra). Los movimientos solo se añaden: un error se compensa con otro de signo contrario. El saldo de una persona es la suma de sus movimientos; la API no aplica el plazo de compensación ni los topes del convenio (los conoce la aplicación, no el servidor). Nunca sale quién apuntó el movimiento ni cuándo. Un movimiento guardado con una forma inesperada no sale. desde y hasta filtran por el día del movimiento. Orden estable por día.

Parámetros de GET /bolsa
ParámetroTipoDescripción
limitconsulta, opcionalinteger, de 1 a 200, por defecto 50Elementos por página (por defecto 50, de 1 a 200; fuera de rango da 400 parametro_invalido).
cursorconsulta, opcionalstringCursor opaco devuelto como siguiente por la página anterior. Solo vale con los mismos filtros (400 cursor_invalido).
personaconsulta, opcionalstring, hasta 128 caracteres
desdeconsulta, opcionalstring (date)Primer día (incluido).
hastaconsulta, opcionalstring (date)Último día (incluido).
Respuestas de GET /bolsa
EstadoQué devuelve
200Una página de movimientos. Cuerpo: Pagina de MovimientoBolsa.
Otro errorError con cuerpo Problema: ver límites y errores.
curl -H "Authorization: Bearer $ERJ_CLAVE" \
  "https://app.elregistrodejornada.com/api/v1/bolsa"

Turnos

GET/turnos

Listar los turnos del cuadrante

Ámbito: turnos:leer

Orden estable por inicio. La excepción escrita de un turno no sale.

Parámetros de GET /turnos
ParámetroTipoDescripción
limitconsulta, opcionalinteger, de 1 a 200, por defecto 50Elementos por página (por defecto 50, de 1 a 200; fuera de rango da 400 parametro_invalido).
cursorconsulta, opcionalstringCursor opaco devuelto como siguiente por la página anterior. Solo vale con los mismos filtros (400 cursor_invalido).
personaconsulta, opcionalstring, hasta 128 caracteres
centroconsulta, opcionalstring, hasta 128 caracteres
desdeconsulta, opcionalstring (date)Fecha laboral inicial (incluida).
hastaconsulta, opcionalstring (date)Fecha laboral final (incluida).
Respuestas de GET /turnos
EstadoQué devuelve
200Una página de turnos. Cuerpo: Pagina de Turno.
Otro errorError con cuerpo Problema: ver límites y errores.
curl -H "Authorization: Bearer $ERJ_CLAVE" \
  "https://app.elregistrodejornada.com/api/v1/turnos"

Calendario

GET/calendario/dias

Días del calendario de la empresa (festivos, cierres, puentes)

Ámbito: empresa:leer

Cuelga de empresa:leer. No confundir con GET /calendario (ausencias del equipo por días).

Parámetros de GET /calendario/dias
ParámetroTipoDescripción
limitconsulta, opcionalinteger, de 1 a 200, por defecto 50Elementos por página (por defecto 50, de 1 a 200; fuera de rango da 400 parametro_invalido).
cursorconsulta, opcionalstringCursor opaco devuelto como siguiente por la página anterior. Solo vale con los mismos filtros (400 cursor_invalido).
centroconsulta, opcionalstring, hasta 128 caracteresIncluye también los días de toda la empresa (sin centro).
desdeconsulta, opcionalstring (date)
hastaconsulta, opcionalstring (date)
Respuestas de GET /calendario/dias
EstadoQué devuelve
200Una página de días. Cuerpo: Pagina de DiaEmpresa.
Otro errorError con cuerpo Problema: ver límites y errores.
curl -H "Authorization: Bearer $ERJ_CLAVE" \
  "https://app.elregistrodejornada.com/api/v1/calendario/dias"

GET/calendario

Ausencias del equipo por días

Ámbito: calendario:leer

Con calendario:leer solo sale el nombre («ausente», sin tipo); con ausencias:leer también el tipo (una baja médica sale solo como baja, nunca con su motivo). Solo ausencias aprobadas, por días naturales y solo los días con alguien ausente. Rango obligatorio de como mucho 93 días (422 rango_demasiado_amplio). Paginado por días.

Parámetros de GET /calendario
ParámetroTipoDescripción
desdeconsulta, obligatoriostring (date)
hastaconsulta, obligatoriostring (date)
centroconsulta, opcionalstring, hasta 128 caracteres
limitconsulta, opcionalinteger, de 1 a 200, por defecto 50Elementos por página (por defecto 50, de 1 a 200; fuera de rango da 400 parametro_invalido).
cursorconsulta, opcionalstringCursor opaco devuelto como siguiente por la página anterior. Solo vale con los mismos filtros (400 cursor_invalido).
Respuestas de GET /calendario
EstadoQué devuelve
200Días con ausencias. Cuerpo: Pagina de DiaCalendario.
422Rango de más de 93 días (rango_demasiado_amplio).
Otro errorError con cuerpo Problema: ver límites y errores.
curl -H "Authorization: Bearer $ERJ_CLAVE" \
  "https://app.elregistrodejornada.com/api/v1/calendario?desde=<desde>&hasta=<hasta>"

GET/calendario.ics

Calendario .ics de ausencias y turnos

Ámbito: calendario:leer

Calendario en formato iCalendar (RFC 5545) para leerlo desde otro sistema con la clave en la cabecera Authorization (de servidor a servidor). Para compartirlo con una persona sin clave existe el enlace privado y revocable que se crea en la aplicación. Solo ausencias aprobadas. Sin persona: el equipo, cada ausencia como «Nombre A. · Ausente», sin tipo ni motivo y sin turnos; quien causó baja antes de hoy no sale. Con persona: sus ausencias (con el tipo solo si la clave tiene ausencias:leer; si no, «Ausente») y, si la clave tiene turnos:leer, sus turnos publicados con los cambios de turno aprobados. Por defecto, de 30 días atrás a 365 días adelante; como mucho 400 días por llamada (422 rango_demasiado_amplio). Cada evento lleva un UID estable, así que un cambio actualiza el evento en vez de duplicarlo. Los errores salen en JSON, como en el resto de rutas.

Parámetros de GET /calendario.ics
ParámetroTipoDescripción
desdeconsulta, opcionalstring (date)Primer día (incluido). Por defecto, hoy menos 30 días.
hastaconsulta, opcionalstring (date)Último día (incluido). Por defecto, desde más 365 días (u hoy más 365 días si no se pasa desde).
centroconsulta, opcionalstring, hasta 128 caracteresSolo el calendario del equipo de ese centro (sin persona).
personaconsulta, opcionalstring, hasta 128 caracteresCalendario de una persona (404 persona_no_encontrada si no existe en la empresa).
Respuestas de GET /calendario.ics
EstadoQué devuelve
200Calendario iCalendar (text/calendar; charset=utf-8). Cuerpo: text/calendar.
422Rango de más de 400 días (rango_demasiado_amplio).
Otro errorError con cuerpo Problema: ver límites y errores.
curl -H "Authorization: Bearer $ERJ_CLAVE" \
  "https://app.elregistrodejornada.com/api/v1/calendario.ics"

Cumplimiento

POST/cumplimiento/validar

Validar un cuadrante, una propuesta de turnos o jornadas trabajadas

Ámbito: turnos:leer

Cumplimiento como servicio: comprueba lo que se envía contra el Estatuto de los Trabajadores (texto refundido, Real Decreto Legislativo 2/2015, https://www.boe.es/buscar/act.php?id=BOE-A-2015-11430) con las mismas reglas que usa la aplicación. Solo calcula: no lee datos de la empresa ni guarda el cuerpo (el registro de llamadas anota la ruta, el estado y la duración, nunca el contenido). Tres modos: cuadrante (turnos): descanso entre jornadas y jornada diaria (art. 34.3, https://www.boe.es/buscar/act.php?id=BOE-A-2015-11430#a34), turnos solapados y turnos mal formados. propuesta (existentes y propuestos): lo mismo, pero solo devuelve lo que provocan los turnos propuestos. jornadas (jornadas, tramos ya trabajados): además, semana por encima de 40 h ordinarias (art. 34.1, cómputo anual, por eso es un aviso), pausa en jornada continuada de más de 6 h (art. 34.4) y descanso semanal (art. 37.1, https://www.boe.es/buscar/act.php?id=BOE-A-2015-11430#a37); el umbral de aviso de 35 h de descanso semanal y el de más de 12 días seguidos son criterios propios de aviso, no cifras de la norma. En este modo todo lo enviado cuenta como jornada ordinaria. Cada incumplimiento lleva cita con el artículo y el enlace al BOE, o null si no hay norma detrás (un turno mal formado o un solape). Es orientativo, no un dictamen: un convenio colectivo o un acuerdo pueden fijar otra distribución (art. 34.2 y 34.3); por eso se aceptan limites y se devuelven los aplicados. Como mucho 500 elementos y 400 días por llamada; el cuerpo, hasta 128 KiB. Con GET, 405 y Allow: POST, OPTIONS.

Respuestas de POST /cumplimiento/validar
EstadoQué devuelve
200Resultado de la validación. Cuerpo: CumplimientoRespuesta.
400Cuerpo no válido (cuerpo_invalido): el detalle dice qué campo.
422Elementos que abarcan más de 400 días (rango_demasiado_amplio).
Otro errorError con cuerpo Problema: ver límites y errores.

Cierres

GET/cierres

Cierres de mes de la empresa

Ámbito: cierres:leer

Solo los meses cerrados, del más antiguo al más reciente, con su estado y un resumen agregado (personas, minutos trabajados y extraordinarios, firmas de las personas y correcciones anotadas). Nunca salen los resúmenes por persona, los hash, quién cerró ni los motivos de las correcciones.

Parámetros de GET /cierres
ParámetroTipoDescripción
limitconsulta, opcionalinteger, de 1 a 200, por defecto 50Elementos por página (por defecto 50, de 1 a 200; fuera de rango da 400 parametro_invalido).
cursorconsulta, opcionalstringCursor opaco devuelto como siguiente por la página anterior. Solo vale con los mismos filtros (400 cursor_invalido).
desdeconsulta, opcionalstringPrimer mes (AAAA-MM), incluido.
hastaconsulta, opcionalstringÚltimo mes (AAAA-MM), incluido.
Respuestas de GET /cierres
EstadoQué devuelve
200Una página de cierres. Cuerpo: Pagina de Cierre.
Otro errorError con cuerpo Problema: ver límites y errores.
curl -H "Authorization: Bearer $ERJ_CLAVE" \
  "https://app.elregistrodejornada.com/api/v1/cierres"

GET/cierres/{mes}

Estado del cierre de un mes

Ámbito: cierres:leer

mes con formato AAAA-MM (otro formato da 400 parametro_invalido). Un mes sin cierre sale como abierto, sin resumen.

Parámetros de GET /cierres/{mes}
ParámetroTipoDescripción
mesruta, obligatoriostring
Respuestas de GET /cierres/{mes}
EstadoQué devuelve
200Estado del cierre. Cuerpo: Cierre.
Otro errorError con cuerpo Problema: ver límites y errores.
curl -H "Authorization: Bearer $ERJ_CLAVE" \
  "https://app.elregistrodejornada.com/api/v1/cierres/<mes>"

GET/cierres/{mes}/firmas

Firmas de las personas en el cierre de un mes

Ámbito: cierres:leer

Cuelga de cierres:leer, como el resumen del cierre (que ya da los recuentos). Una fila por cada persona incluida en el cierre del mes, con su estado (confirmado, discrepa o sin_firmar, según su última firma) y cuándo firmó por última vez. Nunca el motivo de una discrepancia, los hash ni el resumen de la persona. Un mes sin cierre no tiene firmas: lista vacía. mes con formato AAAA-MM (otro formato da 400 parametro_invalido). Orden estable por persona.

Parámetros de GET /cierres/{mes}/firmas
ParámetroTipoDescripción
mesruta, obligatoriostring
limitconsulta, opcionalinteger, de 1 a 200, por defecto 50Elementos por página (por defecto 50, de 1 a 200; fuera de rango da 400 parametro_invalido).
cursorconsulta, opcionalstringCursor opaco devuelto como siguiente por la página anterior. Solo vale con los mismos filtros (400 cursor_invalido).
personaconsulta, opcionalstring, hasta 128 caracteres
estadoconsulta, opcionalsin_firmar | confirmado | discrepa
Respuestas de GET /cierres/{mes}/firmas
EstadoQué devuelve
200Una página de firmas. Cuerpo: Pagina de FirmaCierre.
Otro errorError con cuerpo Problema: ver límites y errores.
curl -H "Authorization: Bearer $ERJ_CLAVE" \
  "https://app.elregistrodejornada.com/api/v1/cierres/<mes>/firmas"

Incidencias

GET/incidencias

Listar incidencias de jornada

Ámbito: incidencias:leer

Avisos «a revisar» calculados sobre los asientos con el mismo motor que el cierre del mes (tramos sin cerrar, descansos cortos, jornadas largas, pausa no registrada…). No son infracciones: la valoración la hace la empresa. No hay estado «resuelta»: un aviso desaparece cuando el registro se corrige. Rango de fechas laborales: por defecto los últimos 7 días y como mucho 31 días (422 rango_demasiado_amplio).

Parámetros de GET /incidencias
ParámetroTipoDescripción
limitconsulta, opcionalinteger, de 1 a 200, por defecto 50Elementos por página (por defecto 50, de 1 a 200; fuera de rango da 400 parametro_invalido).
cursorconsulta, opcionalstringCursor opaco devuelto como siguiente por la página anterior. Solo vale con los mismos filtros (400 cursor_invalido).
personaconsulta, opcionalstring, hasta 128 caracteres
tipoconsulta, opcional
desdeconsulta, opcionalstring (date)
hastaconsulta, opcionalstring (date)
Respuestas de GET /incidencias
EstadoQué devuelve
200Una página de incidencias. Cuerpo: Pagina de Incidencia.
422Rango de más de 31 días (rango_demasiado_amplio).
Otro errorError con cuerpo Problema: ver límites y errores.
curl -H "Authorization: Bearer $ERJ_CLAVE" \
  "https://app.elregistrodejornada.com/api/v1/incidencias"

Informes

GET/informes

Informes y exportaciones generados (solo metadatos)

Ámbito: informes:leer

Listado de los informes y exportaciones de la empresa, del más antiguo al más reciente, con su estado y los metadatos del archivo (nombre, tipo y tamaño). No incluye quién lo pidió, los parámetros internos ni la descarga: el enlace de descarga solo sale en GET /informes/{informeId} y solo para la clave que lo generó con POST /informes; el resto se descarga con la sesión de la empresa en la aplicación.

Parámetros de GET /informes
ParámetroTipoDescripción
limitconsulta, opcionalinteger, de 1 a 200, por defecto 50Elementos por página (por defecto 50, de 1 a 200; fuera de rango da 400 parametro_invalido).
cursorconsulta, opcionalstringCursor opaco devuelto como siguiente por la página anterior. Solo vale con los mismos filtros (400 cursor_invalido).
tipoconsulta, opcionalinforme | exportacion
estadoconsulta, opcionalen_cola | en_proceso | terminado | fallido | caducado
desdeconsulta, opcionalstring (date)Fecha de creación inicial (AAAA-MM-DD, UTC), incluida.
hastaconsulta, opcionalstring (date)Fecha de creación final (AAAA-MM-DD, UTC), incluida.
Respuestas de GET /informes
EstadoQué devuelve
200Una página de informes. Cuerpo: Pagina de Informe.
Otro errorError con cuerpo Problema: ver límites y errores.
curl -H "Authorization: Bearer $ERJ_CLAVE" \
  "https://app.elregistrodejornada.com/api/v1/informes"

POST/informes

Generar un informe (trabajo asíncrono; requiere el ámbito informes:generar)

Ámbito: informes:generar

Pide un informe y responde 202 sin esperar a que se haga, con el informe en estado en_cola y la cabecera Location (/api/v1/informes/{informeId}). Un proceso del servidor lo hace después; consulta GET /informes/{informeId} (con informes:leer) hasta que esté terminado, fallido o caducado. El estado pasa por en_cola → en_proceso → terminado | fallido | caducado; un fallo pasajero se reintenta solo, con espera creciente, hasta 3 intentos. Uno que nadie llega a hacer caduca a las 24 horas.

Hoy solo se genera tipo: exportacion: los asientos de la empresa registrados entre desde y hasta (como mucho 366 días), en CSV y sin el documento de identidad. No modifica ningún dato.

Ámbitos: informes:generar más fichajes:leer y personas:leer (el archivo lleva fichajes y nombres: un informe nunca da más de lo que la clave ya podría leer). informes:generar solo lo concede el panel de Integraciones a la administración de la empresa, nunca OAuth, y solo en los planes de pago de la API: en el resto responde 403 plan_sin_informes. Una clave de pruebas erj_test_ no genera (403 generacion_no_disponible_en_pruebas).

Idempotency-Key es obligatoria. Con la misma clave y los mismos datos se devuelve el mismo informe (200 y Idempotent-Replayed: true) sin crear otro; con la misma clave y otros datos, 409 idempotency_key_reutilizada. La clave se acota a la clave de API que la usó.

Límites: como mucho 10 informes al día por empresa (día UTC, entre todas sus claves; repetir con la misma Idempotency-Key no gasta): si no, 429 limite_diario_informes. Además, como mucho 3 informes sin terminar por clave en el plan Ampliada, y 3 entre todas las claves de la empresa (se reservan huecos para la aplicación): si no, 429 demasiados_informes_abiertos. Cuenta además contra los límites de uso de siempre. El informe lo hace el servidor en su pasada diaria, no al momento.

Códigos propios de esta operación: generacion_no_disponible_en_pruebas, plan_sin_informes, ambito_insuficiente y empresa_inactiva (403), idempotency_key_requerida, idempotency_key_invalida y datos_invalidos (400), idempotency_key_reutilizada (409), demasiados_informes_abiertos y limite_diario_informes (429) y trabajos_sin_configurar (503). Además los generales de la respuesta Error.

Parámetros de POST /informes
ParámetroTipoDescripción
Idempotency-Keycabecera, obligatoriostring, hasta 128 caracteresIdentificador único del intento de escritura (de 1 a 128 caracteres entre letras, cifras, _, ., : y -). Repetirlo con los mismos datos devuelve el mismo resultado sin duplicar.
Respuestas de POST /informes
EstadoQué devuelve
200Reenvío con la misma Idempotency-Key y los mismos datos: el mismo informe, en su estado actual, con Idempotent-Replayed: true. Cuerpo: Informe.
202El informe, en cola. Location apunta a su consulta. Cuerpo: Informe.
Otro errorError con cuerpo Problema: ver límites y errores.

GET/informes/{informeId}

Metadatos de un informe o exportación

Ámbito: informes:leer

404 informe_no_encontrado si no es de esta empresa. Si lo generó ESTA clave con POST /informes, está terminado y la clave tiene los ámbitos de generar, la respuesta trae descarga: el enlace firmado para descargar el archivo, válido 15 minutos como mucho (consulta de nuevo para obtener otro).

Parámetros de GET /informes/{informeId}
ParámetroTipoDescripción
informeIdruta, obligatoriostring
Respuestas de GET /informes/{informeId}
EstadoQué devuelve
200El informe. Cuerpo: Informe.
Otro errorError con cuerpo Problema: ver límites y errores.
curl -H "Authorization: Bearer $ERJ_CLAVE" \
  "https://app.elregistrodejornada.com/api/v1/informes/<informeId>"

GET/informes/{informeId}/descarga

Descargar el archivo de un informe generado por esta clave

Ámbito: informes:generar

Entrega el archivo (hoy, CSV) de un informe generado por ESTA clave con POST /informes. Usa el enlace del campo descarga de GET /informes/{informeId}: la firma ata la descarga a ese informe, a la empresa, a esta clave y a un instante de caducidad (15 minutos como mucho, y nunca más allá de la caducidad del archivo). Hace falta además la cabecera Authorization de la misma clave. Otra clave, aunque sea de la misma empresa, recibe 404 informe_no_encontrado, igual que si no existiera. La respuesta lleva Cache-Control: no-store.

Mismos ámbitos que generar: informes:generar, fichajes:leer y personas:leer.

Códigos propios de esta operación: generacion_no_disponible_en_pruebas, ambito_insuficiente, empresa_inactiva, firma_requerida, firma_invalida y firma_vencida (403), informe_no_encontrado (404), informe_no_listo e informe_fallido (409), informe_caducado (410) y trabajos_sin_configurar y descarga_sin_configurar (503). Además los generales de la respuesta Error.

Parámetros de GET /informes/{informeId}/descarga
ParámetroTipoDescripción
informeIdruta, obligatoriostring
venceconsulta, obligatoriostringInstante de caducidad del enlace (milisegundos desde 1970), tal como lo da descarga.
firmaconsulta, obligatoriostringFirma del enlace (64 caracteres hexadecimales), tal como la da descarga.
Respuestas de GET /informes/{informeId}/descarga
EstadoQué devuelve
200El archivo, con Content-Disposition: attachment y Cache-Control: no-store. Cuerpo: text/csv.
Otro errorError con cuerpo Problema: ver límites y errores.
curl -H "Authorization: Bearer $ERJ_CLAVE" \
  "https://app.elregistrodejornada.com/api/v1/informes/<informeId>/descarga?vence=<vence>&firma=<firma>"

Auditoría

GET/auditoria

Registro de auditoría

Ámbito: auditoria:leer

Ámbito delicado: concédelo solo a quien administra. Solo los eventos de la propia empresa, del más antiguo al más reciente, sin el detalle del evento ni los hash de la cadena (que es de todas las empresas). Incluye los rechazos por ámbito de las claves de API; las lecturas correctas con clave no se anotan. hasta es exclusivo. Cada llamada lee como mucho 1.000 eventos de la empresa: con filtros, una página puede traer menos que limit (o ninguno) y siguiente; sigue pidiendo hasta que siguiente sea null. El cursor cuenta solo los eventos de tu empresa (con los mismos filtros), nunca la numeración de la cadena común, y se admite hasta el evento 20.000: más allá, 400 cursor_invalido; acota con desde/hasta.

Parámetros de GET /auditoria
ParámetroTipoDescripción
limitconsulta, opcionalinteger, de 1 a 200, por defecto 50Elementos por página (por defecto 50, de 1 a 200; fuera de rango da 400 parametro_invalido).
cursorconsulta, opcionalstringCursor opaco devuelto como siguiente por la página anterior. Solo vale con los mismos filtros (400 cursor_invalido).
actorconsulta, opcionalstring, hasta 128 caracteres
tipoconsulta, opcionalstring, hasta 128 caracteresLa acción o su familia (cierre vale para cierre.cerrar).
desdeconsulta, opcionalstringFecha (AAAA-MM-DD) o fecha-hora ISO 8601 con zona (incluida).
hastaconsulta, opcionalstringFecha (AAAA-MM-DD) o fecha-hora ISO 8601 con zona (excluida).
Respuestas de GET /auditoria
EstadoQué devuelve
200Una página de eventos de auditoría. Cuerpo: Pagina de EventoAuditoria.
Otro errorError con cuerpo Problema: ver límites y errores.
curl -H "Authorization: Bearer $ERJ_CLAVE" \
  "https://app.elregistrodejornada.com/api/v1/auditoria"

Eventos

GET/eventos

Flujo ordenado de eventos

Ámbito: eventos:leer

Ámbito propio eventos:leer (ningún otro lo sustituye). Alternativa a los webhooks: eventos de la empresa de la clave, del más antiguo al más reciente, solo con identificadores y fechas (sin nombres, NIF ni motivos; quien quiera más datos los pide al recurso con el identificador). Hoy se emiten fichaje.creado, ausencia.solicitada, ausencia.aprobada, cuadrante.publicado, cierre.realizado y modificacion.propuesta. Paginación por cursor: guarda el siguiente de la respuesta y pásalo como desde en la siguiente llamada (con la página vacía, siguiente es el mismo desde: sirve para sondear). hayMas indica si quedan eventos ya registrados. Un desde que no sea un cursor devuelto por la API da 400 parametro_invalido. El orden es el de registro (secuencia por empresa), no el del instante del evento: uno emitido con el reloj atrasado se entrega después de los ya leídos, no se pierde. El cursor es opaco: no lo interpretes ni lo construyas.

Parámetros de GET /eventos
ParámetroTipoDescripción
limitconsulta, opcionalinteger, de 1 a 200, por defecto 50Elementos por página (por defecto 50, de 1 a 200; fuera de rango da 400 parametro_invalido).
desdeconsulta, opcionalstringCursor devuelto como siguiente por la llamada anterior. Sin él, desde el principio.
Respuestas de GET /eventos
EstadoQué devuelve
200Eventos en orden. Cuerpo: Pagina de Evento (con siguiente y hayMas).
503El flujo de eventos no está disponible en este momento (flujo_sin_configurar).
Otro errorError con cuerpo Problema: ver límites y errores.
curl -H "Authorization: Bearer $ERJ_CLAVE" \
  "https://app.elregistrodejornada.com/api/v1/eventos"

Uso

GET/uso

Consumo y ámbitos de la propia clave

Ámbito: ver la descripción.

La única ruta sin ámbito: no lee datos de la empresa, solo describe la clave (o el token OAuth) con la que se llama: sus ámbitos, su caducidad, el plan de la API de la empresa y su consumo del minuto y del mes, contando esta misma llamada (son las cifras de las cabeceras X-RateLimit-* y X-Monthly-*, que llevan todas las respuestas). Nada de otras claves. Cuenta contra los límites como cualquier llamada. Con una clave erj_test_, entorno es pruebas, plan es null y no hay tope mensual (limite y restantes del mes son null). Una clave de dispositivo (erj_disp_, la de una tableta de fichaje) recibe 403 ambito_insuficiente.

Respuestas de GET /uso
EstadoQué devuelve
200Uso de la clave. Cuerpo: Uso.
Otro errorError con cuerpo Problema: ver límites y errores.
curl -H "Authorization: Bearer $ERJ_CLAVE" \
  "https://app.elregistrodejornada.com/api/v1/uso"