openapi: 3.0.3 info: title: Everhour API description: >- The Everhour API is a RESTful interface providing programmatic access to time tracking, timesheets, timers, projects, tasks, clients, invoices, expenses, resource scheduling, time off, and reporting data in Everhour. The API accepts and returns JSON (UTF-8 only). All requests are authenticated with an X-Api-Key header carrying an API key found at the bottom of your Everhour profile page. An optional X-Accept-Version header pins a specific API version (the most recent, 1.2, is used by default). The API is labeled BETA by Everhour, meaning some calls can be slightly adjusted; breaking changes are pushed in separate API versions. Time values are in seconds and money amounts are in cents throughout. version: '1.2' contact: name: Everhour url: https://everhour.com email: ask@everhour.com servers: - url: https://api.everhour.com description: Everhour production API security: - apiKey: [] tags: - name: Time Records description: Reported time records for the team, users, tasks, and projects. - name: Timers description: Start, inspect, and stop running timers. - name: Timecards description: Clock-in/clock-out attendance timecards. - name: Timesheets description: Weekly timesheets and the timesheet approval workflow. - name: Projects description: Projects, sections, billing, budgets, and integration sync. - name: Tasks description: Tasks, task search, and task estimates. - name: Schedule description: Resource planner assignments. - name: Time Off description: Time off types and allocations. - name: Clients description: Clients and client budgets. - name: Invoices description: Invoices generated from tracked time and expenses. - name: Expenses description: Expenses, expense categories, and attachments. - name: Reports description: Dashboard reports for projects, clients, and users. - name: Users description: Current user and team members. - name: Webhooks description: Webhook subscriptions for resource change events. paths: /team/time: get: operationId: getAllTimeRecords tags: - Time Records summary: Get all time records description: >- Returns time records across the whole team, optionally filtered by date range and paginated. Pass opts_include_billing=1 to include billing data (admins with billing permissions only). parameters: - $ref: '#/components/parameters/From' - $ref: '#/components/parameters/To' - $ref: '#/components/parameters/TimeLimit' - $ref: '#/components/parameters/Page' - $ref: '#/components/parameters/IncludeBilling' responses: '200': description: A list of time records. content: application/json: schema: type: array items: $ref: '#/components/schemas/TimeRecordExtended' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /users/{userId}/time: get: operationId: getUserTimeRecords tags: - Time Records summary: Get user time records description: Returns time records reported by a specific user. parameters: - $ref: '#/components/parameters/UserId' - $ref: '#/components/parameters/From' - $ref: '#/components/parameters/To' - $ref: '#/components/parameters/TimeLimit' - $ref: '#/components/parameters/Page' responses: '200': description: A list of the user's time records. content: application/json: schema: type: array items: $ref: '#/components/schemas/TimeRecord' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /tasks/{taskId}/time: get: operationId: getTaskTimeRecords tags: - Time Records summary: Get task time records description: Returns time records reported against a specific task. parameters: - $ref: '#/components/parameters/TaskId' - $ref: '#/components/parameters/From' - $ref: '#/components/parameters/To' - $ref: '#/components/parameters/TimeLimit' - $ref: '#/components/parameters/Page' responses: '200': description: A list of the task's time records. content: application/json: schema: type: array items: $ref: '#/components/schemas/TimeRecordExtended' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /projects/{projectId}/time: get: operationId: getProjectTimeRecords tags: - Time Records summary: Get project time records description: Returns time records reported against a specific project. parameters: - $ref: '#/components/parameters/ProjectId' - $ref: '#/components/parameters/From' - $ref: '#/components/parameters/To' - $ref: '#/components/parameters/TimeLimit' - $ref: '#/components/parameters/Page' responses: '200': description: A list of the project's time records. content: application/json: schema: type: array items: $ref: '#/components/schemas/TimeRecordExtended' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /time: post: operationId: addTime tags: - Time Records summary: Add time description: Adds a time record to a task for a user on a given date. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/TimeRecordRequest' responses: '201': description: The created time record. content: application/json: schema: $ref: '#/components/schemas/TimeRecordExtended' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /time/{timeId}: parameters: - $ref: '#/components/parameters/TimeId' put: operationId: updateTimeRecord tags: - Time Records summary: Update time record description: Updates an existing time record. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/TimeRecordRequest' responses: '200': description: The updated time record. content: application/json: schema: $ref: '#/components/schemas/TimeRecordExtended' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' delete: operationId: deleteTimeRecord tags: - Time Records summary: Delete time record description: Deletes a time record. responses: '200': description: The deleted time record. content: application/json: schema: $ref: '#/components/schemas/TimeRecordExtended' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /timers: post: operationId: startTimer tags: - Timers summary: Start timer description: Starts a timer on a task for the current user. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/TimerRequest' responses: '201': description: The started timer. content: application/json: schema: $ref: '#/components/schemas/Timer' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /timers/current: get: operationId: getRunningTimer tags: - Timers summary: Get running timer description: Returns the currently running timer for the current user. responses: '200': description: The running timer (status stopped if none is running). content: application/json: schema: $ref: '#/components/schemas/Timer' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' delete: operationId: stopTimer tags: - Timers summary: Stop timer description: Stops the currently running timer and records the tracked time. responses: '200': description: The stopped timer. content: application/json: schema: $ref: '#/components/schemas/Timer' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /team/timers: get: operationId: getAllTeamTimers tags: - Timers summary: Get all team timers description: Returns all currently running timers across the team. responses: '200': description: A list of running timers. content: application/json: schema: type: array items: $ref: '#/components/schemas/Timer' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /timecards: get: operationId: getAllTimecards tags: - Timecards summary: Get all timecards description: Returns timecards for the whole team within a date range (last two weeks by default). parameters: - $ref: '#/components/parameters/From' - $ref: '#/components/parameters/To' responses: '200': description: A list of timecards. content: application/json: schema: type: array items: $ref: '#/components/schemas/Timecard' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /users/{userId}/timecards: get: operationId: getUserTimecards tags: - Timecards summary: Get user timecards description: Returns timecards for a user within a date range (last two weeks by default). parameters: - $ref: '#/components/parameters/UserId' - $ref: '#/components/parameters/From' - $ref: '#/components/parameters/To' responses: '200': description: A list of the user's timecards. content: application/json: schema: type: array items: $ref: '#/components/schemas/Timecard' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /users/{userId}/timecards/{date}: parameters: - $ref: '#/components/parameters/UserId' - $ref: '#/components/parameters/Date' get: operationId: getTimecard tags: - Timecards summary: Get timecard description: Returns the timecard for a user on a specific date. responses: '200': description: The timecard. content: application/json: schema: $ref: '#/components/schemas/Timecard' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' put: operationId: updateTimecard tags: - Timecards summary: Update timecard description: Updates clock-in, clock-out, or break time on a timecard. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/TimecardUpdateRequest' responses: '200': description: The updated timecard. content: application/json: schema: $ref: '#/components/schemas/Timecard' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' delete: operationId: deleteTimecard tags: - Timecards summary: Delete timecard description: Deletes a user's timecard for a specific date. responses: '204': description: Timecard deleted. '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /users/{userId}/timecards/clock-in: post: operationId: clockIn tags: - Timecards summary: Clock in description: Clocks a user in, creating or updating today's timecard. parameters: - $ref: '#/components/parameters/UserId' requestBody: content: application/json: schema: $ref: '#/components/schemas/ClockRequest' responses: '200': description: The timecard after clocking in. content: application/json: schema: $ref: '#/components/schemas/Timecard' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /users/{userId}/timecards/clock-out: post: operationId: clockOut tags: - Timecards summary: Clock out description: Clocks a user out on today's timecard. parameters: - $ref: '#/components/parameters/UserId' requestBody: content: application/json: schema: $ref: '#/components/schemas/ClockRequest' responses: '200': description: The timecard after clocking out. content: application/json: schema: $ref: '#/components/schemas/Timecard' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /users/{userId}/timesheets: get: operationId: getUserTimesheets tags: - Timesheets summary: Get user timesheets description: Returns weekly timesheets for a user (most recent weeks first). parameters: - $ref: '#/components/parameters/UserId' - name: limit in: query description: Max number of weeks to return. schema: type: integer responses: '200': description: A list of the user's timesheets. content: application/json: schema: type: array items: $ref: '#/components/schemas/Timesheet' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /timesheets: get: operationId: getTeamTimesheets tags: - Timesheets summary: Get team timesheets description: >- Returns timesheets for the whole team for a given week. The week ID is the two-digit year plus the week number (for example 2535 for week 35 of 2025). parameters: - name: weekId in: query required: true description: Week ID (two-digit year + week number). schema: type: integer responses: '200': description: A list of team timesheets for the week. content: application/json: schema: type: array items: $ref: '#/components/schemas/Timesheet' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /timesheets/{timesheetId}/approval: parameters: - $ref: '#/components/parameters/TimesheetId' post: operationId: submitTimesheetApproval tags: - Timesheets summary: Approve week / request approval description: >- Submits a weekly timesheet for approval (or approves it directly when called by an admin). The timesheet ID is the user ID concatenated with the week ID. requestBody: content: application/json: schema: $ref: '#/components/schemas/TimesheetApprovalRequest' responses: '200': description: The timesheet approval. content: application/json: schema: $ref: '#/components/schemas/TimesheetApproval' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' put: operationId: reviewTimesheetApproval tags: - Timesheets summary: Approve or reject approval request description: Approves or rejects a pending timesheet approval request, optionally per day of the week. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/TimesheetApprovalReviewRequest' responses: '200': description: The reviewed timesheet approval. content: application/json: schema: $ref: '#/components/schemas/TimesheetApproval' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /timesheets/{timesheetId}/discard-approval: put: operationId: discardTimesheetApproval tags: - Timesheets summary: Discard your approval request description: Discards a previously submitted timesheet approval request. parameters: - $ref: '#/components/parameters/TimesheetId' requestBody: content: application/json: schema: $ref: '#/components/schemas/TimesheetApprovalRequest' responses: '200': description: The timesheet approval after discarding. content: application/json: schema: $ref: '#/components/schemas/TimesheetApproval' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /projects: get: operationId: getAllProjects tags: - Projects summary: Get all projects description: Returns projects, optionally filtered by name query or source integration platform. parameters: - name: limit in: query description: Max results. schema: type: integer - name: query in: query description: Search projects by name. schema: type: string - name: platform in: query description: Filter by integration platform code (for example as, ev, b3, b2, pv, gh, in, tr, jr). schema: type: string responses: '200': description: A list of projects. content: application/json: schema: type: array items: $ref: '#/components/schemas/Project' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' post: operationId: createProject tags: - Projects summary: Create project description: Creates a native Everhour project. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ProjectRequest' responses: '201': description: The created project. content: application/json: schema: $ref: '#/components/schemas/Project' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /projects/{projectId}: parameters: - $ref: '#/components/parameters/ProjectId' get: operationId: getProject tags: - Projects summary: Get project description: Returns a single project by ID. responses: '200': description: The project. content: application/json: schema: $ref: '#/components/schemas/Project' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' put: operationId: updateProject tags: - Projects summary: Update project description: Updates a project. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ProjectRequest' responses: '200': description: The updated project. content: application/json: schema: $ref: '#/components/schemas/Project' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' delete: operationId: deleteProject tags: - Projects summary: Delete project description: Deletes a project. responses: '204': description: Project deleted. '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /projects/{projectId}/archive: patch: operationId: archiveProject tags: - Projects summary: Archive or unarchive project description: Archives or unarchives a project. parameters: - $ref: '#/components/parameters/ProjectId' requestBody: required: true content: application/json: schema: type: object properties: archived: type: boolean responses: '201': description: The project after archiving/unarchiving. content: application/json: schema: $ref: '#/components/schemas/Project' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /projects/{projectId}/billing: put: operationId: updateProjectBilling tags: - Projects summary: Update project billing and budget description: >- Updates a project's billing type (non_billable, hourly, fixed_fee), rate configuration (project_rate or user_rate with per-user overrides), and budget (money, time, or costs; general, monthly, weekly, or daily periods). parameters: - $ref: '#/components/parameters/ProjectId' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ProjectBilling' responses: '200': description: The updated project. content: application/json: schema: $ref: '#/components/schemas/Project' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /projects/{projectId}/sync: post: operationId: syncIntegrationProject tags: - Projects summary: Sync integration project description: >- Instantly synchronizes a project from a connected integration (Asana, Trello, ClickUp, GitHub, and more) into Everhour instead of waiting for background sync. Safe to call multiple times; returns the existing project if already synced. parameters: - $ref: '#/components/parameters/ProjectId' responses: '200': description: The synced project. content: application/json: schema: $ref: '#/components/schemas/Project' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /projects/{projectId}/sections: parameters: - $ref: '#/components/parameters/ProjectId' get: operationId: getProjectSections tags: - Projects summary: Get project sections description: Returns the sections of a project. responses: '200': description: A list of sections. content: application/json: schema: type: array items: $ref: '#/components/schemas/Section' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' post: operationId: createSection tags: - Projects summary: Create section description: Creates a section in a project. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/SectionRequest' responses: '201': description: The created section. content: application/json: schema: $ref: '#/components/schemas/Section' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /sections/{sectionId}: parameters: - name: sectionId in: path required: true description: Section ID. schema: type: integer get: operationId: getSection tags: - Projects summary: Get section description: Returns a single section by ID. responses: '200': description: The section. content: application/json: schema: $ref: '#/components/schemas/Section' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' put: operationId: updateSection tags: - Projects summary: Update section description: Updates a section. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/SectionRequest' responses: '200': description: The updated section. content: application/json: schema: $ref: '#/components/schemas/Section' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' delete: operationId: deleteSection tags: - Projects summary: Delete section description: Deletes a section. responses: '204': description: Section deleted. '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /projects/{projectId}/tasks: parameters: - $ref: '#/components/parameters/ProjectId' get: operationId: getProjectTasks tags: - Tasks summary: Get project tasks description: Returns the tasks of a project, paginated up to 250 per page. parameters: - name: page in: query description: Results page. schema: type: integer - name: limit in: query description: Tasks per page, 250 max. schema: type: integer - name: exclude-closed in: query description: Exclude closed/completed tasks. schema: type: boolean - name: query in: query description: Search tasks by name. schema: type: string responses: '200': description: A list of tasks. content: application/json: schema: type: array items: $ref: '#/components/schemas/Task' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' post: operationId: createTask tags: - Tasks summary: Create task description: Creates a task in a project section. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/TaskRequest' responses: '201': description: The created task. content: application/json: schema: $ref: '#/components/schemas/Task' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /tasks/search: get: operationId: searchTasks tags: - Tasks summary: Search tasks description: Searches tasks across all projects by name. parameters: - name: query in: query description: Search query. schema: type: string - name: limit in: query description: Max number of search results. schema: type: integer - name: searchInClosed in: query description: Also search closed/completed tasks. schema: type: boolean responses: '200': description: Matching tasks. content: application/json: schema: type: array items: $ref: '#/components/schemas/Task' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /projects/{projectId}/tasks/search: get: operationId: searchProjectTasks tags: - Tasks summary: Search project tasks description: Searches tasks within a single project by name. parameters: - $ref: '#/components/parameters/ProjectId' - name: query in: query description: Search query. schema: type: string - name: limit in: query description: Max number of search results. schema: type: integer - name: searchInClosed in: query description: Also search closed/completed tasks. schema: type: boolean responses: '200': description: Matching tasks. content: application/json: schema: type: array items: $ref: '#/components/schemas/Task' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /tasks/{taskId}: parameters: - $ref: '#/components/parameters/TaskId' get: operationId: getTask tags: - Tasks summary: Get task description: >- Returns a single task by ID. Pass opts_include_billing=1 to include billing data (admins with billing permissions only). parameters: - $ref: '#/components/parameters/IncludeBilling' responses: '200': description: The task. content: application/json: schema: $ref: '#/components/schemas/Task' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' put: operationId: updateTask tags: - Tasks summary: Update task description: Updates a task, including custom field values. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/TaskRequest' responses: '200': description: The updated task. content: application/json: schema: $ref: '#/components/schemas/Task' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' delete: operationId: deleteTask tags: - Tasks summary: Delete task description: Deletes a task. responses: '204': description: Task deleted. '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /tasks/{taskId}/estimate: parameters: - $ref: '#/components/parameters/TaskId' put: operationId: updateTaskEstimate tags: - Tasks summary: Update task estimate description: Sets or updates the time estimate on a task (overall or per user). requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/TaskEstimate' responses: '200': description: The task with the updated estimate. content: application/json: schema: $ref: '#/components/schemas/Task' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' delete: operationId: deleteTaskEstimate tags: - Tasks summary: Delete task estimate description: Removes the time estimate from a task. responses: '204': description: Estimate deleted. '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /resource-planner/assignments: get: operationId: getAllAssignments tags: - Schedule summary: Get all assignments description: Returns resource planner assignments, filterable by type, project, task, client, and date range. parameters: - name: type in: query description: Filter by assignment type (assignment or time-off). schema: type: string enum: - assignment - time-off - name: project in: query description: Filter by project ID. schema: type: string - name: task in: query description: Filter by task ID. schema: type: string - name: client in: query description: Filter by client ID. schema: type: integer - name: from in: query description: Assignments starting from this date. schema: type: string format: date - name: to in: query description: Assignments ending at this date. schema: type: string format: date responses: '200': description: A list of assignments. content: application/json: schema: type: array items: $ref: '#/components/schemas/Assignment' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' post: operationId: createAssignment tags: - Schedule summary: Create assignment or time off description: >- Creates a resource planner assignment. With type time-off (plus timeOffType, timeOffPeriod, and approval fields) this same endpoint creates time off for a user. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AssignmentRequest' responses: '201': description: The created assignment. content: application/json: schema: $ref: '#/components/schemas/Assignment' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /resource-planner/assignments/{assignmentId}: parameters: - name: assignmentId in: path required: true description: Assignment ID. schema: type: integer put: operationId: updateAssignment tags: - Schedule summary: Update assignment description: Updates a resource planner assignment. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AssignmentRequest' responses: '200': description: The updated assignment. content: application/json: schema: $ref: '#/components/schemas/Assignment' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' delete: operationId: deleteAssignment tags: - Schedule summary: Delete assignment description: Deletes a resource planner assignment. responses: '204': description: Assignment deleted. '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /resource-planner/time-off-types: get: operationId: getTimeOffTypes tags: - Time Off summary: Get time off types description: Returns the team's time off types (vacation, sick leave, and so on). responses: '200': description: A list of time off types. content: application/json: schema: type: array items: $ref: '#/components/schemas/TimeOffType' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' post: operationId: createTimeOffType tags: - Time Off summary: Create time off type description: Creates a time off type. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/TimeOffTypeRequest' responses: '201': description: The created time off type. content: application/json: schema: $ref: '#/components/schemas/TimeOffType' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /resource-planner/time-off-types/{typeId}: parameters: - name: typeId in: path required: true description: Time off type ID. schema: type: integer put: operationId: updateTimeOffType tags: - Time Off summary: Update time off type description: Updates a time off type. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/TimeOffTypeRequest' responses: '200': description: The updated time off type. content: application/json: schema: $ref: '#/components/schemas/TimeOffType' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' delete: operationId: deleteTimeOffType tags: - Time Off summary: Delete time off type description: Deletes a time off type. responses: '204': description: Time off type deleted. '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /allocations: get: operationId: getAllAllocations tags: - Time Off summary: Get all allocations description: Returns time off allocations (accrual balances) for team members. responses: '200': description: A list of time off allocations. content: application/json: schema: type: array items: $ref: '#/components/schemas/TimeOffAllocation' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' post: operationId: createAllocation tags: - Time Off summary: Create allocation description: Creates a time off allocation for one or more users. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/TimeOffAllocationRequest' responses: '201': description: The created allocation. content: application/json: schema: $ref: '#/components/schemas/TimeOffAllocation' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /allocations/{allocationId}: parameters: - name: allocationId in: path required: true description: Allocation ID. schema: type: integer put: operationId: updateAllocation tags: - Time Off summary: Update allocation description: Updates a time off allocation. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/TimeOffAllocationRequest' responses: '200': description: The updated allocation. content: application/json: schema: $ref: '#/components/schemas/TimeOffAllocation' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' delete: operationId: deleteAllocation tags: - Time Off summary: Delete allocation description: Deletes a time off allocation. responses: '204': description: Allocation deleted. '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /clients: get: operationId: getAllClients tags: - Clients summary: Get all clients description: Returns clients, optionally filtered by name query. parameters: - name: query in: query description: Search clients by name. schema: type: string responses: '200': description: A list of clients. content: application/json: schema: type: array items: $ref: '#/components/schemas/Client' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' post: operationId: createClient tags: - Clients summary: Create client description: Creates a client and optionally links projects to it. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ClientRequest' responses: '201': description: The created client. content: application/json: schema: $ref: '#/components/schemas/Client' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /clients/{clientId}: parameters: - $ref: '#/components/parameters/ClientId' get: operationId: getClient tags: - Clients summary: Get client description: Returns a single client by ID. responses: '200': description: The client. content: application/json: schema: $ref: '#/components/schemas/Client' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' put: operationId: updateClient tags: - Clients summary: Update client description: Updates a client. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ClientRequest' responses: '200': description: The updated client. content: application/json: schema: $ref: '#/components/schemas/Client' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /clients/{clientId}/budget: parameters: - $ref: '#/components/parameters/ClientId' put: operationId: updateClientBudget tags: - Clients summary: Update client budget description: >- Sets or updates a client budget - money, time, or costs based, with general, monthly, weekly, or daily periods, thresholds, and overbudget protection. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ClientBudget' responses: '200': description: The client with the updated budget. content: application/json: schema: $ref: '#/components/schemas/Client' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' delete: operationId: deleteClientBudget tags: - Clients summary: Delete client budget description: Removes the budget from a client. responses: '204': description: Client budget deleted. '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /invoices: get: operationId: getAllInvoices tags: - Invoices summary: Get all invoices description: Returns all invoices. responses: '200': description: A list of invoices. content: application/json: schema: type: array items: $ref: '#/components/schemas/Invoice' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /invoices/{invoiceId}: parameters: - $ref: '#/components/parameters/InvoiceId' get: operationId: getInvoice tags: - Invoices summary: Get invoice description: Returns a single invoice by ID. responses: '200': description: The invoice. content: application/json: schema: $ref: '#/components/schemas/Invoice' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' put: operationId: updateInvoice tags: - Invoices summary: Update invoice description: Updates invoice details, tax, discount, and line items. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/InvoiceUpdateRequest' responses: '200': description: The updated invoice. content: application/json: schema: $ref: '#/components/schemas/Invoice' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' delete: operationId: deleteInvoice tags: - Invoices summary: Delete invoice description: Deletes an invoice. responses: '204': description: Invoice deleted. '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /clients/{clientId}/invoices: post: operationId: createInvoice tags: - Invoices summary: Create invoice description: Creates an invoice for a client from uninvoiced time and expenses within a date range. parameters: - $ref: '#/components/parameters/ClientId' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/InvoiceCreateRequest' responses: '201': description: The created invoice. content: application/json: schema: $ref: '#/components/schemas/Invoice' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /invoices/{invoiceId}/reset-time: post: operationId: refreshInvoiceLineItems tags: - Invoices summary: Refresh invoice line items description: Rebuilds the invoice line items from current time and expense data. parameters: - $ref: '#/components/parameters/InvoiceId' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/InvoiceRefreshRequest' responses: '200': description: The refreshed invoice. content: application/json: schema: $ref: '#/components/schemas/Invoice' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /invoices/{invoiceId}/{status}: post: operationId: setInvoiceStatus tags: - Invoices summary: Mark invoice as draft, sent, or paid description: Transitions an invoice between draft, sent, and paid statuses. parameters: - $ref: '#/components/parameters/InvoiceId' - name: status in: path required: true description: Target invoice status. schema: type: string enum: - draft - sent - paid responses: '200': description: The invoice with the new status. content: application/json: schema: $ref: '#/components/schemas/Invoice' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /invoices/{invoiceId}/export: post: operationId: exportInvoice tags: - Invoices summary: Export invoice to Xero, QuickBooks, or FreshBooks description: Exports the invoice to a connected accounting integration. parameters: - $ref: '#/components/parameters/InvoiceId' responses: '200': description: The exported invoice. content: application/json: schema: $ref: '#/components/schemas/Invoice' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /expenses: get: operationId: getAllExpenses tags: - Expenses summary: Get all expenses description: Returns all expenses. responses: '200': description: A list of expenses. content: application/json: schema: type: array items: $ref: '#/components/schemas/Expense' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' post: operationId: createExpense tags: - Expenses summary: Create expense description: Creates an expense in a category, optionally linked to a project and user. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ExpenseRequest' responses: '201': description: The created expense. content: application/json: schema: $ref: '#/components/schemas/Expense' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /expenses/{expenseId}: parameters: - name: expenseId in: path required: true description: Expense ID. schema: type: integer put: operationId: updateExpense tags: - Expenses summary: Update expense description: Updates an expense. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ExpenseRequest' responses: '200': description: The updated expense. content: application/json: schema: $ref: '#/components/schemas/Expense' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' delete: operationId: deleteExpense tags: - Expenses summary: Delete expense description: Deletes an expense. responses: '204': description: Expense deleted. '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /expenses/categories: get: operationId: getAllExpenseCategories tags: - Expenses summary: Get all expense categories description: Returns all expense categories. responses: '200': description: A list of expense categories. content: application/json: schema: type: array items: $ref: '#/components/schemas/ExpenseCategory' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' post: operationId: createExpenseCategory tags: - Expenses summary: Create expense category description: Creates an expense category, optionally unit-based (for example mileage). requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ExpenseCategoryRequest' responses: '201': description: The created expense category. content: application/json: schema: $ref: '#/components/schemas/ExpenseCategory' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /expenses/categories/{categoryId}: parameters: - name: categoryId in: path required: true description: Expense category ID. schema: type: integer put: operationId: updateExpenseCategory tags: - Expenses summary: Update expense category description: Updates an expense category. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ExpenseCategoryRequest' responses: '200': description: The updated expense category. content: application/json: schema: $ref: '#/components/schemas/ExpenseCategory' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' delete: operationId: deleteExpenseCategory tags: - Expenses summary: Delete expense category description: Deletes an expense category, optionally moving or removing its expenses. requestBody: content: application/json: schema: type: object properties: targetCategory: type: integer description: Category to move existing expenses into. removeExpenses: type: boolean description: Remove the category's expenses instead of moving them. responses: '204': description: Expense category deleted. '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /dashboards/projects: get: operationId: getProjectsReport tags: - Reports summary: Projects report description: >- Returns aggregated time, billable amounts, costs, profit, and expense metrics per project. Time columns are in seconds and amounts in cents. parameters: - $ref: '#/components/parameters/DateGte' - $ref: '#/components/parameters/DateLte' - $ref: '#/components/parameters/FilterProjectId' - $ref: '#/components/parameters/FilterClientId' - $ref: '#/components/parameters/FilterMemberId' responses: '200': description: Per-project report rows. content: application/json: schema: type: array items: $ref: '#/components/schemas/ProjectsDashboardItem' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /dashboards/clients: get: operationId: getClientsReport tags: - Reports summary: Clients report description: Returns aggregated time, billable amounts, costs, profit, and expense metrics per client. parameters: - $ref: '#/components/parameters/DateGte' - $ref: '#/components/parameters/DateLte' - $ref: '#/components/parameters/FilterProjectId' - $ref: '#/components/parameters/FilterClientId' - $ref: '#/components/parameters/FilterMemberId' responses: '200': description: Per-client report rows. content: application/json: schema: type: array items: $ref: '#/components/schemas/ClientsDashboardItem' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /dashboards/users: get: operationId: getUsersReport tags: - Reports summary: Users report description: Returns aggregated time, time off, billable amounts, costs, and profit metrics per team member. parameters: - $ref: '#/components/parameters/DateGte' - $ref: '#/components/parameters/DateLte' - $ref: '#/components/parameters/FilterProjectId' - $ref: '#/components/parameters/FilterClientId' - $ref: '#/components/parameters/FilterMemberId' responses: '200': description: Per-user report rows. content: application/json: schema: type: array items: $ref: '#/components/schemas/UsersDashboardItem' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /users/me: get: operationId: getCurrentUser tags: - Users summary: Get current user description: Returns the user profile that owns the API key. responses: '200': description: The current user. content: application/json: schema: $ref: '#/components/schemas/User' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /team/users: get: operationId: getAllUsers tags: - Users summary: Get all users description: Returns all team members with roles and statuses. responses: '200': description: A list of team members. content: application/json: schema: type: array items: $ref: '#/components/schemas/User' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /hooks: post: operationId: createWebhook tags: - Webhooks summary: Create webhook description: >- Creates a webhook subscription. Everhour sends a verification POST with an X-Hook-Secret header to the target URL; the target must echo the header back to complete verification. Supported events cover project, task, timer, time, section, client, and estimate changes. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/WebhookRequest' responses: '201': description: The created webhook. content: application/json: schema: $ref: '#/components/schemas/Webhook' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' /hooks/{hookId}: parameters: - name: hookId in: path required: true description: Webhook ID. schema: type: integer get: operationId: getWebhook tags: - Webhooks summary: Get webhook description: Returns a webhook subscription by ID. responses: '200': description: The webhook. content: application/json: schema: $ref: '#/components/schemas/Webhook' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' put: operationId: updateWebhook tags: - Webhooks summary: Update webhook description: Updates a webhook subscription (re-triggers target URL verification). requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/WebhookRequest' responses: '200': description: The updated webhook. content: application/json: schema: $ref: '#/components/schemas/Webhook' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' delete: operationId: deleteWebhook tags: - Webhooks summary: Delete webhook description: Deletes a webhook subscription. responses: '204': description: Webhook deleted. '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' components: securitySchemes: apiKey: type: apiKey in: header name: X-Api-Key description: API key from the bottom of your Everhour profile page. parameters: UserId: name: userId in: path required: true description: User ID. schema: type: integer TaskId: name: taskId in: path required: true description: 'Task ID (for example ev:3000010034).' schema: type: string ProjectId: name: projectId in: path required: true description: 'Project ID in {platform code}:{platform ID} format (for example ev:1234567789001 or as:1234567789001).' schema: type: string ClientId: name: clientId in: path required: true description: Client ID. schema: type: integer InvoiceId: name: invoiceId in: path required: true description: Invoice ID. schema: type: integer TimeId: name: timeId in: path required: true description: Time record ID. schema: type: integer TimesheetId: name: timesheetId in: path required: true description: Timesheet ID (user ID concatenated with week ID). schema: type: integer Date: name: date in: path required: true description: Date in YYYY-MM-DD format. schema: type: string format: date From: name: from in: query description: Date from (YYYY-MM-DD). schema: type: string format: date To: name: to in: query description: Date to (YYYY-MM-DD). schema: type: string format: date Page: name: page in: query description: Results page. schema: type: integer TimeLimit: name: limit in: query description: Max results per page (max 50000). schema: type: integer IncludeBilling: name: opts_include_billing in: query description: Set to 1 to include billing data (admins with billing permissions only). schema: type: integer enum: - 1 DateGte: name: date.gte in: query description: Report start date (YYYY-MM-DD). schema: type: string format: date DateLte: name: date.lte in: query description: Report end date (YYYY-MM-DD). schema: type: string format: date FilterProjectId: name: projectId in: query description: Filter by project ID. schema: type: string FilterClientId: name: clientId in: query description: Filter by client ID. schema: type: integer FilterMemberId: name: memberId in: query description: Filter by user ID. schema: type: integer responses: Unauthorized: description: Missing or invalid X-Api-Key header. content: application/json: schema: $ref: '#/components/schemas/Error' TooManyRequests: description: >- Rate limit exceeded (around 20 requests per 10 seconds per API key). The Retry-After response header specifies the number of seconds to wait before making another request. headers: Retry-After: description: Seconds to wait before retrying. schema: type: integer content: application/json: schema: $ref: '#/components/schemas/Error' schemas: Error: type: object properties: code: type: integer message: type: string TimeRecord: type: object properties: id: type: integer description: Time record ID. time: type: integer description: Time recorded in seconds. user: type: integer description: User ID. date: type: string format: date task: $ref: '#/components/schemas/Task' isLocked: type: boolean isInvoiced: type: boolean comment: type: string TimeRecordExtended: allOf: - $ref: '#/components/schemas/TimeRecord' - type: object properties: history: type: array items: $ref: '#/components/schemas/TimeHistory' TimeHistory: type: object properties: id: type: integer description: Time record history ID. createdBy: type: integer description: User ID. time: type: integer description: Time difference in seconds. previousTime: type: integer description: Previous time in seconds. action: type: string enum: - TIMER - ADD - EDIT - REMOVE - COMMENT - MOVE createdAt: type: string TimeRecordRequest: type: object required: - time - date properties: time: type: integer description: Time in seconds. date: type: string format: date task: type: string description: Task ID. user: type: integer description: User ID (defaults to the API key owner). comment: type: string Timer: type: object properties: status: type: string enum: - active - stopped duration: type: integer description: Timer duration in seconds. today: type: integer description: Time tracked today by the user on the timer task, in seconds. startedAt: type: string userDate: type: string format: date comment: type: string task: $ref: '#/components/schemas/Task' user: $ref: '#/components/schemas/User' TimerRequest: type: object required: - task properties: task: type: string description: Task ID to track time against. userDate: type: string format: date comment: type: string Timecard: type: object properties: user: type: integer description: User ID. clockIn: type: string description: Clock-in time in the user timezone (HH:MM). clockOut: type: string description: Clock-out time in the user timezone (HH:MM). breakTime: type: integer description: Breaks duration in seconds. workTime: type: integer description: Working time in seconds (clock-out minus clock-in minus breaks). history: type: array items: $ref: '#/components/schemas/TimecardHistory' TimecardHistory: type: object properties: action: type: string enum: - clock-in - clock-out - break previousTime: type: string time: type: string trigger: type: string enum: - manually - timer - button - day-end - idle-state TimecardUpdateRequest: type: object properties: clockIn: type: string description: Clock-in time in the user timezone (HH:MM). clockOut: type: string description: Clock-out time in the user timezone (HH:MM). breakTime: type: integer description: Breaks duration in seconds. ClockRequest: type: object properties: userDate: type: string format: date description: Current user date; defaults to the user profile timezone. Timesheet: type: object properties: id: type: integer description: Timesheet ID (user ID concatenated with week ID). week: $ref: '#/components/schemas/Week' user: type: integer description: User ID. tasks: type: array items: $ref: '#/components/schemas/Task' dailyTime: type: array items: $ref: '#/components/schemas/DailyTime' approval: $ref: '#/components/schemas/TimesheetApproval' timecards: type: array items: $ref: '#/components/schemas/Timecard' Week: type: object properties: id: type: integer description: Week ID (two-digit year + week number). from: type: string to: type: string beginningOfWeek: type: integer description: 0 if the week starts on Sunday, 1 if Monday. DailyTime: type: object properties: date: type: string time: type: integer description: Total daily time in seconds. timeWithoutTask: type: integer description: Time tracked without a task, in seconds. user: type: integer TimesheetApproval: type: object properties: id: type: integer user: type: integer weekId: type: integer timesheetId: type: integer reviewer: type: integer description: Reviewer user ID. history: type: array items: $ref: '#/components/schemas/TimesheetApprovalHistory' TimesheetApprovalHistory: type: object properties: action: type: string enum: - submitted - rejected - approved - discarded days: $ref: '#/components/schemas/ApprovalHistoryDays' user: type: integer comment: type: string createdAt: type: string TimesheetApprovalRequest: type: object properties: comment: type: string reviewer: type: integer description: User ID of the reviewer (must be a team admin). sendNotification: type: boolean TimesheetApprovalReviewRequest: type: object required: - status properties: status: type: string enum: - approved - rejected days: $ref: '#/components/schemas/ApprovalHistoryDays' comment: type: string sendNotification: type: boolean ApprovalHistoryDays: type: object properties: monday: type: boolean tuesday: type: boolean wednesday: type: boolean thursday: type: boolean friday: type: boolean saturday: type: boolean sunday: type: boolean Project: type: object properties: id: type: string description: 'Project ID in {platform code}:{platform ID} format.' name: type: string workspaceId: type: string workspaceName: type: string client: type: integer description: Client ID. type: type: string enum: - board - list favorite: type: boolean users: type: array description: Assigned user IDs. items: type: integer billing: $ref: '#/components/schemas/ProjectBillingBilling' rate: $ref: '#/components/schemas/ProjectBillingRate' budget: $ref: '#/components/schemas/ProjectBillingBudget' ProjectRequest: type: object required: - name - type properties: name: type: string type: type: string enum: - board - list users: type: array description: Assigned user IDs. items: type: integer ProjectBilling: type: object properties: billing: $ref: '#/components/schemas/ProjectBillingBilling' rate: $ref: '#/components/schemas/ProjectBillingRate' budget: $ref: '#/components/schemas/ProjectBillingBudget' ProjectBillingBilling: type: object properties: type: type: string enum: - non_billable - hourly - fixed_fee fee: type: integer description: Fixed fee in cents (fixed_fee type only). ProjectBillingRate: type: object properties: type: type: string enum: - project_rate - user_rate rate: type: integer description: Flat rate in cents per hour (project_rate type only). userRateOverrides: type: object description: Per-user rate overrides in cents per hour, keyed by user ID. additionalProperties: type: integer ProjectBillingBudget: type: object properties: type: type: string description: Budget type - money, time, or costs. enum: - money - time - costs budget: type: integer description: Budget value in cents (money) or seconds (time). progress: type: integer readOnly: true description: Current budget usage in cents or seconds. timeProgress: type: integer readOnly: true expenseProgress: type: integer readOnly: true period: type: string enum: - general - monthly - weekly - daily appliedFrom: type: string format: date disallowOverbudget: type: boolean excludeUnbillableTime: type: boolean excludeExpenses: type: boolean showToUsers: type: boolean threshold: type: integer description: Email admins when this percentage (1-100) of the budget is reached. Section: type: object properties: id: type: integer name: type: string project: type: string position: type: integer status: type: string enum: - open - archived SectionRequest: type: object required: - name properties: name: type: string position: type: integer status: type: string enum: - open - archived Task: type: object properties: id: type: string description: 'Task ID (for example ev:9876543210).' name: type: string projects: type: array description: Project IDs. items: type: string section: type: integer description: Section ID. labels: type: array items: type: string position: type: integer description: type: string dueAt: type: string status: type: string enum: - open - closed time: $ref: '#/components/schemas/TaskTime' estimate: $ref: '#/components/schemas/TaskEstimate' unbillable: type: boolean TaskRequest: type: object required: - name properties: name: type: string section: type: integer description: Section ID. labels: type: array items: type: string position: type: integer description: type: string dueOn: type: string format: date assignees: type: array items: type: object properties: userId: type: integer status: type: string enum: - open - closed TaskTime: type: object properties: total: type: integer description: Total task time in seconds. users: type: object description: Task time in seconds keyed by user ID. additionalProperties: type: integer TaskEstimate: type: object properties: total: type: integer description: Total task estimate in seconds. type: type: string enum: - overall - users users: type: object description: Task estimate in seconds keyed by user ID. additionalProperties: type: integer Assignment: type: object properties: id: type: integer days: type: integer description: Number of workdays. startDate: type: string format: date endDate: type: string format: date project: type: string time: type: integer description: Scheduled time in seconds. type: type: string enum: - project - time-off user: type: integer AssignmentRequest: type: object properties: startDate: type: string format: date endDate: type: string format: date project: type: string time: type: integer description: Scheduled time in seconds. type: type: string enum: - project - time-off user: type: integer users: type: array description: Create the same schedule for multiple team users. items: type: integer timeOffType: type: integer description: Time off type ID (time-off type only). timeOffPeriod: type: string enum: - full-day - half-of-day - quarter-of-day - half-and-quarter-of-day status: type: string description: Admins can set approved on create; regular users create pending time off. enum: - pending - approved reviewer: type: integer description: Admin who receives the approval notification. sendNotification: type: boolean considerAllocations: type: boolean forceOverride: type: boolean TimeOffType: type: object properties: id: type: integer name: type: string color: type: string paid: type: boolean description: type: string TimeOffTypeRequest: type: object required: - name properties: name: type: string color: type: string paid: type: boolean description: type: string TimeOffAllocation: type: object properties: id: type: integer startDate: type: string format: date endDate: type: string format: date contractStartDate: type: string format: date user: type: integer timeOffType: type: integer days: type: number daysCarried: type: number daysAllocated: type: number daysUsed: type: number accrualFrequency: type: string enum: - daily - immediately restrictOverAllocation: type: boolean completed: type: boolean notes: type: string createdBy: type: integer createdAt: type: string TimeOffAllocationRequest: type: object properties: startDate: type: string format: date endDate: type: string format: date contractStartDate: type: string format: date users: type: array items: type: integer timeOffType: type: integer days: type: number daysCarried: type: number accrualFrequency: type: string enum: - daily - immediately restrictOverAllocation: type: boolean completed: type: boolean notes: type: string Client: type: object properties: id: type: integer name: type: string projects: type: array description: Project IDs linked to the client. items: type: string businessDetails: type: string budget: $ref: '#/components/schemas/ClientBudget' ClientRequest: type: object required: - name properties: name: type: string projects: type: array items: type: string businessDetails: type: string ClientBudget: type: object required: - type - budget - period properties: type: type: string description: Budget type - money, time, or costs. enum: - money - time - costs budget: type: integer description: Budget value in cents (money) or seconds (time). period: type: string enum: - general - monthly - weekly - daily appliedFrom: type: string format: date disallowOverbudget: type: boolean excludeUnbillableTime: type: boolean excludeExpenses: type: boolean threshold: type: integer description: Email admins when this percentage (1-100) of the budget is reached. progress: type: integer readOnly: true description: Current budget usage in cents or seconds. Invoice: type: object properties: id: type: integer client: $ref: '#/components/schemas/Client' createdAt: type: string createdBy: $ref: '#/components/schemas/User' dueDate: type: string format: date issueDate: type: string format: date limitDateFrom: type: string format: date limitDateTill: type: string format: date discount: type: object properties: amount: type: integer rate: type: number tax: type: object properties: amount: type: integer rate: type: number includeExpenses: type: boolean includeTime: type: boolean invoiceItems: type: array items: $ref: '#/components/schemas/InvoiceItem' listAmount: type: integer description: List amount in cents (without discount and taxes). netAmount: type: integer description: Net amount in cents (with discount, without taxes). totalAmount: type: integer description: Total amount in cents (with discount and taxes). totalTime: type: integer description: Total invoice time in seconds. projects: type: array items: type: string publicId: type: string status: type: string enum: - draft - sent - paid InvoiceItem: type: object properties: id: type: integer name: type: string billedTime: type: integer description: Time in seconds. listAmount: type: integer description: Amount in cents. netAmount: type: integer totalAmount: type: integer custom: type: boolean taxable: type: integer position: type: integer createdAt: type: string InvoiceCreateRequest: type: object properties: limitDateFrom: type: string format: date limitDateTill: type: string format: date includeExpenses: type: boolean includeTime: type: boolean projects: type: array items: type: string tax: type: object properties: rate: type: number amount: type: integer discount: type: object properties: rate: type: number amount: type: integer InvoiceUpdateRequest: type: object properties: publicId: type: string issueDate: type: string format: date dueDate: type: string format: date reference: type: string publicNotes: type: string tax: type: object properties: rate: type: number amount: type: integer discount: type: object properties: rate: type: number amount: type: integer invoiceItems: type: array items: $ref: '#/components/schemas/InvoiceItem' InvoiceRefreshRequest: type: object properties: limitDateFrom: type: string format: date limitDateTill: type: string format: date includeExpenses: type: boolean includeTime: type: boolean projects: type: array items: type: string expenseMask: type: string timeMask: type: string Expense: type: object properties: id: type: integer amount: type: integer description: Amount in cents. attachments: type: array items: $ref: '#/components/schemas/AttachmentDetails' billable: type: boolean category: type: integer description: Expense category ID. date: type: string format: date details: type: string project: type: string quantity: type: number user: type: integer ExpenseRequest: type: object required: - category - date properties: amount: type: integer description: Amount in cents. attachments: type: array description: Attachment IDs. items: type: integer billable: type: boolean category: type: integer date: type: string format: date details: type: string project: type: string quantity: type: number user: type: integer ExpenseCategory: type: object properties: id: type: integer name: type: string color: type: string unitBased: type: boolean unitName: type: string unitPrice: type: integer ExpenseCategoryRequest: type: object required: - name properties: name: type: string color: type: string unitBased: type: boolean unitName: type: string unitPrice: type: integer AttachmentDetails: type: object properties: id: type: integer name: type: string token: type: string ProjectsDashboardItem: type: object description: Per-project report row. Time is in seconds and amounts in cents. properties: projectId: type: string projectName: type: string projectStatus: type: string enum: - open - archived clientId: type: integer clientName: type: string billingType: type: string enum: - non_billable - hourly - fixed_fee time: type: integer billableTime: type: integer nonBillableTime: type: integer billableAmount: type: integer costs: type: integer profit: type: integer uninvoicedAmount: type: integer expenses: type: integer ClientsDashboardItem: type: object description: Per-client report row. Time is in seconds and amounts in cents. properties: clientId: type: integer clientName: type: string time: type: integer billableTime: type: integer nonBillableTime: type: integer billableAmount: type: integer costs: type: integer profit: type: integer uninvoicedAmount: type: integer expenses: type: integer UsersDashboardItem: type: object description: Per-user report row. Time is in seconds and amounts in cents. properties: memberId: type: integer memberName: type: string memberHeadline: type: string memberStatus: type: string enum: - active - invited - pending - removed time: type: integer billableTime: type: integer nonBillableTime: type: integer timeOffTime: type: integer timeOffDays: type: number billableAmount: type: integer costs: type: integer profit: type: integer expenses: type: integer User: type: object properties: id: type: integer name: type: string headline: type: string avatarUrl: type: string role: type: string enum: - admin - supervisor - member status: type: string enum: - active - invited - pending - removed Webhook: type: object properties: id: type: integer targetUrl: type: string events: type: array description: Subscribed events, for example api:time:updated or api:timer:started. items: type: string project: type: string description: Optional project scope for events. isActive: type: boolean createdAt: type: string lastUsedAt: type: string WebhookRequest: type: object required: - targetUrl - events properties: targetUrl: type: string description: HTTPS endpoint that will receive event payloads. events: type: array description: >- Events to receive. Supported values include api:project:created, api:project:updated, api:project:removed, api:task:created, api:task:updated, api:task:removed, api:timer:started, api:timer:stopped, api:time:updated, api:section:created, api:section:updated, api:section:removed, api:client:created, api:client:updated, and api:estimate:updated. items: type: string project: type: string description: Receive events only for a specific project.