Back to documentation
API Reference

OpenJornada REST API

Complete technical documentation for integrating OpenJornada with other systems. RESTful API with JWT authentication and JSON responses.

Base URL

https://tu-dominio.com/api

All endpoints are under the /api prefix. Interactive documentation is available at /api/docs (Swagger UI) and /api/redoc (ReDoc).

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.

POST/api/tokenGet access token

Authenticates 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...
GET/api/users/meCurrent user

Returns information about the currently authenticated user.

POST/api/forgot-passwordRequest password reset

Sends an email with instructions to reset the password (admin users).

POST/api/reset-passwordReset password

Resets the password using the token received by email.

Employees

Employee management: create, update, list, and delete employees. Employees can belong to multiple companies.

GET/api/workers/ AuthListar todos los trabajadores activos
POST/api/workers/ AuthCrear nuevo trabajador
Request body:
{
  "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)"
}
GET/api/workers/{worker_id} AuthObtener trabajador por ID
PUT/api/workers/{worker_id} AuthActualizar trabajador
DELETE/api/workers/{worker_id} AuthEliminar trabajador (soft delete)
PATCH/api/workers/change-passwordCambiar contrasena (endpoint publico para trabajadores)
Request body:
{
  "email": "string",
  "current_password": "string",
  "new_password": "string"
}
POST/api/workers/forgot-passwordSolicitar reset de password de trabajador
POST/api/workers/my-companiesObtener empresas del trabajador autenticado
Request body:
{
  "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.

GET/api/companies/ AuthListar todas las empresas
Query params:
  • * include_deleted: boolean (opcional)
POST/api/companies/ AuthCrear nueva empresa
Request body:
{
  "name": "string"
}
GET/api/companies/{company_id} AuthObtener empresa por ID
PATCH/api/companies/{company_id} AuthActualizar empresa
DELETE/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 start
  • exit - Clock-out / shift end
  • pause_start - Break start
  • pause_end - Break end
POST/api/time-records/ AuthCrear registro de tiempo (entrada/salida/pausa)
Request body:
{
  "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)"
}
GET/api/time-records/ AuthListar todos los registros (admin)
Query params:
  • * start_date: YYYY-MM-DD
  • * end_date: YYYY-MM-DD
  • * company_id: string
  • * worker_name: string
  • * timezone: string
GET/api/time-records/worker/{worker_id} AuthRegistros de un trabajador especifico
Query params:
  • * start_date: YYYY-MM-DD
  • * end_date: YYYY-MM-DD
POST/api/time-records/current-statusEstado actual del trabajador (webapp)
Request body:
{
  "email": "string",
  "password": "string",
  "company_id": "string"
}
POST/api/time-records/worker/historyHistorial del trabajador autenticado
Request body:
{
  "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)
GET/api/pause-types/ AuthListar tipos de pausa
Query params:
  • * include_deleted: boolean
  • * company_id: string
POST/api/pause-types/ AuthCrear tipo de pausa
Request body:
{
  "name": "string",
  "type": "inside_shift | outside_shift",
  "description": "string (opcional)",
  "company_ids": [
    "string"
  ]
}
PUT/api/pause-types/{pause_type_id} AuthActualizar tipo de pausa
DELETE/api/pause-types/{pause_type_id} AuthEliminar tipo de pausa (soft delete)
POST/api/pause-types/availablePausas disponibles para trabajador (webapp)
Request body:
{
  "email": "string",
  "password": "string",
  "company_id": "string"
}

Incidents

Incident reporting system. Employees can report problems and administrators can manage them.

Incident Statuses

  • pending - Pending review
  • in_progress - In progress
  • resolved - Resolved
POST/api/incidents/ AuthCrear incidencia (trabajador)
Request body:
{
  "email": "string",
  "password": "string",
  "description": "string"
}
GET/api/incidents/ AuthListar incidencias
Query params:
  • * status: pending|in_progress|resolved
  • * worker_id: string
  • * start_date: YYYY-MM-DD
  • * end_date: YYYY-MM-DD
GET/api/incidents/{incident_id} AuthObtener incidencia por ID
PATCH/api/incidents/{incident_id} AuthActualizar incidencia (admin)
Request body:
{
  "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 review
  • accepted - Accepted and applied
  • rejected - Rejected
POST/api/change-requests/ AuthCrear solicitud de cambio
Request body:
{
  "email": "string",
  "password": "string",
  "time_record_id": "string",
  "company_id": "string",
  "date": "YYYY-MM-DD",
  "new_timestamp": "ISO 8601 datetime",
  "reason": "string"
}
POST/api/change-requests/pending/check AuthVerificar si tiene solicitud pendiente
GET/api/change-requests/ AuthListar solicitudes de cambio
Query params:
  • * status: pending|accepted|rejected
  • * worker_id: string
  • * start_date: YYYY-MM-DD
  • * end_date: YYYY-MM-DD
GET/api/change-requests/{id} AuthObtener solicitud por ID
PATCH/api/change-requests/{id} AuthAprobar o rechazar solicitud
Request body:
{
  "status": "accepted | rejected",
  "admin_internal_notes": "string (opcional)",
  "admin_public_comment": "string (opcional)"
}

Settings

General application settings: contact email and automatic backup configuration.

GET/api/settings/ AuthObtener configuracion actual
PATCH/api/settings/ AuthActualizar configuracion
Request body:
{
  "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.

GET/api/backups/ AuthListar todos los backups
POST/api/backups/trigger AuthCrear backup manual
GET/api/backups/{backup_id} AuthObtener detalles de backup
DELETE/api/backups/{backup_id} AuthEliminar backup
POST/api/backups/{backup_id}/restore AuthRestaurar desde backup
Request body:
{
  "confirm": "boolean (debe ser true)"
}
GET/api/backups/{backup_id}/download AuthDescargar backup (local storage)
GET/api/backups/{backup_id}/download-url AuthObtener URL de descarga (S3)
POST/api/backups/test-connection AuthProbar conexion de almacenamiento
GET/api/backups/schedule/status AuthEstado de backups programados

GDPR (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
GET/api/gdpr/worker/{worker_id}/export AuthExportar todos los datos del trabajador
GET/api/gdpr/worker/{worker_id}/data AuthObtener datos personales (simplificado)
POST/api/gdpr/worker/{worker_id}/anonymize AuthAnonimizar datos del trabajador
Request body:
{
  "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

CodeDescription
400Bad Request - Invalid or missing data
401Unauthorized - Invalid or expired token
403Forbidden - Insufficient permissions for this action
404Not Found - Resource not found
409Conflict - Conflict with current state
429Too Many Requests - Rate limit exceeded
500Internal Server Error - Server error

Complete interactive documentation is available on your OpenJornada instance.

OpenJornada REST API - Technical Documentation & Endpoints