Time Entries API
Time entries record work performed for clients. They can be logged against clients, projects, tickets, or retainer agreements and form the basis for invoicing.
The Time Entry Object
{
"id": "time_cuid123456",
"user_id": "usr_xxxxx",
"date": "2026-01-25",
"hours": 2.50,
"description": "Implemented contact form validation",
"client_id": "cli_xxxxx",
"project_id": "prj_xxxxx",
"ticket_id": "tkt_xxxxx",
"agreement_id": null,
"period_id": null,
"billing": {
"billable": true,
"billed": false,
"rate_id": "rate_xxxxx",
"rate_type": "standard",
"rate_charged": 150.00,
"rate_override": false,
"invoice_line_id": null
},
"exclusion": {
"excluded": false,
"reason": null,
"note": null
},
"timer": {
"running": false,
"started_at": null
},
"created_at": "2026-01-25T16:30:00Z",
"updated_at": "2026-01-25T16:30:00Z"
}Time Entry Fields
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier (prefix: time_) |
user_id | string | Required. User who logged the time |
date | date | Required. Date of work (YYYY-MM-DD) |
hours | decimal | Required. Hours worked (0.01 - 24.00) |
description | string | Work description |
client_id | string | Associated client |
project_id | string | Associated project |
ticket_id | string | Associated ticket |
agreement_id | string | Retainer agreement |
period_id | string | Specific retainer period |
billing | object | Billing details |
exclusion | object | Exclusion details (if not billed) |
timer | object | Timer state |
created_at | datetime | When entry was created |
updated_at | datetime | When entry was last updated |
Billing Object
| Field | Type | Description |
|---|---|---|
billable | boolean | Whether this time is billable |
billed | boolean | Whether this has been invoiced |
rate_id | string | Rate card ID |
rate_type | enum | standard, emergency, custom |
rate_charged | decimal | Actual hourly rate |
rate_override | boolean | Whether rate was manually set |
invoice_line_id | string | Invoice line (if billed) |
Rate Types
| Type | Description |
|---|---|
standard | Normal hourly rate |
emergency | After-hours/rush rate (typically 1.5x) |
custom | Manually specified rate |
List Time Entries
/v1/time-entriesList time entriesReturns a paginated list of time entries.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number |
per_page | integer | 20 | Results per page (max: 100) |
user_id | string | Filter by user | |
client_id | string | Filter by client | |
project_id | string | Filter by project | |
ticket_id | string | Filter by ticket | |
agreement_id | string | Filter by agreement | |
from | date | Start date (YYYY-MM-DD) | |
to | date | End date (YYYY-MM-DD) | |
billable | boolean | Filter by billable status | |
billed | boolean | Filter by billed status | |
sort | string | date | Sort by: date, created_at, hours |
order | string | desc | Sort order: asc, desc |
Request
curl "https://api.govantage.co/v1/time-entries?from=2026-01-01&to=2026-01-31&billable=true" \
-H "Authorization: Bearer vnt_sk_live_xxxxx"Response
{
"data": [
{
"id": "time_cuid123456",
"user_id": "usr_xxxxx",
"user_name": "John Smith",
"date": "2026-01-25",
"hours": 2.50,
"description": "Implemented contact form validation",
"client_id": "cli_xxxxx",
"client_name": "Acme Corporation",
"project_id": "prj_xxxxx",
"project_title": "Website Redesign",
"ticket_id": "tkt_xxxxx",
"billing": {
"billable": true,
"billed": false,
"rate_charged": 150.00
},
"created_at": "2026-01-25T16:30:00Z"
}
],
"pagination": {
"page": 1,
"per_page": 20,
"total": 342,
"total_pages": 18
},
"summary": {
"total_hours": 485.50,
"billable_hours": 425.25,
"non_billable_hours": 60.25,
"total_value": 63787.50
}
}The summary object provides aggregated totals for the filtered results, useful for reporting without additional API calls.
Create a Time Entry
/v1/time-entriesCreate a time entryRequest Body
| Field | Type | Required | Description |
|---|---|---|---|
user_id | string | Yes | User ID (defaults to authenticated user if API key is user-scoped) |
date | date | Yes | Date of work (YYYY-MM-DD) |
hours | decimal | Yes | Hours worked |
description | string | No | Work description |
client_id | string | No* | Client ID |
project_id | string | No* | Project ID |
ticket_id | string | No* | Ticket ID |
agreement_id | string | No | Retainer agreement ID |
period_id | string | No | Specific retainer period |
billable | boolean | No | Default: true |
rate_type | string | No | standard, emergency, custom |
rate_charged | decimal | No | Custom rate (when rate_type is custom) |
At least one of client_id, project_id, or ticket_id must be provided. If you provide project_id or ticket_id, the client is inferred automatically.
Request
curl -X POST "https://api.govantage.co/v1/time-entries" \
-H "Authorization: Bearer vnt_sk_live_xxxxx" \
-H "Content-Type: application/json" \
-d '{
"user_id": "usr_xxxxx",
"date": "2026-01-25",
"hours": 2.5,
"description": "Implemented contact form validation",
"ticket_id": "tkt_xxxxx",
"billable": true,
"rate_type": "standard"
}'Response
{
"data": {
"id": "time_cuid789012",
"user_id": "usr_xxxxx",
"date": "2026-01-25",
"hours": 2.50,
"description": "Implemented contact form validation",
"client_id": "cli_xxxxx",
"project_id": "prj_xxxxx",
"ticket_id": "tkt_xxxxx",
"billing": {
"billable": true,
"billed": false,
"rate_id": "rate_xxxxx",
"rate_type": "standard",
"rate_charged": 150.00,
"rate_override": false
},
"created_at": "2026-01-25T16:30:00Z",
"updated_at": "2026-01-25T16:30:00Z"
}
}Get a Time Entry
/v1/time-entries/:idRetrieve a time entry by IDPath Parameters
| Parameter | Description |
|---|---|
id | The time entry ID |
Request
curl "https://api.govantage.co/v1/time-entries/time_cuid123456" \
-H "Authorization: Bearer vnt_sk_live_xxxxx"Update a Time Entry
/v1/time-entries/:idUpdate a time entryTime entries that have been billed (billed: true) cannot be modified. Void the invoice first.
Path Parameters
| Parameter | Description |
|---|---|
id | The time entry ID |
Request
curl -X PUT "https://api.govantage.co/v1/time-entries/time_cuid123456" \
-H "Authorization: Bearer vnt_sk_live_xxxxx" \
-H "Content-Type: application/json" \
-d '{
"hours": 3.0,
"description": "Implemented contact form validation and error handling"
}'Delete a Time Entry
/v1/time-entries/:idDelete a time entryBilled time entries cannot be deleted. Void the associated invoice first.
Request
curl -X DELETE "https://api.govantage.co/v1/time-entries/time_cuid123456" \
-H "Authorization: Bearer vnt_sk_live_xxxxx"Timer Operations
Start Timer
/v1/time-entries/timer/startStart a timerCreates a time entry with a running timer. The hours field will be calculated when the timer is stopped.
curl -X POST "https://api.govantage.co/v1/time-entries/timer/start" \
-H "Authorization: Bearer vnt_sk_live_xxxxx" \
-H "Content-Type: application/json" \
-d '{
"user_id": "usr_xxxxx",
"description": "Working on homepage design",
"ticket_id": "tkt_xxxxx"
}'Response
{
"data": {
"id": "time_cuid789012",
"user_id": "usr_xxxxx",
"date": "2026-01-25",
"hours": 0,
"description": "Working on homepage design",
"ticket_id": "tkt_xxxxx",
"timer": {
"running": true,
"started_at": "2026-01-25T14:30:00Z"
},
"created_at": "2026-01-25T14:30:00Z"
}
}Stop Timer
/v1/time-entries/:id/timer/stopStop a running timerStops the timer and calculates the elapsed hours.
curl -X POST "https://api.govantage.co/v1/time-entries/time_cuid789012/timer/stop" \
-H "Authorization: Bearer vnt_sk_live_xxxxx"Response
{
"data": {
"id": "time_cuid789012",
"hours": 2.25,
"timer": {
"running": false,
"started_at": null
}
}
}Get Running Timers
/v1/time-entries/timer/runningList all running timerscurl "https://api.govantage.co/v1/time-entries/timer/running" \
-H "Authorization: Bearer vnt_sk_live_xxxxx"A user can only have one running timer at a time. Starting a new timer will stop any existing timer.
Bulk Operations
Bulk Create
/v1/time-entries/bulkCreate multiple time entriescurl -X POST "https://api.govantage.co/v1/time-entries/bulk" \
-H "Authorization: Bearer vnt_sk_live_xxxxx" \
-H "Content-Type: application/json" \
-d '{
"entries": [
{
"user_id": "usr_xxxxx",
"date": "2026-01-25",
"hours": 2.0,
"description": "Morning standup and planning",
"project_id": "prj_xxxxx"
},
{
"user_id": "usr_xxxxx",
"date": "2026-01-25",
"hours": 4.0,
"description": "Feature development",
"ticket_id": "tkt_xxxxx"
}
]
}'Exclude from Billing
/v1/time-entries/:id/excludeExclude a time entry from billingMark a time entry as excluded from billing with a reason.
curl -X POST "https://api.govantage.co/v1/time-entries/time_cuid123456/exclude" \
-H "Authorization: Bearer vnt_sk_live_xxxxx" \
-H "Content-Type: application/json" \
-d '{
"reason": "internal_meeting",
"note": "Weekly team sync - not client billable"
}'Exclusion Reasons
| Reason | Description |
|---|---|
internal_meeting | Internal meetings/syncs |
rework | Fixing our own mistakes |
goodwill | Client goodwill gesture |
training | Training/learning time |
admin | Administrative tasks |
other | Other (specify in note) |
Reporting Endpoints
Timesheet Summary
/v1/time-entries/summaryGet aggregated time datacurl "https://api.govantage.co/v1/time-entries/summary?from=2026-01-01&to=2026-01-31&group_by=user" \
-H "Authorization: Bearer vnt_sk_live_xxxxx"Response
{
"data": {
"period": {
"from": "2026-01-01",
"to": "2026-01-31"
},
"totals": {
"hours": 1250.50,
"billable_hours": 1125.25,
"value": 168787.50,
"utilization": 0.78
},
"by_user": [
{
"user_id": "usr_xxxxx",
"user_name": "John Smith",
"hours": 168.00,
"billable_hours": 152.00,
"utilization": 0.90
}
]
}
}Webhooks
Subscribe to time entry events:
| Event | Description |
|---|---|
time_entry.created | New time entry logged |
time_entry.updated | Time entry modified |
time_entry.deleted | Time entry removed |
time_entry.timer_started | Timer started |
time_entry.timer_stopped | Timer stopped |
Next Steps
- Projects API - Manage projects
- Tickets API - Manage tickets
- Invoices API - Create invoices from time