LeaveFlow: REST API
LeaveFlow REST API: bearer token, employee endpoints under /api/v1/employees, error format and behavior on create.
LeaveFlow: REST API
The REST API enables integrations such as HR systems: read, create and update employees. It authenticates with a bearer token and responds with JSON.
The interactive Swagger UI of your instance is at
/api/doc, the OpenAPI description at/api/doc.json. Both are reachable without signing in.
Authentication
Every request under /api/ (except the documentation) needs a token in the header:
Authorization: Bearer YOUR_API_TOKEN
Creating a token
- As an admin click Create token under API Access Tokens (
/admin/api-tokens). - Enter a name and optionally an expiry date in the future.
- Click Generate token and copy the token right away. It is shown only once.
LeaveFlow stores only the SHA-256 hash of the token. A token belongs to the company and is invalid immediately after revocation (Revoke in the list) or expiry. There is no detail page per token.
Base URL
https://<your-domain>/api/v1
Endpoints
| Method | Path | Purpose | Success |
|---|---|---|---|
GET |
/employees |
List all employees, including those who have left | 200 |
GET |
/employees/{id} |
Read one employee | 200 |
POST |
/employees |
Create an employee with a user account | 201 |
PATCH |
/employees/{id} |
Partially update an employee | 200 |
DELETE |
/employees/{id} |
Trigger an exit (not reliable, see below) | 204 |
Employee object
| Field | Type | Description |
|---|---|---|
id |
integer | Internal ID |
name |
string | Full name |
employeeNumber |
string | Employee number |
email |
string or null | Email of the linked user account |
locationId, locationName |
integer, string | Location |
joinedAt |
string | Join date, YYYY-MM-DD |
leftAt |
string or null | Exit date, YYYY-MM-DD |
weeklyHours |
number | Weekly hours |
userId |
integer or null | ID of the user account |
GET /employees returns all employees of the company, including those who have left (recognizable by leftAt).
Creating an employee
| Field | Required | Description |
|---|---|---|
name |
yes | At most 150 characters |
email |
yes | Valid email address of the user account |
employeeNumber |
yes | At most 50 characters, unique within the company |
locationId |
yes | ID of a location of the company |
joinedAt |
yes | Date YYYY-MM-DD |
weeklyHours |
no | Greater than 0, default 40.0 |
role |
no | employee (default) or manager |
curl -X POST "https://<your-domain>/api/v1/employees" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"Anna New","email":"anna.new@example.com","employeeNumber":"EMP-010","locationId":1,"joinedAt":"2026-07-01","weeklyHours":40.0,"role":"employee"}'
- Working time is distributed evenly across Monday to Friday.
- The API rejects the role
adminwith422(message:Role "admin" cannot be assigned via the API.). Any other unknown value silently becomesemployee. - No invitation email is sent, and the user account has no password. The person sets one through "Forgot your password?" or you trigger Send reset under Users in the admin.
- A taken employee number returns
422(message:Employee number already in use.). An unknown or foreignlocationIdreturns404(message:Location not found.). - The email address is not checked for duplicates. If it is already taken, the call fails at the database with a server error.
Updating an employee
All fields are optional, only the fields you send are changed.
| Field | Description |
|---|---|
name |
At most 150 characters |
locationId |
ID of a location of the company, otherwise 404 |
weeklyHours |
Greater than 0; working time is distributed evenly across Monday to Friday again |
Deactivating an employee
The endpoint
DELETE /employees/{id}exists and answers calls with204. However, it is not reliable that the exit date and the deactivation of the user account are stored permanently by it. Do not rely on it and record exits in the employee management of the admin area via Exit employee... instead.
Status codes and error format
| Code | Meaning |
|---|---|
200, 201, 204 |
Success |
400 |
Malformed request body |
401 |
Authorization header present, but token invalid, revoked or expired |
404 |
Employee or location not found or belongs to another company |
422 |
Validation failed or rule violated |
500 |
Server error |
Always send the Authorization header: no 401 response is defined for requests without this header.
There is no 403 response. Errors other than 401 have this format; for validation errors message contains the error text, there is no list of individual fields (violations):
{ "error": true, "message": "Description of the error" }
For 401 the response looks like this and includes the header WWW-Authenticate: Bearer realm="LeaveFlow API":
{ "error": "Unauthorized", "message": "Invalid or expired API token." }