Documentation
Sign In

Time Entries

Log and manage tracked time. Entries flow through an approval workflow and can be rolled up into invoices.

Required scopes:time-entries:readtime-entries:write

All endpoints require authentication with an API key via Authorization: Bearer anch_... — see Authentication. A :write scope implicitly includes its :read scope.

Quick example

curl "https://your-domain.com/api/time-entries?dealId=dl_123&approvalStatus=approved" \
  -H "Authorization: Bearer anch_your_api_key"

Endpoints

GET/api/time-entries
POST/api/time-entries
GET/api/time-entries/{id}
PATCH/api/time-entries/{id}
DELETE/api/time-entries/{id}
POST/api/time-entries/{id}/approve
POST/api/time-entries/{id}/pay

GET/api/time-entries

Query parameters

FieldTypeDescription
taskIdstringFilter to a specific task
dealIdstringFilter to a specific deal
deliverableIdstringFilter to a specific deliverable
userIdstringFilter to entries logged by a user
approvalStatusstringpending, approved, or rejected
startDateintegerOnly entries on/after this time (Unix ms)
endDateintegerOnly entries on/before this time (Unix ms)
sortOrderstringasc or desc
limitintegerPage size (default: 50)
offsetintegerPagination offset (default: 0)

Response (200)

{
  "data": [ { "id": "te_...", "durationMinutes": 90, "billable": true, ... } ],
  "meta": { "total": 210, "limit": 50, "offset": 0 }
}

POST/api/time-entries

Body fields

FieldTypeDescription
durationMinutesrequiredintegerDuration in minutes
userIdstringUser the entry belongs to (defaults to key owner context)
taskIdstringAssociated task
dealIdstringAssociated deal
deliverableIdstringAssociated deliverable
descriptionstringWhat the time was spent on
startTimeinteger | stringStart time — Unix ms or ISO string
endTimeinteger | stringEnd time — Unix ms or ISO string
billablebooleanWhether the time is billable (default: true)
hourlyRateCentsintegerOverride rate in cents

Response (201)

{ "id": "te_V1StGXR8Z5jdHi6B" }

GET/api/time-entries/{id}

Response (200)

{
  "data": {
    "id": "te_V1StGXR8Z5jdHi6B",
    "organizationId": "org_4f90...",
    "userId": "usr_...",
    "taskId": "tsk_...",
    "dealId": "dl_...",
    "durationMinutes": 90,
    "description": "Implementation work",
    "billable": true,
    "hourlyRateCents": 15000,
    "approvalStatus": "pending",
    "createdAt": 1736899200000,
    "updatedAt": 1736899200000,
    "deletedAt": null
  }
}

PATCH/api/time-entries/{id}

PUT is also accepted. All fields are optional; only provided fields are updated.

Body fields

FieldTypeDescription
durationMinutesintegerDuration in minutes
userIdstringUser the entry belongs to (defaults to key owner context)
taskIdstringAssociated task
dealIdstringAssociated deal
deliverableIdstringAssociated deliverable
descriptionstringWhat the time was spent on
startTimeinteger | stringStart time — Unix ms or ISO string
endTimeinteger | stringEnd time — Unix ms or ISO string
billablebooleanWhether the time is billable (default: true)
hourlyRateCentsintegerOverride rate in cents

Response (200)

{ "ok": true }

DELETE/api/time-entries/{id}

Soft delete. With session auth this requires a manager or admin role.

Response (200)

{ "ok": true }

POST/api/time-entries/{id}/approve

Requires a manager or admin role. Sets the entry's approval status.

Body fields

FieldTypeDescription
approvalStatusrequiredstringpending, approved, or rejected
rejectionReasonstringReason shown to the submitter when rejecting

Response (200)

{ "id": "te_...", "approvalStatus": "approved", ... }

This endpoint returns the raw updated time entry object rather than the { data } envelope.

POST/api/time-entries/{id}/pay

Requires a manager or admin role. Records how the time was paid out.

Body fields

FieldTypeDescription
paymentMethodstringcash, check, business_account, personal_card, or other

Response (200)

{ "ok": true }

Enumerations

Approval statuses

  • pending
  • approved
  • rejected

Notes

  • The URL segment is hyphenated: /api/time-entries.