OpenJornada REST API
Complete technical documentation for integrating OpenJornada with other systems. RESTful API with JWT authentication and JSON responses.
Base URL
All endpoints are under the /api prefix. Interactive documentation is available at /api/docs (Swagger UI) and /api/redoc (ReDoc).
Contents
Authentication
The API uses JWT (JSON Web Tokens) for authentication. Tokens are obtained via the /api/token endpoint and must be included in the Authorization header of all protected requests.
/api/tokenGet access tokenAuthenticates an administrator user and returns a JWT token.
# Request (form-data)
username: admin@example.com
password: tu_contraseña
# Response
{
"access_token": "eyJhbGciOiJIUzI1NiIs...",
"token_type": "bearer"
}Token Usage
Include the token in all protected requests:
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
/api/users/meCurrent userReturns information about the currently authenticated user.
/api/forgot-passwordRequest password resetSends an email with instructions to reset the password (admin users).
/api/reset-passwordReset passwordResets the password using the token received by email.
Employees
Employee management: create, update, list, and delete employees. Employees can belong to multiple companies.
/api/workers/ AuthListar todos los trabajadores activos/api/workers/ AuthCrear nuevo trabajador{
"first_name": "string",
"last_name": "string",
"email": "string",
"password": "string",
"id_number": "string (DNI/NIE)",
"phone_number": "string (opcional)",
"company_ids": [
"string"
],
"send_welcome_email": "boolean (opcional)"
}/api/workers/{worker_id} AuthObtener trabajador por ID/api/workers/{worker_id} AuthActualizar trabajador/api/workers/{worker_id} AuthEliminar trabajador (soft delete)/api/workers/change-passwordCambiar contrasena (endpoint publico para trabajadores){
"email": "string",
"current_password": "string",
"new_password": "string"
}/api/workers/forgot-passwordSolicitar reset de password de trabajador/api/workers/my-companiesObtener empresas del trabajador autenticado{
"email": "string",
"password": "string"
}Companies
Company management. Each employee must be associated with at least one company. Companies cannot be deleted if they have associated employees.
/api/companies/ AuthListar todas las empresas- * include_deleted: boolean (opcional)
/api/companies/ AuthCrear nueva empresa{
"name": "string"
}/api/companies/{company_id} AuthObtener empresa por ID/api/companies/{company_id} AuthActualizar empresa/api/companies/{company_id} AuthEliminar empresa (soft delete)Time Records
Clock-in, clock-out, and break records. The system automatically detects the record type based on the employee's current status.
Record Types
entry- Clock-in / shift startexit- Clock-out / shift endpause_start- Break startpause_end- Break end
/api/time-records/ AuthCrear registro de tiempo (entrada/salida/pausa){
"email": "string",
"password": "string",
"company_id": "string",
"action": "entry | exit | pause_start | pause_end (opcional)",
"pause_type_id": "string (requerido para pause_start)",
"timezone": "string (opcional, default: UTC)"
}/api/time-records/ AuthListar todos los registros (admin)- * start_date: YYYY-MM-DD
- * end_date: YYYY-MM-DD
- * company_id: string
- * worker_name: string
- * timezone: string
/api/time-records/worker/{worker_id} AuthRegistros de un trabajador especifico- * start_date: YYYY-MM-DD
- * end_date: YYYY-MM-DD
/api/time-records/current-statusEstado actual del trabajador (webapp){
"email": "string",
"password": "string",
"company_id": "string"
}/api/time-records/worker/historyHistorial del trabajador autenticado{
"email": "string",
"password": "string",
"company_id": "string",
"start_date": "YYYY-MM-DD",
"end_date": "YYYY-MM-DD"
}Break Types
Break type configuration per company. Each type can be "inside shift" (counts as work time) or "outside shift".
Break Types
inside_shift- Inside shift (paid break)outside_shift- Outside shift (unpaid)
/api/pause-types/ AuthListar tipos de pausa- * include_deleted: boolean
- * company_id: string
/api/pause-types/ AuthCrear tipo de pausa{
"name": "string",
"type": "inside_shift | outside_shift",
"description": "string (opcional)",
"company_ids": [
"string"
]
}/api/pause-types/{pause_type_id} AuthActualizar tipo de pausa/api/pause-types/{pause_type_id} AuthEliminar tipo de pausa (soft delete)/api/pause-types/availablePausas disponibles para trabajador (webapp){
"email": "string",
"password": "string",
"company_id": "string"
}Incidents
Incident reporting system. Employees can report problems and administrators can manage them.
Incident Statuses
pending- Pending reviewin_progress- In progressresolved- Resolved
/api/incidents/ AuthCrear incidencia (trabajador){
"email": "string",
"password": "string",
"description": "string"
}/api/incidents/ AuthListar incidencias- * status: pending|in_progress|resolved
- * worker_id: string
- * start_date: YYYY-MM-DD
- * end_date: YYYY-MM-DD
/api/incidents/{incident_id} AuthObtener incidencia por ID/api/incidents/{incident_id} AuthActualizar incidencia (admin){
"status": "pending | in_progress | resolved",
"admin_notes": "string (opcional)"
}Change Requests
Employees can request corrections to their time records. Administrators review and approve/reject requests.
Request Statuses
pending- Pending reviewaccepted- Accepted and appliedrejected- Rejected
/api/change-requests/ AuthCrear solicitud de cambio{
"email": "string",
"password": "string",
"time_record_id": "string",
"company_id": "string",
"date": "YYYY-MM-DD",
"new_timestamp": "ISO 8601 datetime",
"reason": "string"
}/api/change-requests/pending/check AuthVerificar si tiene solicitud pendiente/api/change-requests/ AuthListar solicitudes de cambio- * status: pending|accepted|rejected
- * worker_id: string
- * start_date: YYYY-MM-DD
- * end_date: YYYY-MM-DD
/api/change-requests/{id} AuthObtener solicitud por ID/api/change-requests/{id} AuthAprobar o rechazar solicitud{
"status": "accepted | rejected",
"admin_internal_notes": "string (opcional)",
"admin_public_comment": "string (opcional)"
}Settings
General application settings: contact email and automatic backup configuration.
/api/settings/ AuthObtener configuracion actual/api/settings/ AuthActualizar configuracion{
"contact_email": "string (opcional)",
"backup_config": {
"enabled": "boolean",
"schedule": {
"hour": "number",
"minute": "number"
},
"retention_days": "number",
"storage_type": "local | s3 | sftp"
}
}Backups
Backup management. Supports local, S3, and SFTP storage. Backups are created in compressed format with integrity verification.
/api/backups/ AuthListar todos los backups/api/backups/trigger AuthCrear backup manual/api/backups/{backup_id} AuthObtener detalles de backup/api/backups/{backup_id} AuthEliminar backup/api/backups/{backup_id}/restore AuthRestaurar desde backup{
"confirm": "boolean (debe ser true)"
}/api/backups/{backup_id}/download AuthDescargar backup (local storage)/api/backups/{backup_id}/download-url AuthObtener URL de descarga (S3)/api/backups/test-connection AuthProbar conexion de almacenamiento/api/backups/schedule/status AuthEstado de backups programadosGDPR (ARCO Rights)
Endpoints for GDPR compliance. Allow exporting and anonymizing employee data while respecting legal retention periods.
Implemented Rights
- Right of access (Art. 15 GDPR)
- Right to data portability (Art. 20 GDPR)
- Right to erasure (Art. 17 GDPR) - with legal retention
/api/gdpr/worker/{worker_id}/export AuthExportar todos los datos del trabajador/api/gdpr/worker/{worker_id}/data AuthObtener datos personales (simplificado)/api/gdpr/worker/{worker_id}/anonymize AuthAnonimizar datos del trabajador{
"reason": "string (min 5 caracteres)"
}Importante
Anonymization preserves time records in anonymous form to comply with the legal obligation to retain them for 4 years (Art. 34.9 of the Workers' Statute / Estatuto de los Trabajadores).
Error Codes
| Code | Description |
|---|---|
400 | Bad Request - Invalid or missing data |
401 | Unauthorized - Invalid or expired token |
403 | Forbidden - Insufficient permissions for this action |
404 | Not Found - Resource not found |
409 | Conflict - Conflict with current state |
429 | Too Many Requests - Rate limit exceeded |
500 | Internal Server Error - Server error |
Complete interactive documentation is available on your OpenJornada instance.