DEVELOPER DOCUMENTATION
Public API
Programmatic, read-only access to your Papervee workspace. Authenticate with a token and pull data across the Papervee platforms - employee leaves and events, plus project management data such as clients, projects and tracked time.
All requests are made over HTTPS to https://api.papervee.com. Replace {tenant_id} in each path with your workspace identifier - you can find it under the Need help button in the bottom-left corner of the screen.
Authentication
Every request must include your workspace token in the x-api-token header. Requests with a missing or invalid token return 401 Unauthorized.
GET /{tenant_id}/api/public/v1/leaves-events
x-api-token: YOUR_PUBLIC_API_TOKENAPI token
Generate your PUBLIC_API_TOKEN from your workspace App Center — Public API settings (only the workspace owner can generate it). Keep it secret and send it on every request.
Rate limits
Requests are limited per IP. Staying under the limit keeps your integration responsive; exceeding it returns a rate-limit error.
Rate limit
Requests are limited to 60 requests / minute per IP. Exceeding the limit returns 429 Too Many Requests.
Papervee Core
Workspace-level data: employee leaves and events.
Leaves & Events feed
Returns a chronological list of employee leaves (vacation, sick leave, remote work, etc.) and events (business travel, leave of absence, etc.) overlapping a given date range.
Query parameters
start_datestring · YYYY-MM-DDRequiredStart of the period.
end_datestring · YYYY-MM-DDRequiredEnd of the period. Must be on or after start_date. Maximum range is 366 days.
include_leavesboolean default trueInclude leaves in the response.
include_eventsboolean default trueInclude events in the response. At least one of include_leaves / include_events must be true.
daily_splitboolean default falsefalse returns one entry per record (the full period). true returns one entry per day.
Filtering behavior
- A record is returned if any part of it overlaps the requested range.
- Records with status Deleted are excluded. Waiting (pending) records are included.
- Type names are localized to your workspace language.
Response attributes
JSON array, sorted ascending by start date (by day when daily_split=true).
Common fields
Present on every item.
categorystring"leave" or "event".
idintegerUnique identifier of the record.
request_typestringType code, e.g. VC, WFH, SL, DEL.
request_type_namestringLocalized, human-readable type name (e.g. "Vacation").
statusstringRecord status, e.g. "Approved", "Waiting".
userobjectThe employee the record belongs to. See the user object below.
created_atstring · ISO 8601When the record was created. ISO 8601, UTC (e.g. 2026-05-20T09:12:00.000000Z).
The user object
Nested inside every item.
idintegerUser identifier.
full_namestringEmployee full name.
working_normstringContracted working hours per day (e.g. "8").
Event-only fields
Present only when the event type is time-based (event_request_is_on_time = true).
event_request_is_on_timebooleanAlways true when present; marks a time-based event.
duration_msintegerDuration in milliseconds.
start_timestring · HH:MMStart time.
end_timestring · HH:MMEnd time.
When daily_split=false (default)
Returned in addition to the common fields.
request_periodobject{ start_date, end_date } in YYYY-MM-DD; reflects the record's full period.
leave_daysintegerNumber of leave days (leaves only).
event_daysintegerNumber of event days (events only).
When daily_split=true
request_period, leave_days and event_days are omitted.
daystring · YYYY-MM-DDThe single day this entry represents.
Errors
{ "message": "Invalid parameters", "errors": { ... } }Validation failed; errors names the offending fields.
{ "message": "Unauthorized" }Missing or invalid token.
-Rate limit exceeded (60 requests / minute per IP).
GET https://api.papervee.com/{tenant_id}/api/public/v1/leaves-events?start_date=2026-06-01&end_date=2026-06-30&daily_split=false
x-api-token: YOUR_PUBLIC_API_TOKEN[
{
"category": "leave",
"id": 12,
"request_type": "VC",
"request_type_name": "Vacation",
"status": "Approved",
"request_period": { "start_date": "2026-06-01", "end_date": "2026-06-03" },
"leave_days": 3,
"user": { "id": 5, "full_name": "Ion Pop", "working_norm": "8" },
"created_at": "2026-05-20T09:12:00.000000Z"
},
{
"category": "event",
"id": 3,
"request_type": "DEL",
"request_type_name": "Business Travel",
"status": "Approved",
"event_request_is_on_time": true,
"duration_ms": 7200000,
"start_time": "09:00",
"end_time": "11:00",
"request_period": { "start_date": "2026-06-02", "end_date": "2026-06-02" },
"event_days": 1,
"user": { "id": 7, "full_name": "Ana Ban", "working_norm": "8" },
"created_at": "2026-05-22T11:00:00.000000Z"
}
]Papervee Projects
Project management data: clients, projects, subprojects, tracked time and employees.
List clients
Returns all project clients with their project and subproject counts. No query parameters.
Response attributes
200 OK - JSON array. Each item:
Response item
client_idintegerClient identifier.
client_namestringbrand_namestringvat_numberstringtrade_register_numberstringclient_codestringaddress, city, county, countrystringAddress fields.
iban, bankstringBanking details.
email, contact_person, phonestringContact details.
tax_payeras storedTax-payer flag/value.
projects_countintegerNumber of (non-deleted) projects.
subprojects_countintegerNumber of subprojects.
projectsinteger[]Project IDs.
sub_projectsinteger[]Subproject IDs.
archivedbooleanTrue if the client is deleted/archived.
created_atstring · ISO 8601GET https://api.papervee.com/{tenant_id}/api/public/v1/projects/clients
x-api-token: YOUR_PUBLIC_API_TOKEN[
{
"client_id": 1,
"client_name": "Nord Logistics SRL",
"brand_name": "Nord Logistics",
"vat_number": "RO12345678",
"trade_register_number": "J40/1234/2019",
"client_code": "CLI-001",
"address": "Str. Aurel Vlaicu 12",
"city": "Cluj-Napoca",
"county": "Cluj",
"country": "Romania",
"iban": "RO49BTRL1234567890123456",
"bank": "Banca Transilvania",
"email": "office@nordlogistics.ro",
"contact_person": "Ion Pop",
"phone": "+40 721 000 000",
"tax_payer": true,
"projects_count": 3,
"subprojects_count": 7,
"projects": [42, 43, 51],
"sub_projects": [101, 102, 103],
"archived": false,
"created_at": "2025-01-15T08:30:00.000000Z"
}
]List projects
Returns all projects with billing info and assigned users. No query parameters.
Response attributes
200 OK - JSON array. Each item:
Response item
project_idintegerproject_namestringproject_client_idintegerOwning client ID.
is_billablebooleanWhether the project is billable.
rate_typestring | null"hourly", "monthly", or null (only set when billable).
project_currencystring | nullCurrency code (only when billable).
assigned_usersobject[]See the user-info object below.
sub_projectsinteger[]Subproject IDs.
archivedbooleanTrue if the project is deleted/archived.
created_atstring · ISO 8601client_vat_codestringClient's VAT number.
client_contact_personstringclient_county, client_citystringThe user-info object
Each entry in assigned_users.
userIdintegerfirst_namestringlast_namestringfull_namestringemailstringjob_titlestringavatar_urlstringGET https://api.papervee.com/{tenant_id}/api/public/v1/projects
x-api-token: YOUR_PUBLIC_API_TOKEN[
{
"project_id": 42,
"project_name": "Website Redesign",
"project_client_id": 1,
"is_billable": true,
"rate_type": "hourly",
"project_currency": "EUR",
"assigned_users": [
{
"userId": 5,
"first_name": "Ion",
"last_name": "Pop",
"full_name": "Ion Pop",
"email": "ion.pop@company.com",
"job_title": "Frontend Developer",
"avatar_url": "https://cdn.papervee.com/avatars/5.png"
}
],
"sub_projects": [101, 102],
"archived": false,
"created_at": "2025-02-01T09:00:00.000000Z",
"client_vat_code": "RO12345678",
"client_contact_person": "Ion Pop",
"client_county": "Cluj",
"client_city": "Cluj-Napoca"
}
]List subprojects of a project
Returns the subprojects belonging to a project.
Path parameters
project_idintegerRequiredProject identifier.
Response attributes
200 OK - JSON array. Each item:
Response item
client_idintegerThe parent project's client ID.
subproject_idintegersubproject_namestringcompletedbooleanTrue when status is complete.
time_estimatednumberEstimated time in seconds.
time_spentnumberTotal tracked time in seconds.
GET https://api.papervee.com/{tenant_id}/api/public/v1/projects/42/subprojects
x-api-token: YOUR_PUBLIC_API_TOKEN[
{
"client_id": 1,
"subproject_id": 101,
"subproject_name": "Landing pages",
"completed": false,
"time_estimated": 144000,
"time_spent": 90000
}
]Users' tracked time entries
Returns locked project-tracking time entries per user within a date range.
Query parameters
start_datestring · YYYY-MM-DDTHH:MM:SSRequiredISO datetime, e.g. 2026-06-01T00:00:00.
end_datestring · YYYY-MM-DDTHH:MM:SSRequiredMust be on or after start_date. The range may not exceed 31 days.
Filtering behavior
- Only time entries with status locked whose start and end fall inside the range are included.
Response attributes
200 OK - JSON array. Each item:
Response item
user_idintegeruserobject{ first_name, last_name, email }.
time_entriesobject[]See the time-entry object below.
The time-entry object
Each entry in time_entries.
client_idintegerproject_idintegersubproject_idintegerstart_timestring · ISO 8601end_timestring · ISO 8601descriptionstringtime_spentnumberDuration in seconds.
Errors
{ "message": "Invalid dates" }Missing/malformed dates or end_date before start_date.
{ "message": "Requested period greater than a month" }Range exceeds 31 days.
GET https://api.papervee.com/{tenant_id}/api/public/v1/projects/users?start_date=2026-06-01T00:00:00&end_date=2026-06-30T23:59:59
x-api-token: YOUR_PUBLIC_API_TOKEN[
{
"user_id": 5,
"user": { "first_name": "Ion", "last_name": "Pop", "email": "ion.pop@company.com" },
"time_entries": [
{
"client_id": 1,
"project_id": 42,
"subproject_id": 101,
"start_time": "2026-06-01T09:00:00.000000Z",
"end_time": "2026-06-01T12:30:00.000000Z",
"description": "Implemented hero section",
"time_spent": 12600
}
]
}
]List employees
Returns active employees with job title, public custom fields, and team memberships. No query parameters.
Response attributes
200 OK - JSON array. Each item:
Response item
idintegerUser ID.
first_namestringlast_namestringemailstringjob_titlestringFrom contract data.
custom_categoriesobject[]Public custom fields grouped by category. See the custom-category object below.
teamsobject[]Project memberships. See the team object below.
The custom-category object
Each entry in custom_categories. Only custom fields marked public are included.
categorystringfieldsobject[]Array of { custom_field_id, custom_field_name, custom_field_value }.
The team object
Each entry in teams.
project_idintegernamestringhas_manage_rightsbooleanGET https://api.papervee.com/{tenant_id}/api/public/v1/projects/employees
x-api-token: YOUR_PUBLIC_API_TOKEN[
{
"id": 5,
"first_name": "Ion",
"last_name": "Pop",
"email": "ion.pop@company.com",
"job_title": "Frontend Developer",
"custom_categories": [
{
"category": "Personal",
"fields": [
{ "custom_field_id": 3, "custom_field_name": "T-shirt size", "custom_field_value": "L" }
]
}
],
"teams": [
{ "project_id": 42, "name": "Website Redesign", "has_manage_rights": true }
]
}
]Papervee Time Tracking
Write endpoints for an employee's work timer - clock in/out and pause/resume. Each request takes a JSON body and identifies the employee with user_id or email (at least one; user_id wins if both are sent). Datetimes are sent in UTC / ISO-8601 and converted to the employee's timezone before storing.
Clock in
Starts a running work timer for an employee. Fails if the employee already has an active timer.
Body parameters
user_idintegerRequiredEmployee id. Provide this or email.
emailstringRequiredEmployee email. Provide this or user_id.
start_timestring · YYYY-MM-DDTHH:MM:SSZWhen work starts, in UTC, e.g. 2026-06-29T08:00:00Z. Optional. If omitted, the current time in the user's timezone is used.
project_idintegerProject to attach. Saved only when project time-tracking is enabled for the employee and they can manage the project.
subproject_idintegerSubproject to attach. Saved only alongside a valid project_id it belongs to.
Errors
{ "error": "Active time already exists" }The employee already has a running or paused timer.
{ "message": "Invalid parameters", "errors": { ... } }Missing or invalid user_id / email / start_time.
POST https://api.papervee.com/{tenant_id}/api/public/v1/start-time
x-api-token: YOUR_PUBLIC_API_TOKEN
Content-Type: application/json
{
"user_id": 5,
"start_time": "2026-06-29T08:00:00Z",
"project_id": 42,
"subproject_id": 101
}{ "message": "Time started successfully" }Clock out
Stops the employee's running work timer and records the finalized work entry. A session shorter than one minute is discarded - the timer is removed and no entry is written.
Body parameters
user_idintegerRequiredEmployee id. Provide this or email.
emailstringRequiredEmployee email. Provide this or user_id.
end_timestring · YYYY-MM-DDTHH:MM:SSZWhen work stops, in UTC. Must be after the timer's start. Optional. If omitted, the current time in the user's timezone is used.
Errors
{ "error": "No active time to stop" }The employee has no active timer.
{ "error": "End time must be after start time" }end_time is at or before the timer's start.
{ "message": "Invalid parameters", "errors": { ... } }Missing or invalid user_id / email / end_time.
POST https://api.papervee.com/{tenant_id}/api/public/v1/stop-time
x-api-token: YOUR_PUBLIC_API_TOKEN
Content-Type: application/json
{
"user_id": 5,
"end_time": "2026-06-29T16:30:00Z"
}{ "message": "Time stopped successfully" }Start pause
Puts a running work timer on pause: closes the open work segment and opens a pause timer in its place. Requires a currently running (work) timer. A work segment shorter than one minute is discarded, but the transition to pause still happens.
Body parameters
user_idintegerRequiredEmployee id. Provide this or email.
emailstringRequiredEmployee email. Provide this or user_id.
start_timestring · YYYY-MM-DDTHH:MM:SSZWhen the pause begins, in UTC. Must be after the work segment started. Optional. If omitted, the current time in the user's timezone is used.
Errors
{ "error": "No active time to pause" }The employee has no active timer.
{ "error": "Active time is not running" }The employee is already on pause, not working.
{ "error": "Pause start must be after the work start time" }start_time is at or before the work segment's start.
{ "message": "Invalid parameters", "errors": { ... } }Missing or invalid user_id / email / start_time.
POST https://api.papervee.com/{tenant_id}/api/public/v1/start-pause
x-api-token: YOUR_PUBLIC_API_TOKEN
Content-Type: application/json
{
"user_id": 5,
"start_time": "2026-06-29T12:00:00Z"
}{ "message": "Pause started successfully" }Stop pause (resume)
Resumes from pause: closes the open pause segment and opens a new work timer in its place. Requires a currently paused timer. A pause segment shorter than one minute is discarded, but work still resumes.
Body parameters
user_idintegerRequiredEmployee id. Provide this or email.
emailstringRequiredEmployee email. Provide this or user_id.
end_timestring · YYYY-MM-DDTHH:MM:SSZWhen work resumes, in UTC. Must be after the pause started. Optional. If omitted, the current time in the user's timezone is used.
project_idintegerProject to attach to the resumed work timer. Saved only when project time-tracking is enabled for the employee and they can manage the project.
subproject_idintegerSubproject to attach. Saved only alongside a valid project_id it belongs to.
Errors
{ "error": "No active pause to stop" }The employee has no active timer.
{ "error": "Active time is not paused" }The employee is working, not on pause.
{ "error": "End time must be after start time" }end_time is at or before the pause's start.
{ "message": "Invalid parameters", "errors": { ... } }Missing or invalid user_id / email / end_time.
POST https://api.papervee.com/{tenant_id}/api/public/v1/stop-pause
x-api-token: YOUR_PUBLIC_API_TOKEN
Content-Type: application/json
{
"user_id": 5,
"end_time": "2026-06-29T13:00:00Z",
"project_id": 42,
"subproject_id": 101
}{ "message": "Pause stopped successfully" }Papervee Users
User management: create an employee with their profile, contract, leave balance, settings and module access in a single call.
Create user
Creates a new employee in the workspace — the same result as adding one from the Papervee interface: the profile, contract, leave balance, settings and module access are all set up in one call. Choose between two flows with invited_by_email: email invitation — the employee receives an invitation email with a link (valid for 2 days) where they set their own password — or manual add — the account is usable immediately, and the employee is asked to change the supplied password on first login.
Body parameters
first_namestringRequiredEmployee first name. Max 255 characters.
last_namestringRequiredEmployee last name. Max 255 characters.
emailstringRequiredWith invited_by_email: true, a valid, unused email address — the invitation is sent to it. With invited_by_email: false it is a workspace username, not a real address: the tenant domain is added as a prefix (e.g. mihai.tatu in the induserv workspace is stored as induserv.mihai.tatu), and the combined value must be at most 50 characters and unused.
invited_by_emailbooleanRequiredtrue = send an invitation email (the employee is created as pending and activates the account through the emailed link); false = manual add, the account is active immediately.
passwordstringRequired when invited_by_email is false and can_log_in is not false. Minimum 6 characters, containing at least two of: lowercase letters, uppercase letters, digits. Not accepted on the email-invitation flow (the employee sets their own password there).
password_confirmationstringRequired whenever password is sent. Must match password exactly.
can_log_inboolean default trueManual flow only. Set to false to create an employee who cannot log in (no password needed then). null is not accepted — send true, false, or omit the field.
send_invitation_to_userboolean default trueEmail flow only. Set to false to create the pending employee without sending the invitation email yet.
job_titlestringRequiredMax 255 characters.
hire_datestring · YYYY-MM-DDRequiredContract start date, e.g. 2026-08-25. Must be between 1900-01-01 and 2100-12-31.
working_normeintegerRequiredDaily working norm in hours, 1–24.
has_meal_vouchersboolean default falseWhether the contract includes meal vouchers.
leave_daysintegerRequiredAnnual leave days on the contract, 0–365.
available_leave_daysintegerRequiredLeave days currently available to the employee, 0–365.
vacation_days_carried_over_previous_yearintegerRequired0–365. Leave days the employee carried over from the previous year — include these in available_leave_days if not yet used.
core_module_accessboolean default falseGrants access to the Core HR module. Requires an active core subscription; the seat is added to it. At least one of core_module_access / performance_module_access must be true.
performance_module_accessboolean default falseGrants access to the Performance module. Requires an active performance subscription; the seat is added to it.
performance_module_admin_roleboolean default falseWith performance access: true = Performance admin, false = Performance user.
project_tracking_module_accessboolean default falseGrants access to project time-tracking. Requires an active core subscription.
project_tracking_module_admin_roleboolean default falseWith project-tracking access: true = admin role, false = user role.
recruitment_module_accessboolean default falseGrants access to the Recruitment module.
Good to know
- The workspace owner is recorded as the inviter of the invitation email and becomes the new employee's manager.
- The invitation link expires after 2 days; it can be re-sent later from the Papervee interface.
Errors
{ "message": "Invalid parameters", "errors": { "field": ["reason"] } }Validation failed; errors names the offending fields and the reasons.
{ "error": "..." }Business-rule violation. The error message is one of: User must have access at minimum one base subscription, Core module access requires an active core subscription, Performance module access requires an active performance subscription, or Project tracking module access requires an active core subscription.
{ "message": "Unauthorized" }Missing or invalid x-api-token.
{ "error": "Payment needed!" }No active subscription on the workspace.
POST https://api.papervee.com/{tenant_id}/api/public/v1/users
x-api-token: YOUR_PUBLIC_API_TOKEN
Content-Type: application/json
{
"first_name": "Andreea",
"last_name": "Pop",
"email": "andreea.pop@example.com",
"invited_by_email": true,
"job_title": "QA Engineer",
"hire_date": "2026-09-01",
"working_norme": 8,
"has_meal_vouchers": true,
"leave_days": 21,
"available_leave_days": 21,
"vacation_days_carried_over_previous_year": 0,
"core_module_access": true
}{ "message": "User created successfully", "user_id": 123 }Ești gata să începi?
Simplifică și digitalizează fluxurile de HR în compania ta și ajută echipa să se concentreze pe proiectele care chiar contează.