Skip to content

Time Entries API

Track time spent on tickets for billing and reporting.

Endpoints

MethodEndpointDescription
GET/time-entriesList time entries
POST/tickets/:ticket_id/time-entriesLog time on ticket
GET/time-entries/:idGet time entry
PATCH/time-entries/:idUpdate time entry
DELETE/time-entries/:idDelete time entry

List Time Entries

Terminal window
GET /api/v1/time-entries

Query Parameters

ParameterTypeDescription
ticket_iduuidFilter by ticket
user_iduuidFilter by team member
company_iduuidFilter by company
billablebooleanFilter billable only
date_fromdateEntries on or after date
date_todateEntries on or before date
pageintegerPage number
per_pageintegerItems per page

Response

{
"data": [
{
"id": "entry-uuid",
"ticket": {
"id": "ticket-uuid",
"code": "ACME-42",
"subject": "Cannot login"
},
"user": {
"id": "user-uuid",
"name": "Jane Agent"
},
"duration_minutes": 45,
"description": "Investigated login issue, reset password",
"billable": true,
"rate": 150.00,
"currency": "USD",
"amount": 112.50,
"date": "2024-01-15",
"created_at": "2024-01-15T11:30:00Z"
}
],
"meta": {
"total": 523,
"page": 1,
"per_page": 20,
"totals": {
"duration_minutes": 12450,
"billable_amount": 31125.00
}
}
}

Log Time

Terminal window
POST /api/v1/tickets/:ticket_id/time-entries

Request Body

{
"duration_minutes": 45,
"description": "Investigated login issue, reset password",
"billable": true,
"date": "2024-01-15",
"rate": 150.00
}
FieldTypeRequiredDescription
duration_minutesintegerYesTime in minutes
descriptionstringNoWork description
billablebooleanNoBillable time (default: true)
datedateNoDate of work (default: today)
ratedecimalNoOverride hourly rate

Response

{
"data": {
"id": "entry-uuid",
"ticket": { ... },
"user": { ... },
"duration_minutes": 45,
"description": "Investigated login issue, reset password",
"billable": true,
"rate": 150.00,
"currency": "USD",
"amount": 112.50,
"date": "2024-01-15",
"created_at": "2024-01-15T11:30:00Z"
}
}

Rate Calculation

If rate is not provided, it’s determined by:

  1. Company rate (if ticket has a company with rate set)
  2. User rate (team member’s default rate)
  3. Organization default rate

The amount is calculated as:

amount = (duration_minutes / 60) * rate

Duration Formats

The API accepts minutes, but you can calculate from various formats:

InputMinutes
1 hour60
1h 30m90
1.5 hours90
45 minutes45

Get Time Entry

Terminal window
GET /api/v1/time-entries/:id

Returns full time entry details.

Update Time Entry

Terminal window
PATCH /api/v1/time-entries/:id
{
"duration_minutes": 60,
"description": "Updated description",
"billable": false
}

Delete Time Entry

Terminal window
DELETE /api/v1/time-entries/:id

Response

204 No Content

Timer (Coming Soon)

Live timer endpoints for real-time tracking:

Terminal window
# Start timer
POST /api/v1/tickets/:ticket_id/timer/start
# Stop timer
POST /api/v1/tickets/:ticket_id/timer/stop
# Get active timer
GET /api/v1/timer/active

Reporting

Summary by Company

Terminal window
GET /api/v1/time-entries/summary?group_by=company&date_from=2024-01-01&date_to=2024-01-31
{
"data": [
{
"company": { "id": "...", "name": "Acme Corp" },
"total_minutes": 1250,
"billable_minutes": 1100,
"total_amount": 2750.00,
"currency": "USD"
}
]
}

Summary by User

Terminal window
GET /api/v1/time-entries/summary?group_by=user&date_from=2024-01-01&date_to=2024-01-31

Export

Terminal window
GET /api/v1/time-entries/export?format=csv&date_from=2024-01-01&date_to=2024-01-31

Returns CSV with columns:

  • Date
  • Ticket Code
  • Ticket Subject
  • Company
  • User
  • Duration
  • Description
  • Billable
  • Rate
  • Amount
  • Currency

Error Codes

CodeDescription
TICKET_NOT_FOUNDTicket doesn’t exist
TIME_ENTRY_NOT_FOUNDTime entry doesn’t exist
INVALID_DURATIONDuration must be positive
UNAUTHORIZEDCan only edit own entries (non-admin)