API reference

A predictable REST API for time, catalog, billing, and reporting data. Machine-readable spec: /api/v1/openapi.json (imports straight into Postman).

Authentication

Send Authorization: Bearer <token>. Two token kinds, both created on the in-app Developer page:

Endpoints marked manager+ or admin refuse lower-grade personal tokens — money (rates, invoices, reports) never reaches member tokens.

Conventions

Company

The authenticated workspace.

GET/v1/companyRetrieve the company
RESPONSES
  • 200OK
  • 401Missing, expired or invalid token
  • 403Token lacks the read scope
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE RESPONSE
{
  "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"
}

Time entries

Tracked time. Member-grade personal tokens see and modify only their own entries; submitted or approved weeks are locked.

GET/v1/time_entriesList time entries
PARAMETERS
  • fromOnly entries on/after this date (YYYY-MM-DD)
  • toOnly entries on/before this date
  • user_idFilter to one member
  • client_idFilter by client
  • project_idFilter by project
  • task_idFilter by task
  • billabletrue/false
  • is_billedtrue = already invoiced
  • is_runningtrue = timer currently running
  • approval_statusunsubmitted, submitted, or approved
  • external_reference_idMatch an external reference
  • updated_sinceISO 8601 datetime
  • pagePage number, starting at 1
  • per_pageItems per page (default 100, max 2000)
RESPONSES
  • 200OK
  • 401Missing, expired or invalid token
  • 403Token lacks the read scope
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE LIST
{
  "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 entry

Personal 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.

BODY
  • project_idUUID, required
  • task_idUUID, required
  • spent_dateYYYY-MM-DD, required
  • hoursDecimal hours (rounded per org policy). OMIT to start a running timer instead.
  • notesEntry notes
  • billableDefaults true
  • external_reference.idExternal system reference — import provenance, unique per org
  • issue_keyJira issue this entry is for, e.g. ACME-142. Several entries may share one.
  • user_idRequired with an organization key; ignored for personal tokens
RESPONSES
  • 201Created
  • 400Malformed JSON, or a field failed validation
  • 401Missing, expired or invalid token
  • 403Token lacks the write scope
  • 422Refused by a business rule — the message says which
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE RESPONSE
{
  "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 entry
PARAMETERS
  • id (required)The time entry id (UUID)
RESPONSES
  • 200OK
  • 401Missing, expired or invalid token
  • 403Token lacks the read scope
  • 404No such record in this workspace
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE RESPONSE
{
  "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 entry

Locked (approved/invoiced) and submitted entries return 422.

PARAMETERS
  • id (required)The time entry id (UUID)
BODY
  • project_idUUID
  • task_idUUID
  • spent_dateYYYY-MM-DD (target week must be open)
  • hoursDecimal hours
  • notesEntry notes
  • billabletrue/false
  • external_reference.idSet or replace the external reference
RESPONSES
  • 200OK
  • 400Malformed JSON, or a field failed validation
  • 401Missing, expired or invalid token
  • 403Token lacks the write scope
  • 404No such record in this workspace
  • 422Refused by a business rule — the message says which
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE RESPONSE
{
  "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 entry
PARAMETERS
  • id (required)The time entry id (UUID)
RESPONSES
  • 204Deleted. No body.
  • 400Malformed JSON, or a field failed validation
  • 401Missing, expired or invalid token
  • 403Token lacks the write scope
  • 404No such record in this workspace
  • 422Refused by a business rule — the message says which
  • 429Rate limited. Retry after the Retry-After header.
ERRORS
{
  "message": "Project not found"
}
PATCH/v1/time_entries/{id}/restartRestart the timer on an entry · personal token

Personal tokens only — timers belong to a person. Stops any other running timer.

PARAMETERS
  • id (required)The time entry id (UUID)
RESPONSES
  • 200OK
  • 400Malformed JSON, or a field failed validation
  • 401Missing, expired or invalid token
  • 403Token lacks the write scope or the required grade (personal)
  • 404No such record in this workspace
  • 422Refused by a business rule — the message says which
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE RESPONSE
{
  "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 entry

A timer that has run past the sanity cap refuses with 409 and a message; re-send with actual_hours to bank the real figure.

PARAMETERS
  • id (required)The time entry id (UUID)
BODY
  • actual_hoursHours actually worked. Only needed to stop a timer that ran implausibly long and was refused (409).
RESPONSES
  • 200OK
  • 400Malformed JSON, or a field failed validation
  • 401Missing, expired or invalid token
  • 403Token lacks the write scope
  • 404No such record in this workspace
  • 422Refused by a business rule — the message says which
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE RESPONSE
{
  "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 reference
PARAMETERS
  • id (required)The time entry id (UUID)
RESPONSES
  • 204Deleted. No body.
  • 400Malformed JSON, or a field failed validation
  • 401Missing, expired or invalid token
  • 403Token lacks the write scope
  • 404No such record in this workspace
  • 422Refused by a business rule — the message says which
  • 429Rate limited. Retry after the Retry-After header.
ERRORS
{
  "message": "Project not found"
}

Clients

Clients and their currencies.

GET/v1/clientsList clients
PARAMETERS
  • nameCase-insensitive name fragment
  • pagePage number, starting at 1
  • per_pageItems per page (default 100, max 2000)
RESPONSES
  • 200OK
  • 401Missing, expired or invalid token
  • 403Token lacks the read scope
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE LIST
{
  "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+
BODY
  • nameRequired
  • currency3-letter code
  • addressPostal address
  • notesNotes
RESPONSES
  • 201Created
  • 400Malformed JSON, or a field failed validation
  • 401Missing, expired or invalid token
  • 403Token lacks the write scope or the required grade (org-wide)
  • 422Refused by a business rule — the message says which
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE RESPONSE
{
  "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 client
PARAMETERS
  • id (required)The client id (UUID)
RESPONSES
  • 200OK
  • 401Missing, expired or invalid token
  • 403Token lacks the read scope
  • 404No such record in this workspace
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE RESPONSE
{
  "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+
PARAMETERS
  • id (required)The client id (UUID)
BODY
  • nameClient name
  • currency3-letter code
  • addressPostal address
  • notesNotes
RESPONSES
  • 200OK
  • 400Malformed JSON, or a field failed validation
  • 401Missing, expired or invalid token
  • 403Token lacks the write scope or the required grade (org-wide)
  • 404No such record in this workspace
  • 422Refused by a business rule — the message says which
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE RESPONSE
{
  "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.

PARAMETERS
  • id (required)The client id (UUID)
RESPONSES
  • 204Deleted. No body.
  • 400Malformed JSON, or a field failed validation
  • 401Missing, expired or invalid token
  • 403Token lacks the write scope or the required grade (org-wide)
  • 404No such record in this workspace
  • 422Refused by a business rule — the message says which
  • 429Rate limited. Retry after the Retry-After header.
ERRORS
{
  "message": "Project not found"
}

Projects

Projects, and who is assigned to them.

GET/v1/projectsList projects
PARAMETERS
  • client_idFilter by client
  • is_activetrue/false
  • pagePage number, starting at 1
  • per_pageItems per page (default 100, max 2000)
RESPONSES
  • 200OK
  • 401Missing, expired or invalid token
  • 403Token lacks the read scope
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE LIST
{
  "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+
BODY
  • client_idUUID, required
  • nameRequired
  • codeShort code
  • hourly_rateProject hourly rate
  • starts_onYYYY-MM-DD
  • ends_onYYYY-MM-DD
RESPONSES
  • 201Created
  • 400Malformed JSON, or a field failed validation
  • 401Missing, expired or invalid token
  • 403Token lacks the write scope or the required grade (org-wide)
  • 422Refused by a business rule — the message says which
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE RESPONSE
{
  "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 project
PARAMETERS
  • id (required)The project id (UUID)
RESPONSES
  • 200OK
  • 401Missing, expired or invalid token
  • 403Token lacks the read scope
  • 404No such record in this workspace
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE RESPONSE
{
  "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+
PARAMETERS
  • id (required)The project id (UUID)
BODY
  • client_idUUID
  • nameProject name
  • codeShort code
  • is_activefalse archives, true restores
  • hourly_rateProject hourly rate
  • starts_onYYYY-MM-DD
  • ends_onYYYY-MM-DD
RESPONSES
  • 200OK
  • 400Malformed JSON, or a field failed validation
  • 401Missing, expired or invalid token
  • 403Token lacks the write scope or the required grade (org-wide)
  • 404No such record in this workspace
  • 422Refused by a business rule — the message says which
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE RESPONSE
{
  "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+
PARAMETERS
  • id (required)The project id (UUID)
RESPONSES
  • 204Deleted. No body.
  • 400Malformed JSON, or a field failed validation
  • 401Missing, expired or invalid token
  • 403Token lacks the write scope or the required grade (org-wide)
  • 404No such record in this workspace
  • 422Refused by a business rule — the message says which
  • 429Rate limited. Retry after the Retry-After header.
ERRORS
{
  "message": "Project not found"
}
GET/v1/projects/{id}/user_assignmentsList a project’s people
PARAMETERS
  • id (required)The project id (UUID)
  • pagePage number, starting at 1
  • per_pageItems per page (default 100, max 2000)
RESPONSES
  • 200OK
  • 401Missing, expired or invalid token
  • 403Token lacks the read scope
  • 404No such record in this workspace
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE LIST
{
  "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+
PARAMETERS
  • id (required)The project id (UUID)
BODY
  • user_idMember UUID, required
  • is_project_managerGrants the PM flag
  • hourly_ratePer-assignment billable rate
RESPONSES
  • 201Created
  • 400Malformed JSON, or a field failed validation
  • 401Missing, expired or invalid token
  • 403Token lacks the write scope or the required grade (org-wide)
  • 404No such record in this workspace
  • 422Refused by a business rule — the message says which
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE RESPONSE
{
  "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+
PARAMETERS
  • id (required)The project id (UUID)
  • assignmentId (required)Assignment UUID
BODY
  • is_project_managerPM flag
  • hourly_ratePer-assignment billable rate
RESPONSES
  • 200OK
  • 400Malformed JSON, or a field failed validation
  • 401Missing, expired or invalid token
  • 403Token lacks the write scope or the required grade (org-wide)
  • 404No such record in this workspace
  • 422Refused by a business rule — the message says which
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE RESPONSE
{
  "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+
PARAMETERS
  • id (required)The project id (UUID)
  • assignmentId (required)Assignment UUID
RESPONSES
  • 204Deleted. No body.
  • 400Malformed JSON, or a field failed validation
  • 401Missing, expired or invalid token
  • 403Token lacks the write scope or the required grade (org-wide)
  • 404No such record in this workspace
  • 422Refused by a business rule — the message says which
  • 429Rate limited. Retry after the Retry-After header.
ERRORS
{
  "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.

PARAMETERS
  • id (required)The project id (UUID)
  • pagePage number, starting at 1
  • per_pageItems per page (default 100, max 2000)
RESPONSES
  • 200OK
  • 401Missing, expired or invalid token
  • 403Token lacks the read scope
  • 404No such record in this workspace
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE LIST
{
  "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

Tasks (each belongs to one project).

GET/v1/tasksList tasks
PARAMETERS
  • project_idFilter by project
  • pagePage number, starting at 1
  • per_pageItems per page (default 100, max 2000)
RESPONSES
  • 200OK
  • 401Missing, expired or invalid token
  • 403Token lacks the read scope
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE LIST
{
  "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+
BODY
  • project_idUUID, required
  • nameRequired
  • billable_by_defaultDefaults true
  • default_hourly_rateTask rate
RESPONSES
  • 201Created
  • 400Malformed JSON, or a field failed validation
  • 401Missing, expired or invalid token
  • 403Token lacks the write scope or the required grade (org-wide)
  • 422Refused by a business rule — the message says which
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE RESPONSE
{
  "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 task
PARAMETERS
  • id (required)The task id (UUID)
RESPONSES
  • 200OK
  • 401Missing, expired or invalid token
  • 403Token lacks the read scope
  • 404No such record in this workspace
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE RESPONSE
{
  "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+
PARAMETERS
  • id (required)The task id (UUID)
BODY
  • nameTask name
  • billable_by_defaulttrue/false
  • default_hourly_rateTask rate
RESPONSES
  • 200OK
  • 400Malformed JSON, or a field failed validation
  • 401Missing, expired or invalid token
  • 403Token lacks the write scope or the required grade (org-wide)
  • 404No such record in this workspace
  • 422Refused by a business rule — the message says which
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE RESPONSE
{
  "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+
PARAMETERS
  • id (required)The task id (UUID)
RESPONSES
  • 204Deleted. No body.
  • 400Malformed JSON, or a field failed validation
  • 401Missing, expired or invalid token
  • 403Token lacks the write scope or the required grade (org-wide)
  • 404No such record in this workspace
  • 422Refused by a business rule — the message says which
  • 429Rate limited. Retry after the Retry-After header.
ERRORS
{
  "message": "Project not found"
}

Users

Workspace members. Rates are money — manager+ tokens only.

GET/v1/usersList users
PARAMETERS
  • roleowner, admin, manager, or member
  • pagePage number, starting at 1
  • per_pageItems per page (default 100, max 2000)
RESPONSES
  • 200OK
  • 401Missing, expired or invalid token
  • 403Token lacks the read scope
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE LIST
{
  "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
RESPONSES
  • 200OK
  • 401Missing, expired or invalid token
  • 403Token lacks the read scope or the required grade (personal)
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE RESPONSE
{
  "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 user
PARAMETERS
  • id (required)The user id (UUID)
RESPONSES
  • 200OK
  • 401Missing, expired or invalid token
  • 403Token lacks the read scope
  • 404No such record in this workspace
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE RESPONSE
{
  "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+
PARAMETERS
  • id (required)The user id (UUID)
  • pagePage number, starting at 1
  • per_pageItems per page (default 100, max 2000)
RESPONSES
  • 200OK
  • 401Missing, expired or invalid token
  • 403Token lacks the read scope or the required grade (org-wide)
  • 404No such record in this workspace
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE LIST
{
  "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+
PARAMETERS
  • id (required)The user id (UUID)
  • pagePage number, starting at 1
  • per_pageItems per page (default 100, max 2000)
RESPONSES
  • 200OK
  • 401Missing, expired or invalid token
  • 403Token lacks the read scope or the required grade (org-wide)
  • 404No such record in this workspace
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE LIST
{
  "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 assignments
PARAMETERS
  • id (required)The user id (UUID)
  • pagePage number, starting at 1
  • per_pageItems per page (default 100, max 2000)
RESPONSES
  • 200OK
  • 401Missing, expired or invalid token
  • 403Token lacks the read scope
  • 404No such record in this workspace
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE LIST
{
  "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 reports
PARAMETERS
  • id (required)The user id (UUID)
  • pagePage number, starting at 1
  • per_pageItems per page (default 100, max 2000)
RESPONSES
  • 200OK
  • 401Missing, expired or invalid token
  • 403Token lacks the read scope
  • 404No such record in this workspace
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE LIST
{
  "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"
}

Roles

Work roles (job functions), assignable to members.

GET/v1/rolesList roles
PARAMETERS
  • pagePage number, starting at 1
  • per_pageItems per page (default 100, max 2000)
RESPONSES
  • 200OK
  • 401Missing, expired or invalid token
  • 403Token lacks the read scope
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE LIST
{
  "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+
BODY
  • nameRequired
RESPONSES
  • 201Created
  • 400Malformed JSON, or a field failed validation
  • 401Missing, expired or invalid token
  • 403Token lacks the write scope or the required grade (org-wide)
  • 422Refused by a business rule — the message says which
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE RESPONSE
{
  "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+
PARAMETERS
  • id (required)The role id (UUID)
BODY
  • nameRequired
RESPONSES
  • 200OK
  • 400Malformed JSON, or a field failed validation
  • 401Missing, expired or invalid token
  • 403Token lacks the write scope or the required grade (org-wide)
  • 404No such record in this workspace
  • 422Refused by a business rule — the message says which
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE RESPONSE
{
  "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+
PARAMETERS
  • id (required)The role id (UUID)
RESPONSES
  • 204Deleted. No body.
  • 400Malformed JSON, or a field failed validation
  • 401Missing, expired or invalid token
  • 403Token lacks the write scope or the required grade (org-wide)
  • 404No such record in this workspace
  • 422Refused by a business rule — the message says which
  • 429Rate limited. Retry after the Retry-After header.
ERRORS
{
  "message": "Project not found"
}

Invoices

Invoices, payments, and sending. Admin tokens or organization keys only.

GET/v1/invoicesList invoices
PARAMETERS
  • statedraft, open, partially_paid, paid, closed
  • client_idFilter by client
  • pagePage number, starting at 1
  • per_pageItems per page (default 100, max 2000)
RESPONSES
  • 200OK
  • 401Missing, expired or invalid token
  • 403Token lacks the read scope
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE LIST
{
  "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 · admin

Provide line_items OR period_start+period_end. Generated invoices mark hours billed so nothing is double-invoiced.

BODY
  • client_idUUID, required
  • line_itemsArray of {kind, description, quantity, unit_price} for a free-form invoice
  • period_startWith period_end: generate from uninvoiced time instead
  • period_endYYYY-MM-DD
  • groupingtask (default), person, or detailed
  • include_expensesDefaults true
  • subjectSubject line
  • issue_dateDefaults today
  • due_dateYYYY-MM-DD
  • taxPercent
  • discountPercent
RESPONSES
  • 201Created
  • 400Malformed JSON, or a field failed validation
  • 401Missing, expired or invalid token
  • 403Token lacks the write scope or the required grade (admin)
  • 422Refused by a business rule — the message says which
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE RESPONSE
{
  "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)
PARAMETERS
  • id (required)The invoice id (UUID)
RESPONSES
  • 200OK
  • 401Missing, expired or invalid token
  • 403Token lacks the read scope
  • 404No such record in this workspace
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE RESPONSE
{
  "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-invoice

Returns application/xml (not the JSON envelope). Supplier details come from Invoices → Configure → Company info.

PARAMETERS
  • id (required)The invoice id (UUID)
RESPONSES
  • 200OK
  • 401Missing, expired or invalid token
  • 403Token lacks the read scope
  • 404No such record in this workspace
  • 429Rate limited. Retry after the Retry-After header.
ERRORS
{
  "message": "Project not found"
}
PATCH/v1/invoices/{id}Update a draft invoice · admin
PARAMETERS
  • id (required)The invoice id (UUID)
BODY
  • subjectSubject
  • notesNotes
  • issue_dateYYYY-MM-DD
  • due_dateYYYY-MM-DD
  • taxPercent
  • discountPercent
RESPONSES
  • 200OK
  • 400Malformed JSON, or a field failed validation
  • 401Missing, expired or invalid token
  • 403Token lacks the write scope or the required grade (admin)
  • 404No such record in this workspace
  • 422Refused by a business rule — the message says which
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE RESPONSE
{
  "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 · admin
PARAMETERS
  • id (required)The invoice id (UUID)
RESPONSES
  • 204Deleted. No body.
  • 400Malformed JSON, or a field failed validation
  • 401Missing, expired or invalid token
  • 403Token lacks the write scope or the required grade (admin)
  • 404No such record in this workspace
  • 422Refused by a business rule — the message says which
  • 429Rate limited. Retry after the Retry-After header.
ERRORS
{
  "message": "Project not found"
}
POST/v1/invoices/{id}/messagesMark an invoice sent · admin

Moves draft → open. Email delivery stays a deliberate in-app action.

PARAMETERS
  • id (required)The invoice id (UUID)
RESPONSES
  • 201Created
  • 400Malformed JSON, or a field failed validation
  • 401Missing, expired or invalid token
  • 403Token lacks the write scope or the required grade (admin)
  • 404No such record in this workspace
  • 422Refused by a business rule — the message says which
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE RESPONSE
{
  "id": "4d5e6f70-8192-4c3d-a4b5-c6d7e8f90a1b",
  "event_type": "send",
  "state": "open"
}
ERRORS
{
  "message": "Project not found"
}
POST/v1/invoices/{id}/paymentsRecord a payment · admin
PARAMETERS
  • id (required)The invoice id (UUID)
BODY
  • amountRequired
  • paid_dateYYYY-MM-DD, required
  • notesNotes
RESPONSES
  • 201Created
  • 400Malformed JSON, or a field failed validation
  • 401Missing, expired or invalid token
  • 403Token lacks the write scope or the required grade (admin)
  • 404No such record in this workspace
  • 422Refused by a business rule — the message says which
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE RESPONSE
{
  "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 · admin
PARAMETERS
  • id (required)The invoice id (UUID)
  • paymentId (required)Payment UUID
RESPONSES
  • 204Deleted. No body.
  • 400Malformed JSON, or a field failed validation
  • 401Missing, expired or invalid token
  • 403Token lacks the write scope or the required grade (admin)
  • 404No such record in this workspace
  • 422Refused by a business rule — the message says which
  • 429Rate limited. Retry after the Retry-After header.
ERRORS
{
  "message": "Project not found"
}

Estimates

Quotes that convert to invoices. Admin tokens or organization keys only.

GET/v1/estimatesList estimates · manager+
PARAMETERS
  • pagePage number, starting at 1
  • per_pageItems per page (default 100, max 2000)
RESPONSES
  • 200OK
  • 401Missing, expired or invalid token
  • 403Token lacks the read scope or the required grade (org-wide)
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE LIST
{
  "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 · admin
BODY
  • client_idUUID, required
  • line_itemsArray of {kind, description, quantity, unit_price}, required
  • subjectSubject
  • issue_dateDefaults today
  • taxPercent
  • discountPercent
RESPONSES
  • 201Created
  • 400Malformed JSON, or a field failed validation
  • 401Missing, expired or invalid token
  • 403Token lacks the write scope or the required grade (admin)
  • 422Refused by a business rule — the message says which
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE RESPONSE
{
  "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+
PARAMETERS
  • id (required)The estimate id (UUID)
RESPONSES
  • 200OK
  • 401Missing, expired or invalid token
  • 403Token lacks the read scope or the required grade (org-wide)
  • 404No such record in this workspace
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE RESPONSE
{
  "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 · admin
PARAMETERS
  • id (required)The estimate id (UUID)
BODY
  • statesent, accepted, or declined
RESPONSES
  • 200OK
  • 400Malformed JSON, or a field failed validation
  • 401Missing, expired or invalid token
  • 403Token lacks the write scope or the required grade (admin)
  • 404No such record in this workspace
  • 422Refused by a business rule — the message says which
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE RESPONSE
{
  "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 · admin
PARAMETERS
  • id (required)The estimate id (UUID)
RESPONSES
  • 204Deleted. No body.
  • 400Malformed JSON, or a field failed validation
  • 401Missing, expired or invalid token
  • 403Token lacks the write scope or the required grade (admin)
  • 404No such record in this workspace
  • 422Refused by a business rule — the message says which
  • 429Rate limited. Retry after the Retry-After header.
ERRORS
{
  "message": "Project not found"
}
POST/v1/estimates/{id}/convertConvert to a draft invoice · admin
PARAMETERS
  • id (required)The estimate id (UUID)
RESPONSES
  • 201Created
  • 400Malformed JSON, or a field failed validation
  • 401Missing, expired or invalid token
  • 403Token lacks the write scope or the required grade (admin)
  • 404No such record in this workspace
  • 422Refused by a business rule — the message says which
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE RESPONSE
{
  "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

Expenses and categories. Member tokens manage their own.

GET/v1/expensesList expenses
PARAMETERS
  • user_idRequired with an organization key
  • fromYYYY-MM-DD
  • toYYYY-MM-DD
  • pagePage number, starting at 1
  • per_pageItems per page (default 100, max 2000)
RESPONSES
  • 200OK
  • 401Missing, expired or invalid token
  • 403Token lacks the read scope
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE LIST
{
  "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 expense
BODY
  • spent_dateYYYY-MM-DD, required
  • total_costRequired
  • project_idUUID
  • expense_category_idUUID
  • billabletrue/false
  • is_reimbursabletrue/false
  • notesNotes
  • user_idRequired with an organization key
RESPONSES
  • 201Created
  • 400Malformed JSON, or a field failed validation
  • 401Missing, expired or invalid token
  • 403Token lacks the write scope
  • 422Refused by a business rule — the message says which
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE RESPONSE
{
  "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 expense
PARAMETERS
  • id (required)The expense id (UUID)
RESPONSES
  • 204Deleted. No body.
  • 400Malformed JSON, or a field failed validation
  • 401Missing, expired or invalid token
  • 403Token lacks the write scope
  • 404No such record in this workspace
  • 422Refused by a business rule — the message says which
  • 429Rate limited. Retry after the Retry-After header.
ERRORS
{
  "message": "Project not found"
}
GET/v1/expense_categoriesList expense categories
PARAMETERS
  • pagePage number, starting at 1
  • per_pageItems per page (default 100, max 2000)
RESPONSES
  • 200OK
  • 401Missing, expired or invalid token
  • 403Token lacks the read scope
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE LIST
{
  "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+
BODY
  • nameRequired
  • unit_priceFor unit-based categories
RESPONSES
  • 201Created
  • 400Malformed JSON, or a field failed validation
  • 401Missing, expired or invalid token
  • 403Token lacks the write scope or the required grade (org-wide)
  • 422Refused by a business rule — the message says which
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE RESPONSE
{
  "id": "a1b2c3d4-e5f6-4071-8293-a4b5c6d7e8f9",
  "name": "Software",
  "unit_price": null,
  "is_active": true
}
ERRORS
{
  "message": "Project not found"
}

Reports

Aggregations with money — manager+ tokens or organization keys.

GET/v1/reports/time/{dimension}Time report by clients, projects, tasks, or team · manager+
PARAMETERS
  • dimension (required)clients, projects, tasks, or team
  • from (required)YYYY-MM-DD
  • to (required)YYYY-MM-DD
RESPONSES
  • 200OK
  • 401Missing, expired or invalid token
  • 403Token lacks the read scope or the required grade (org-wide)
  • 404No such record in this workspace
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE RESPONSE
{
  "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+
PARAMETERS
  • dimension (required)categories, projects, or team
  • from (required)YYYY-MM-DD
  • to (required)YYYY-MM-DD
RESPONSES
  • 200OK
  • 401Missing, expired or invalid token
  • 403Token lacks the read scope or the required grade (org-wide)
  • 404No such record in this workspace
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE RESPONSE
{
  "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+
PARAMETERS
  • from (required)YYYY-MM-DD
  • to (required)YYYY-MM-DD
RESPONSES
  • 200OK
  • 401Missing, expired or invalid token
  • 403Token lacks the read scope or the required grade (org-wide)
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE LIST
{
  "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+
PARAMETERS
  • pagePage number, starting at 1
  • per_pageItems per page (default 100, max 2000)
RESPONSES
  • 200OK
  • 401Missing, expired or invalid token
  • 403Token lacks the read scope or the required grade (org-wide)
  • 429Rate limited. Retry after the Retry-After header.
EXAMPLE LIST
{
  "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"
}