A predictable REST API for time, catalog, billing, and reporting data. Machine-readable spec: /api/v1/openapi.json (imports straight into Postman).
Send Authorization: Bearer <token>. Two token kinds, both created on the in-app Developer page:
user_id.Endpoints marked manager+ or admin refuse lower-grade personal tokens — money (rates, invoices, reports) never reaches member tokens.
per_page, total_pages, total_entries, next_page, previous_page, and a links object.{"message": "…"} with meaningful status codes; business rules refuse with 422.Retry-After).Idempotency-Key header (any unique string, ≤255 chars) with POSTs. Retrying with the same key and payload within 24 hours replays the original response (Idempotency-Replayed: true) instead of creating a duplicate; the same key with a different payload is refused with 422.approval_status maps open and rejected weeks to unsubmitted.The authenticated workspace.
GET/v1/companyRetrieve the company{
"name": "Fieldnote Studio",
"is_active": true,
"base_uri": "https://fieldnote.timetrakkr.com",
"full_domain": "fieldnote.timetrakkr.com",
"week_start_day": "Monday",
"currency": "USD",
"time_zone": "America/New_York"
}ERRORS{
"message": "Project not found"
}Tracked time. Member-grade personal tokens see and modify only their own entries; submitted or approved weeks are locked.
GET/v1/time_entriesList time entriesfrom — Only entries on/after this date (YYYY-MM-DD)to — Only entries on/before this dateuser_id — Filter to one memberclient_id — Filter by clientproject_id — Filter by projecttask_id — Filter by taskbillable — true/falseis_billed — true = already invoicedis_running — true = timer currently runningapproval_status — unsubmitted, submitted, or approvedexternal_reference_id — Match an external referenceupdated_since — ISO 8601 datetimepage — Page number, starting at 1per_page — Items per page (default 100, max 2000){
"time_entries": [
{
"id": "3f0a1c2e-5b6d-4e7f-8a90-1b2c3d4e5f60",
"spent_date": "2026-08-03",
"hours": 2,
"notes": "Homepage hero — second revision round",
"billable": true,
"is_locked": false,
"is_billed": false,
"is_running": false,
"approval_status": "unsubmitted",
"user": {
"id": "7a1b2c3d-4e5f-4061-8273-8495a6b7c8d9",
"name": "Priya Nair"
},
"project": {
"id": "9c8b7a65-4321-4fed-9876-543210fedcba",
"name": "Acme Rebrand"
},
"task": {
"id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
"name": "Design"
},
"client": {
"id": "2b3c4d5e-6f70-4b8c-9d0e-1f2a3b4c5d6e",
"name": "Acme Corp"
},
"external_reference": null,
"created_at": "2026-08-03T09:12:00.000Z",
"updated_at": "2026-08-03T09:12:00.000Z"
}
],
"per_page": 100,
"total_pages": 1,
"total_entries": 1,
"next_page": null,
"previous_page": null,
"page": 1,
"links": {
"first": "https://timetrakkr.com/api/v1/time_entries?page=1",
"next": null,
"previous": null,
"last": "https://timetrakkr.com/api/v1/time_entries?page=1"
}
}ERRORS{
"message": "Project not found"
}POST/v1/time_entriesCreate a time entryPersonal tokens log as their owner. Weeks already submitted for approval refuse new time (422). Omitting `hours` starts a running timer and returns the entry with `is_running` true.
BODYproject_id — UUID, requiredtask_id — UUID, requiredspent_date — YYYY-MM-DD, requiredhours — Decimal hours (rounded per org policy). OMIT to start a running timer instead.notes — Entry notesbillable — Defaults trueexternal_reference.id — External system reference — import provenance, unique per orgissue_key — Jira issue this entry is for, e.g. ACME-142. Several entries may share one.user_id — Required with an organization key; ignored for personal tokens{
"id": "3f0a1c2e-5b6d-4e7f-8a90-1b2c3d4e5f60",
"spent_date": "2026-08-03",
"hours": 2,
"notes": "Homepage hero — second revision round",
"billable": true,
"is_locked": false,
"is_billed": false,
"is_running": false,
"approval_status": "unsubmitted",
"user": {
"id": "7a1b2c3d-4e5f-4061-8273-8495a6b7c8d9",
"name": "Priya Nair"
},
"project": {
"id": "9c8b7a65-4321-4fed-9876-543210fedcba",
"name": "Acme Rebrand"
},
"task": {
"id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
"name": "Design"
},
"client": {
"id": "2b3c4d5e-6f70-4b8c-9d0e-1f2a3b4c5d6e",
"name": "Acme Corp"
},
"external_reference": null,
"created_at": "2026-08-03T09:12:00.000Z",
"updated_at": "2026-08-03T09:12:00.000Z"
}ERRORS{
"message": "Project not found"
}GET/v1/time_entries/{id}Retrieve a time entryid (required) — The time entry id (UUID){
"id": "3f0a1c2e-5b6d-4e7f-8a90-1b2c3d4e5f60",
"spent_date": "2026-08-03",
"hours": 2,
"notes": "Homepage hero — second revision round",
"billable": true,
"is_locked": false,
"is_billed": false,
"is_running": false,
"approval_status": "unsubmitted",
"user": {
"id": "7a1b2c3d-4e5f-4061-8273-8495a6b7c8d9",
"name": "Priya Nair"
},
"project": {
"id": "9c8b7a65-4321-4fed-9876-543210fedcba",
"name": "Acme Rebrand"
},
"task": {
"id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
"name": "Design"
},
"client": {
"id": "2b3c4d5e-6f70-4b8c-9d0e-1f2a3b4c5d6e",
"name": "Acme Corp"
},
"external_reference": null,
"created_at": "2026-08-03T09:12:00.000Z",
"updated_at": "2026-08-03T09:12:00.000Z"
}ERRORS{
"message": "Project not found"
}PATCH/v1/time_entries/{id}Update a time entryLocked (approved/invoiced) and submitted entries return 422.
PARAMETERSid (required) — The time entry id (UUID)project_id — UUIDtask_id — UUIDspent_date — YYYY-MM-DD (target week must be open)hours — Decimal hoursnotes — Entry notesbillable — true/falseexternal_reference.id — Set or replace the external reference{
"id": "3f0a1c2e-5b6d-4e7f-8a90-1b2c3d4e5f60",
"spent_date": "2026-08-03",
"hours": 2,
"notes": "Homepage hero — second revision round",
"billable": true,
"is_locked": false,
"is_billed": false,
"is_running": false,
"approval_status": "unsubmitted",
"user": {
"id": "7a1b2c3d-4e5f-4061-8273-8495a6b7c8d9",
"name": "Priya Nair"
},
"project": {
"id": "9c8b7a65-4321-4fed-9876-543210fedcba",
"name": "Acme Rebrand"
},
"task": {
"id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
"name": "Design"
},
"client": {
"id": "2b3c4d5e-6f70-4b8c-9d0e-1f2a3b4c5d6e",
"name": "Acme Corp"
},
"external_reference": null,
"created_at": "2026-08-03T09:12:00.000Z",
"updated_at": "2026-08-03T09:12:00.000Z"
}ERRORS{
"message": "Project not found"
}DELETE/v1/time_entries/{id}Delete a time entryid (required) — The time entry id (UUID){
"message": "Project not found"
}PATCH/v1/time_entries/{id}/restartRestart the timer on an entry · personal tokenPersonal tokens only — timers belong to a person. Stops any other running timer.
PARAMETERSid (required) — The time entry id (UUID){
"id": "3f0a1c2e-5b6d-4e7f-8a90-1b2c3d4e5f60",
"spent_date": "2026-08-03",
"hours": 2,
"notes": "Homepage hero — second revision round",
"billable": true,
"is_locked": false,
"is_billed": false,
"is_running": false,
"approval_status": "unsubmitted",
"user": {
"id": "7a1b2c3d-4e5f-4061-8273-8495a6b7c8d9",
"name": "Priya Nair"
},
"project": {
"id": "9c8b7a65-4321-4fed-9876-543210fedcba",
"name": "Acme Rebrand"
},
"task": {
"id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
"name": "Design"
},
"client": {
"id": "2b3c4d5e-6f70-4b8c-9d0e-1f2a3b4c5d6e",
"name": "Acme Corp"
},
"external_reference": null,
"created_at": "2026-08-03T09:12:00.000Z",
"updated_at": "2026-08-03T09:12:00.000Z"
}ERRORS{
"message": "Project not found"
}PATCH/v1/time_entries/{id}/stopStop the running timer on an entryA timer that has run past the sanity cap refuses with 409 and a message; re-send with actual_hours to bank the real figure.
PARAMETERSid (required) — The time entry id (UUID)actual_hours — Hours actually worked. Only needed to stop a timer that ran implausibly long and was refused (409).{
"id": "3f0a1c2e-5b6d-4e7f-8a90-1b2c3d4e5f60",
"spent_date": "2026-08-03",
"hours": 2,
"notes": "Homepage hero — second revision round",
"billable": true,
"is_locked": false,
"is_billed": false,
"is_running": false,
"approval_status": "unsubmitted",
"user": {
"id": "7a1b2c3d-4e5f-4061-8273-8495a6b7c8d9",
"name": "Priya Nair"
},
"project": {
"id": "9c8b7a65-4321-4fed-9876-543210fedcba",
"name": "Acme Rebrand"
},
"task": {
"id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
"name": "Design"
},
"client": {
"id": "2b3c4d5e-6f70-4b8c-9d0e-1f2a3b4c5d6e",
"name": "Acme Corp"
},
"external_reference": null,
"created_at": "2026-08-03T09:12:00.000Z",
"updated_at": "2026-08-03T09:12:00.000Z"
}ERRORS{
"message": "Project not found"
}DELETE/v1/time_entries/{id}/external_referenceRemove an entry’s external referenceid (required) — The time entry id (UUID){
"message": "Project not found"
}Clients and their currencies.
GET/v1/clientsList clientsname — Case-insensitive name fragmentpage — Page number, starting at 1per_page — Items per page (default 100, max 2000){
"clients": [
{
"id": "2b3c4d5e-6f70-4b8c-9d0e-1f2a3b4c5d6e",
"name": "Acme Corp",
"is_active": true,
"address": "14 Bridge Street, Bristol BS1 4TW",
"currency": "USD",
"created_at": "2026-08-03T09:12:00.000Z",
"updated_at": "2026-08-03T09:12:00.000Z"
}
],
"per_page": 100,
"total_pages": 1,
"total_entries": 1,
"next_page": null,
"previous_page": null,
"page": 1,
"links": {
"first": "https://timetrakkr.com/api/v1/clients?page=1",
"next": null,
"previous": null,
"last": "https://timetrakkr.com/api/v1/clients?page=1"
}
}ERRORS{
"message": "Project not found"
}POST/v1/clientsCreate a client · manager+name — Requiredcurrency — 3-letter codeaddress — Postal addressnotes — Notes{
"id": "2b3c4d5e-6f70-4b8c-9d0e-1f2a3b4c5d6e",
"name": "Acme Corp",
"is_active": true,
"address": "14 Bridge Street, Bristol BS1 4TW",
"currency": "USD",
"created_at": "2026-08-03T09:12:00.000Z",
"updated_at": "2026-08-03T09:12:00.000Z"
}ERRORS{
"message": "Project not found"
}GET/v1/clients/{id}Retrieve a clientid (required) — The client id (UUID){
"id": "2b3c4d5e-6f70-4b8c-9d0e-1f2a3b4c5d6e",
"name": "Acme Corp",
"is_active": true,
"address": "14 Bridge Street, Bristol BS1 4TW",
"currency": "USD",
"created_at": "2026-08-03T09:12:00.000Z",
"updated_at": "2026-08-03T09:12:00.000Z"
}ERRORS{
"message": "Project not found"
}PATCH/v1/clients/{id}Update a client · manager+id (required) — The client id (UUID)name — Client namecurrency — 3-letter codeaddress — Postal addressnotes — Notes{
"id": "2b3c4d5e-6f70-4b8c-9d0e-1f2a3b4c5d6e",
"name": "Acme Corp",
"is_active": true,
"address": "14 Bridge Street, Bristol BS1 4TW",
"currency": "USD",
"created_at": "2026-08-03T09:12:00.000Z",
"updated_at": "2026-08-03T09:12:00.000Z"
}ERRORS{
"message": "Project not found"
}DELETE/v1/clients/{id}Archive a client · manager+Refuses (422) while the client has active projects.
PARAMETERSid (required) — The client id (UUID){
"message": "Project not found"
}Projects, and who is assigned to them.
GET/v1/projectsList projectsclient_id — Filter by clientis_active — true/falsepage — Page number, starting at 1per_page — Items per page (default 100, max 2000){
"projects": [
{
"id": "9c8b7a65-4321-4fed-9876-543210fedcba",
"name": "Acme Rebrand",
"code": null,
"is_active": true,
"client": {
"id": "2b3c4d5e-6f70-4b8c-9d0e-1f2a3b4c5d6e",
"name": "Acme Corp"
},
"hourly_rate": 145,
"created_at": "2026-08-03T09:12:00.000Z",
"updated_at": "2026-08-03T09:12:00.000Z"
}
],
"per_page": 100,
"total_pages": 1,
"total_entries": 1,
"next_page": null,
"previous_page": null,
"page": 1,
"links": {
"first": "https://timetrakkr.com/api/v1/projects?page=1",
"next": null,
"previous": null,
"last": "https://timetrakkr.com/api/v1/projects?page=1"
}
}ERRORS{
"message": "Project not found"
}POST/v1/projectsCreate a project · manager+client_id — UUID, requiredname — Requiredcode — Short codehourly_rate — Project hourly ratestarts_on — YYYY-MM-DDends_on — YYYY-MM-DD{
"id": "9c8b7a65-4321-4fed-9876-543210fedcba",
"name": "Acme Rebrand",
"code": null,
"is_active": true,
"client": {
"id": "2b3c4d5e-6f70-4b8c-9d0e-1f2a3b4c5d6e",
"name": "Acme Corp"
},
"hourly_rate": 145,
"created_at": "2026-08-03T09:12:00.000Z",
"updated_at": "2026-08-03T09:12:00.000Z"
}ERRORS{
"message": "Project not found"
}GET/v1/projects/{id}Retrieve a projectid (required) — The project id (UUID){
"id": "9c8b7a65-4321-4fed-9876-543210fedcba",
"name": "Acme Rebrand",
"code": null,
"is_active": true,
"client": {
"id": "2b3c4d5e-6f70-4b8c-9d0e-1f2a3b4c5d6e",
"name": "Acme Corp"
},
"hourly_rate": 145,
"created_at": "2026-08-03T09:12:00.000Z",
"updated_at": "2026-08-03T09:12:00.000Z"
}ERRORS{
"message": "Project not found"
}PATCH/v1/projects/{id}Update a project · manager+id (required) — The project id (UUID)client_id — UUIDname — Project namecode — Short codeis_active — false archives, true restoreshourly_rate — Project hourly ratestarts_on — YYYY-MM-DDends_on — YYYY-MM-DD{
"id": "9c8b7a65-4321-4fed-9876-543210fedcba",
"name": "Acme Rebrand",
"code": null,
"is_active": true,
"client": {
"id": "2b3c4d5e-6f70-4b8c-9d0e-1f2a3b4c5d6e",
"name": "Acme Corp"
},
"hourly_rate": 145,
"created_at": "2026-08-03T09:12:00.000Z",
"updated_at": "2026-08-03T09:12:00.000Z"
}ERRORS{
"message": "Project not found"
}DELETE/v1/projects/{id}Archive a project · manager+id (required) — The project id (UUID){
"message": "Project not found"
}GET/v1/projects/{id}/user_assignmentsList a project’s peopleid (required) — The project id (UUID)page — Page number, starting at 1per_page — Items per page (default 100, max 2000){
"user_assignments": [
{
"id": "5e6f7081-92a3-4d4e-b5c6-d7e8f90a1b2c",
"is_project_manager": false,
"is_active": true,
"hourly_rate": 145,
"user": {
"id": "7a1b2c3d-4e5f-4061-8273-8495a6b7c8d9",
"name": "Priya Nair"
},
"project": {
"id": "9c8b7a65-4321-4fed-9876-543210fedcba",
"name": "Acme Rebrand"
}
}
],
"per_page": 100,
"total_pages": 1,
"total_entries": 1,
"next_page": null,
"previous_page": null,
"page": 1,
"links": {
"first": "https://timetrakkr.com/api/v1/projects/ID/user_assignments?page=1",
"next": null,
"previous": null,
"last": "https://timetrakkr.com/api/v1/projects/ID/user_assignments?page=1"
}
}ERRORS{
"message": "Project not found"
}POST/v1/projects/{id}/user_assignmentsAssign a person to a project · manager+id (required) — The project id (UUID)user_id — Member UUID, requiredis_project_manager — Grants the PM flaghourly_rate — Per-assignment billable rate{
"id": "5e6f7081-92a3-4d4e-b5c6-d7e8f90a1b2c",
"is_project_manager": false,
"is_active": true,
"hourly_rate": 145,
"user": {
"id": "7a1b2c3d-4e5f-4061-8273-8495a6b7c8d9",
"name": "Priya Nair"
},
"project": {
"id": "9c8b7a65-4321-4fed-9876-543210fedcba",
"name": "Acme Rebrand"
}
}ERRORS{
"message": "Project not found"
}PATCH/v1/projects/{id}/user_assignments/{assignmentId}Update an assignment · manager+id (required) — The project id (UUID)assignmentId (required) — Assignment UUIDis_project_manager — PM flaghourly_rate — Per-assignment billable rate{
"id": "5e6f7081-92a3-4d4e-b5c6-d7e8f90a1b2c",
"is_project_manager": false,
"is_active": true,
"hourly_rate": 145,
"user": {
"id": "7a1b2c3d-4e5f-4061-8273-8495a6b7c8d9",
"name": "Priya Nair"
},
"project": {
"id": "9c8b7a65-4321-4fed-9876-543210fedcba",
"name": "Acme Rebrand"
}
}ERRORS{
"message": "Project not found"
}DELETE/v1/projects/{id}/user_assignments/{assignmentId}Remove an assignment · manager+id (required) — The project id (UUID)assignmentId (required) — Assignment UUID{
"message": "Project not found"
}GET/v1/projects/{id}/task_assignmentsList a project’s tasks (compatibility view)Tasks belong to projects here, so each task is its own assignment.
PARAMETERSid (required) — The project id (UUID)page — Page number, starting at 1per_page — Items per page (default 100, max 2000){
"tasks": [
{
"id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
"name": "Design",
"project_id": "9c8b7a65-4321-4fed-9876-543210fedcba",
"billable_by_default": true,
"default_hourly_rate": 145,
"is_active": true,
"created_at": "2026-08-03T09:12:00.000Z",
"updated_at": "2026-08-03T09:12:00.000Z"
}
],
"per_page": 100,
"total_pages": 1,
"total_entries": 1,
"next_page": null,
"previous_page": null,
"page": 1,
"links": {
"first": "https://timetrakkr.com/api/v1/projects/ID/task_assignments?page=1",
"next": null,
"previous": null,
"last": "https://timetrakkr.com/api/v1/projects/ID/task_assignments?page=1"
}
}ERRORS{
"message": "Project not found"
}Tasks (each belongs to one project).
GET/v1/tasksList tasksproject_id — Filter by projectpage — Page number, starting at 1per_page — Items per page (default 100, max 2000){
"tasks": [
{
"id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
"name": "Design",
"project_id": "9c8b7a65-4321-4fed-9876-543210fedcba",
"billable_by_default": true,
"default_hourly_rate": 145,
"is_active": true,
"created_at": "2026-08-03T09:12:00.000Z",
"updated_at": "2026-08-03T09:12:00.000Z"
}
],
"per_page": 100,
"total_pages": 1,
"total_entries": 1,
"next_page": null,
"previous_page": null,
"page": 1,
"links": {
"first": "https://timetrakkr.com/api/v1/tasks?page=1",
"next": null,
"previous": null,
"last": "https://timetrakkr.com/api/v1/tasks?page=1"
}
}ERRORS{
"message": "Project not found"
}POST/v1/tasksCreate a task · manager+project_id — UUID, requiredname — Requiredbillable_by_default — Defaults truedefault_hourly_rate — Task rate{
"id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
"name": "Design",
"project_id": "9c8b7a65-4321-4fed-9876-543210fedcba",
"billable_by_default": true,
"default_hourly_rate": 145,
"is_active": true,
"created_at": "2026-08-03T09:12:00.000Z",
"updated_at": "2026-08-03T09:12:00.000Z"
}ERRORS{
"message": "Project not found"
}GET/v1/tasks/{id}Retrieve a taskid (required) — The task id (UUID){
"id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
"name": "Design",
"project_id": "9c8b7a65-4321-4fed-9876-543210fedcba",
"billable_by_default": true,
"default_hourly_rate": 145,
"is_active": true,
"created_at": "2026-08-03T09:12:00.000Z",
"updated_at": "2026-08-03T09:12:00.000Z"
}ERRORS{
"message": "Project not found"
}PATCH/v1/tasks/{id}Update a task · manager+id (required) — The task id (UUID)name — Task namebillable_by_default — true/falsedefault_hourly_rate — Task rate{
"id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
"name": "Design",
"project_id": "9c8b7a65-4321-4fed-9876-543210fedcba",
"billable_by_default": true,
"default_hourly_rate": 145,
"is_active": true,
"created_at": "2026-08-03T09:12:00.000Z",
"updated_at": "2026-08-03T09:12:00.000Z"
}ERRORS{
"message": "Project not found"
}DELETE/v1/tasks/{id}Delete a task · manager+id (required) — The task id (UUID){
"message": "Project not found"
}Workspace members. Rates are money — manager+ tokens only.
GET/v1/usersList usersrole — owner, admin, manager, or memberpage — Page number, starting at 1per_page — Items per page (default 100, max 2000){
"users": [
{
"id": "7a1b2c3d-4e5f-4061-8273-8495a6b7c8d9",
"name": "Priya Nair",
"first_name": "Priya",
"last_name": "Nair",
"email": "[email protected]",
"is_active": true,
"access_roles": [
"member"
],
"created_at": "2026-08-03T09:12:00.000Z",
"updated_at": "2026-08-03T09:12:00.000Z"
}
],
"per_page": 100,
"total_pages": 1,
"total_entries": 1,
"next_page": null,
"previous_page": null,
"page": 1,
"links": {
"first": "https://timetrakkr.com/api/v1/users?page=1",
"next": null,
"previous": null,
"last": "https://timetrakkr.com/api/v1/users?page=1"
}
}ERRORS{
"message": "Project not found"
}GET/v1/users/meRetrieve the token’s owner · personal token{
"id": "7a1b2c3d-4e5f-4061-8273-8495a6b7c8d9",
"name": "Priya Nair",
"first_name": "Priya",
"last_name": "Nair",
"email": "[email protected]",
"is_active": true,
"access_roles": [
"member"
],
"created_at": "2026-08-03T09:12:00.000Z",
"updated_at": "2026-08-03T09:12:00.000Z"
}ERRORS{
"message": "Project not found"
}GET/v1/users/{id}Retrieve a userid (required) — The user id (UUID){
"id": "7a1b2c3d-4e5f-4061-8273-8495a6b7c8d9",
"name": "Priya Nair",
"first_name": "Priya",
"last_name": "Nair",
"email": "[email protected]",
"is_active": true,
"access_roles": [
"member"
],
"created_at": "2026-08-03T09:12:00.000Z",
"updated_at": "2026-08-03T09:12:00.000Z"
}ERRORS{
"message": "Project not found"
}GET/v1/users/{id}/billable_ratesList a user’s billable rates · manager+id (required) — The user id (UUID)page — Page number, starting at 1per_page — Items per page (default 100, max 2000){
"billable_rates": [
{
"id": "6f708192-a3b4-4e5f-c6d7-e8f90a1b2c3d",
"amount": 145,
"start_date": "2026-01-01",
"end_date": null
}
],
"per_page": 100,
"total_pages": 1,
"total_entries": 1,
"next_page": null,
"previous_page": null,
"page": 1,
"links": {
"first": "https://timetrakkr.com/api/v1/users/ID/billable_rates?page=1",
"next": null,
"previous": null,
"last": "https://timetrakkr.com/api/v1/users/ID/billable_rates?page=1"
}
}ERRORS{
"message": "Project not found"
}GET/v1/users/{id}/cost_ratesList a user’s cost rates · manager+id (required) — The user id (UUID)page — Page number, starting at 1per_page — Items per page (default 100, max 2000){
"cost_rates": [
{
"id": "6f708192-a3b4-4e5f-c6d7-e8f90a1b2c3d",
"amount": 68,
"start_date": "2026-01-01",
"end_date": null
}
],
"per_page": 100,
"total_pages": 1,
"total_entries": 1,
"next_page": null,
"previous_page": null,
"page": 1,
"links": {
"first": "https://timetrakkr.com/api/v1/users/ID/cost_rates?page=1",
"next": null,
"previous": null,
"last": "https://timetrakkr.com/api/v1/users/ID/cost_rates?page=1"
}
}ERRORS{
"message": "Project not found"
}GET/v1/users/{id}/project_assignmentsList a user’s project assignmentsid (required) — The user id (UUID)page — Page number, starting at 1per_page — Items per page (default 100, max 2000){
"user_assignments": [
{
"id": "5e6f7081-92a3-4d4e-b5c6-d7e8f90a1b2c",
"is_project_manager": false,
"is_active": true,
"hourly_rate": 145,
"user": {
"id": "7a1b2c3d-4e5f-4061-8273-8495a6b7c8d9",
"name": "Priya Nair"
},
"project": {
"id": "9c8b7a65-4321-4fed-9876-543210fedcba",
"name": "Acme Rebrand"
}
}
],
"per_page": 100,
"total_pages": 1,
"total_entries": 1,
"next_page": null,
"previous_page": null,
"page": 1,
"links": {
"first": "https://timetrakkr.com/api/v1/users/ID/project_assignments?page=1",
"next": null,
"previous": null,
"last": "https://timetrakkr.com/api/v1/users/ID/project_assignments?page=1"
}
}ERRORS{
"message": "Project not found"
}GET/v1/users/{id}/teammatesList a user’s direct reportsid (required) — The user id (UUID)page — Page number, starting at 1per_page — Items per page (default 100, max 2000){
"users": [
{
"id": "7a1b2c3d-4e5f-4061-8273-8495a6b7c8d9",
"name": "Priya Nair",
"first_name": "Priya",
"last_name": "Nair",
"email": "[email protected]",
"is_active": true,
"access_roles": [
"member"
],
"created_at": "2026-08-03T09:12:00.000Z",
"updated_at": "2026-08-03T09:12:00.000Z"
}
],
"per_page": 100,
"total_pages": 1,
"total_entries": 1,
"next_page": null,
"previous_page": null,
"page": 1,
"links": {
"first": "https://timetrakkr.com/api/v1/users/ID/teammates?page=1",
"next": null,
"previous": null,
"last": "https://timetrakkr.com/api/v1/users/ID/teammates?page=1"
}
}ERRORS{
"message": "Project not found"
}Work roles (job functions), assignable to members.
GET/v1/rolesList rolespage — Page number, starting at 1per_page — Items per page (default 100, max 2000){
"roles": [
{
"id": "80192a3b-4c5d-4f60-9718-293a4b5c6d7e",
"name": "Senior designer",
"created_at": "2026-08-03T09:12:00.000Z",
"updated_at": "2026-08-03T09:12:00.000Z"
}
],
"per_page": 100,
"total_pages": 1,
"total_entries": 1,
"next_page": null,
"previous_page": null,
"page": 1,
"links": {
"first": "https://timetrakkr.com/api/v1/roles?page=1",
"next": null,
"previous": null,
"last": "https://timetrakkr.com/api/v1/roles?page=1"
}
}ERRORS{
"message": "Project not found"
}POST/v1/rolesCreate a role · manager+name — Required{
"id": "80192a3b-4c5d-4f60-9718-293a4b5c6d7e",
"name": "Senior designer",
"created_at": "2026-08-03T09:12:00.000Z",
"updated_at": "2026-08-03T09:12:00.000Z"
}ERRORS{
"message": "Project not found"
}PATCH/v1/roles/{id}Update a role · manager+id (required) — The role id (UUID)name — Required{
"id": "80192a3b-4c5d-4f60-9718-293a4b5c6d7e",
"name": "Senior designer",
"created_at": "2026-08-03T09:12:00.000Z",
"updated_at": "2026-08-03T09:12:00.000Z"
}ERRORS{
"message": "Project not found"
}DELETE/v1/roles/{id}Delete a role · manager+id (required) — The role id (UUID){
"message": "Project not found"
}Invoices, payments, and sending. Admin tokens or organization keys only.
GET/v1/invoicesList invoicesstate — draft, open, partially_paid, paid, closedclient_id — Filter by clientpage — Page number, starting at 1per_page — Items per page (default 100, max 2000){
"invoices": [
{
"id": "4d5e6f70-8192-4c3d-a4b5-c6d7e8f90a1b",
"number": "1042",
"state": "draft",
"subject": "August retainer",
"client": {
"id": "2b3c4d5e-6f70-4b8c-9d0e-1f2a3b4c5d6e",
"name": "Acme Corp"
},
"amount": 5400,
"paid_amount": 0,
"due_amount": 5400,
"currency": "USD",
"issue_date": "2026-08-01",
"due_date": "2026-08-31",
"period_start": "2026-07-01",
"period_end": "2026-07-31",
"sent_at": null,
"created_at": "2026-08-03T09:12:00.000Z",
"updated_at": "2026-08-03T09:12:00.000Z"
}
],
"per_page": 100,
"total_pages": 1,
"total_entries": 1,
"next_page": null,
"previous_page": null,
"page": 1,
"links": {
"first": "https://timetrakkr.com/api/v1/invoices?page=1",
"next": null,
"previous": null,
"last": "https://timetrakkr.com/api/v1/invoices?page=1"
}
}ERRORS{
"message": "Project not found"
}POST/v1/invoicesCreate an invoice · adminProvide line_items OR period_start+period_end. Generated invoices mark hours billed so nothing is double-invoiced.
BODYclient_id — UUID, requiredline_items — Array of {kind, description, quantity, unit_price} for a free-form invoiceperiod_start — With period_end: generate from uninvoiced time insteadperiod_end — YYYY-MM-DDgrouping — task (default), person, or detailedinclude_expenses — Defaults truesubject — Subject lineissue_date — Defaults todaydue_date — YYYY-MM-DDtax — Percentdiscount — Percent{
"id": "4d5e6f70-8192-4c3d-a4b5-c6d7e8f90a1b",
"number": "1042",
"state": "draft",
"subject": "August retainer",
"client": {
"id": "2b3c4d5e-6f70-4b8c-9d0e-1f2a3b4c5d6e",
"name": "Acme Corp"
},
"amount": 5400,
"paid_amount": 0,
"due_amount": 5400,
"currency": "USD",
"issue_date": "2026-08-01",
"due_date": "2026-08-31",
"period_start": "2026-07-01",
"period_end": "2026-07-31",
"sent_at": null,
"created_at": "2026-08-03T09:12:00.000Z",
"updated_at": "2026-08-03T09:12:00.000Z"
}ERRORS{
"message": "Project not found"
}GET/v1/invoices/{id}Retrieve an invoice (lines + payments)id (required) — The invoice id (UUID){
"id": "4d5e6f70-8192-4c3d-a4b5-c6d7e8f90a1b",
"number": "1042",
"state": "draft",
"subject": "August retainer",
"client": {
"id": "2b3c4d5e-6f70-4b8c-9d0e-1f2a3b4c5d6e",
"name": "Acme Corp"
},
"amount": 5400,
"paid_amount": 0,
"due_amount": 5400,
"currency": "USD",
"issue_date": "2026-08-01",
"due_date": "2026-08-31",
"period_start": "2026-07-01",
"period_end": "2026-07-31",
"sent_at": null,
"created_at": "2026-08-03T09:12:00.000Z",
"updated_at": "2026-08-03T09:12:00.000Z"
}ERRORS{
"message": "Project not found"
}GET/v1/invoices/{id}/ublDownload the invoice as a UBL 2.1 (EN 16931) XML e-invoiceReturns application/xml (not the JSON envelope). Supplier details come from Invoices → Configure → Company info.
PARAMETERSid (required) — The invoice id (UUID){
"message": "Project not found"
}PATCH/v1/invoices/{id}Update a draft invoice · adminid (required) — The invoice id (UUID)subject — Subjectnotes — Notesissue_date — YYYY-MM-DDdue_date — YYYY-MM-DDtax — Percentdiscount — Percent{
"id": "4d5e6f70-8192-4c3d-a4b5-c6d7e8f90a1b",
"number": "1042",
"state": "draft",
"subject": "August retainer",
"client": {
"id": "2b3c4d5e-6f70-4b8c-9d0e-1f2a3b4c5d6e",
"name": "Acme Corp"
},
"amount": 5400,
"paid_amount": 0,
"due_amount": 5400,
"currency": "USD",
"issue_date": "2026-08-01",
"due_date": "2026-08-31",
"period_start": "2026-07-01",
"period_end": "2026-07-31",
"sent_at": null,
"created_at": "2026-08-03T09:12:00.000Z",
"updated_at": "2026-08-03T09:12:00.000Z"
}ERRORS{
"message": "Project not found"
}DELETE/v1/invoices/{id}Delete a draft invoice · adminid (required) — The invoice id (UUID){
"message": "Project not found"
}POST/v1/invoices/{id}/messagesMark an invoice sent · adminMoves draft → open. Email delivery stays a deliberate in-app action.
PARAMETERSid (required) — The invoice id (UUID){
"id": "4d5e6f70-8192-4c3d-a4b5-c6d7e8f90a1b",
"event_type": "send",
"state": "open"
}ERRORS{
"message": "Project not found"
}POST/v1/invoices/{id}/paymentsRecord a payment · adminid (required) — The invoice id (UUID)amount — Requiredpaid_date — YYYY-MM-DD, requirednotes — Notes{
"id": "4d5e6f70-8192-4c3d-a4b5-c6d7e8f90a1b",
"number": "1042",
"state": "draft",
"subject": "August retainer",
"client": {
"id": "2b3c4d5e-6f70-4b8c-9d0e-1f2a3b4c5d6e",
"name": "Acme Corp"
},
"amount": 5400,
"paid_amount": 0,
"due_amount": 5400,
"currency": "USD",
"issue_date": "2026-08-01",
"due_date": "2026-08-31",
"period_start": "2026-07-01",
"period_end": "2026-07-31",
"sent_at": null,
"created_at": "2026-08-03T09:12:00.000Z",
"updated_at": "2026-08-03T09:12:00.000Z"
}ERRORS{
"message": "Project not found"
}DELETE/v1/invoices/{id}/payments/{paymentId}Delete a payment · adminid (required) — The invoice id (UUID)paymentId (required) — Payment UUID{
"message": "Project not found"
}Quotes that convert to invoices. Admin tokens or organization keys only.
GET/v1/estimatesList estimates · manager+page — Page number, starting at 1per_page — Items per page (default 100, max 2000){
"estimates": [
{
"id": "b2c3d4e5-f607-4182-93a4-b5c6d7e8f90a",
"number": "204",
"state": "draft",
"subject": "Rebrand — phase two",
"client": {
"id": "2b3c4d5e-6f70-4b8c-9d0e-1f2a3b4c5d6e",
"name": "Acme Corp"
},
"amount": 18500,
"currency": "USD",
"issue_date": "2026-08-01",
"created_at": "2026-08-03T09:12:00.000Z"
}
],
"per_page": 100,
"total_pages": 1,
"total_entries": 1,
"next_page": null,
"previous_page": null,
"page": 1,
"links": {
"first": "https://timetrakkr.com/api/v1/estimates?page=1",
"next": null,
"previous": null,
"last": "https://timetrakkr.com/api/v1/estimates?page=1"
}
}ERRORS{
"message": "Project not found"
}POST/v1/estimatesCreate an estimate · adminclient_id — UUID, requiredline_items — Array of {kind, description, quantity, unit_price}, requiredsubject — Subjectissue_date — Defaults todaytax — Percentdiscount — Percent{
"id": "b2c3d4e5-f607-4182-93a4-b5c6d7e8f90a",
"number": "204",
"state": "draft",
"subject": "Rebrand — phase two",
"client": {
"id": "2b3c4d5e-6f70-4b8c-9d0e-1f2a3b4c5d6e",
"name": "Acme Corp"
},
"amount": 18500,
"currency": "USD",
"issue_date": "2026-08-01",
"created_at": "2026-08-03T09:12:00.000Z"
}ERRORS{
"message": "Project not found"
}GET/v1/estimates/{id}Retrieve an estimate · manager+id (required) — The estimate id (UUID){
"id": "b2c3d4e5-f607-4182-93a4-b5c6d7e8f90a",
"number": "204",
"state": "draft",
"subject": "Rebrand — phase two",
"client": {
"id": "2b3c4d5e-6f70-4b8c-9d0e-1f2a3b4c5d6e",
"name": "Acme Corp"
},
"amount": 18500,
"currency": "USD",
"issue_date": "2026-08-01",
"created_at": "2026-08-03T09:12:00.000Z"
}ERRORS{
"message": "Project not found"
}PATCH/v1/estimates/{id}Change estimate state · adminid (required) — The estimate id (UUID)state — sent, accepted, or declined{
"id": "b2c3d4e5-f607-4182-93a4-b5c6d7e8f90a",
"number": "204",
"state": "draft",
"subject": "Rebrand — phase two",
"client": {
"id": "2b3c4d5e-6f70-4b8c-9d0e-1f2a3b4c5d6e",
"name": "Acme Corp"
},
"amount": 18500,
"currency": "USD",
"issue_date": "2026-08-01",
"created_at": "2026-08-03T09:12:00.000Z"
}ERRORS{
"message": "Project not found"
}DELETE/v1/estimates/{id}Delete a draft estimate · adminid (required) — The estimate id (UUID){
"message": "Project not found"
}POST/v1/estimates/{id}/convertConvert to a draft invoice · adminid (required) — The estimate id (UUID){
"id": "4d5e6f70-8192-4c3d-a4b5-c6d7e8f90a1b",
"number": "1042",
"state": "draft",
"subject": "August retainer",
"client": {
"id": "2b3c4d5e-6f70-4b8c-9d0e-1f2a3b4c5d6e",
"name": "Acme Corp"
},
"amount": 5400,
"paid_amount": 0,
"due_amount": 5400,
"currency": "USD",
"issue_date": "2026-08-01",
"due_date": "2026-08-31",
"period_start": "2026-07-01",
"period_end": "2026-07-31",
"sent_at": null,
"created_at": "2026-08-03T09:12:00.000Z",
"updated_at": "2026-08-03T09:12:00.000Z"
}ERRORS{
"message": "Project not found"
}Expenses and categories. Member tokens manage their own.
GET/v1/expensesList expensesuser_id — Required with an organization keyfrom — YYYY-MM-DDto — YYYY-MM-DDpage — Page number, starting at 1per_page — Items per page (default 100, max 2000){
"expenses": [
{
"id": "90a1b2c3-d4e5-4f60-8172-93a4b5c6d7e8",
"spent_date": "2026-08-03",
"total_cost": 42.5,
"billable": true,
"is_reimbursable": true,
"notes": "Stock photography license",
"project": {
"name": "Acme Rebrand"
},
"client": {
"name": "Acme Corp"
},
"expense_category": {
"name": "Software"
},
"user": {
"id": "7a1b2c3d-4e5f-4061-8273-8495a6b7c8d9"
}
}
],
"per_page": 100,
"total_pages": 1,
"total_entries": 1,
"next_page": null,
"previous_page": null,
"page": 1,
"links": {
"first": "https://timetrakkr.com/api/v1/expenses?page=1",
"next": null,
"previous": null,
"last": "https://timetrakkr.com/api/v1/expenses?page=1"
}
}ERRORS{
"message": "Project not found"
}POST/v1/expensesCreate an expensespent_date — YYYY-MM-DD, requiredtotal_cost — Requiredproject_id — UUIDexpense_category_id — UUIDbillable — true/falseis_reimbursable — true/falsenotes — Notesuser_id — Required with an organization key{
"id": "90a1b2c3-d4e5-4f60-8172-93a4b5c6d7e8",
"spent_date": "2026-08-03",
"total_cost": 42.5,
"billable": true,
"is_reimbursable": true,
"notes": "Stock photography license",
"project": {
"name": "Acme Rebrand"
},
"client": {
"name": "Acme Corp"
},
"expense_category": {
"name": "Software"
},
"user": {
"id": "7a1b2c3d-4e5f-4061-8273-8495a6b7c8d9"
}
}ERRORS{
"message": "Project not found"
}DELETE/v1/expenses/{id}Delete an expenseid (required) — The expense id (UUID){
"message": "Project not found"
}GET/v1/expense_categoriesList expense categoriespage — Page number, starting at 1per_page — Items per page (default 100, max 2000){
"expense_categories": [
{
"id": "a1b2c3d4-e5f6-4071-8293-a4b5c6d7e8f9",
"name": "Software",
"unit_price": null,
"is_active": true
}
],
"per_page": 100,
"total_pages": 1,
"total_entries": 1,
"next_page": null,
"previous_page": null,
"page": 1,
"links": {
"first": "https://timetrakkr.com/api/v1/expense_categories?page=1",
"next": null,
"previous": null,
"last": "https://timetrakkr.com/api/v1/expense_categories?page=1"
}
}ERRORS{
"message": "Project not found"
}POST/v1/expense_categoriesCreate an expense category · manager+name — Requiredunit_price — For unit-based categories{
"id": "a1b2c3d4-e5f6-4071-8293-a4b5c6d7e8f9",
"name": "Software",
"unit_price": null,
"is_active": true
}ERRORS{
"message": "Project not found"
}Aggregations with money — manager+ tokens or organization keys.
GET/v1/reports/time/{dimension}Time report by clients, projects, tasks, or team · manager+dimension (required) — clients, projects, tasks, or teamfrom (required) — YYYY-MM-DDto (required) — YYYY-MM-DD{
"project": "Acme Rebrand",
"total_hours": 128.5,
"billable_hours": 119,
"billable_amount": 17255
}ERRORS{
"message": "Project not found"
}GET/v1/reports/expenses/{dimension}Expense report by categories, projects, or team · manager+dimension (required) — categories, projects, or teamfrom (required) — YYYY-MM-DDto (required) — YYYY-MM-DD{
"project": "Acme Rebrand",
"total_amount": 412.75,
"billable_amount": 380
}ERRORS{
"message": "Project not found"
}GET/v1/reports/project_budgetHours budget vs actual per project · manager+from (required) — YYYY-MM-DDto (required) — YYYY-MM-DD{
"results": [
{
"project_id": "9c8b7a65-4321-4fed-9876-543210fedcba",
"project_name": "Acme Rebrand",
"budget": 400,
"budget_spent": 328,
"budget_remaining": 72,
"budget_by": "project_hours",
"budget_people": []
}
],
"per_page": 100,
"total_pages": 1,
"total_entries": 1,
"next_page": null,
"previous_page": null,
"page": 1,
"links": {
"first": "https://timetrakkr.com/api/v1/reports/project_budget?page=1",
"next": null,
"previous": null,
"last": "https://timetrakkr.com/api/v1/reports/project_budget?page=1"
}
}ERRORS{
"message": "Project not found"
}GET/v1/reports/uninvoicedApproved, unbilled hours and amounts per project · manager+page — Page number, starting at 1per_page — Items per page (default 100, max 2000){
"results": [
{
"project_id": "9c8b7a65-4321-4fed-9876-543210fedcba",
"project_name": "Acme Rebrand",
"client_name": "Acme Corp",
"uninvoiced_hours": 22.75,
"uninvoiced_amount": 3298.75,
"uninvoiced_expenses": 42.5
}
],
"per_page": 100,
"total_pages": 1,
"total_entries": 1,
"next_page": null,
"previous_page": null,
"page": 1,
"links": {
"first": "https://timetrakkr.com/api/v1/reports/uninvoiced?page=1",
"next": null,
"previous": null,
"last": "https://timetrakkr.com/api/v1/reports/uninvoiced?page=1"
}
}ERRORS{
"message": "Project not found"
}