API reference: time entries
Read time entries, and add or change your own draft time on a task or a service desk ticket.
Last updated
Time endpoints need time:read to read and time:write to change. A new entry is a draft for the key's own person. The API never reads or sets a billing code, a rate or a contract. Every sample reads the key from CURRENT_API_KEY and calls https://api.current.day/v1.
/v1/time-entriesNeeds the time:read scope. Pages with a cursor.
Lists the time entries in a date range (the last 31 days when left out, at most 92) that this key may read: its holder's own, and a manager's team. It changes nothing and never shows a billing code, contract, role, rate or money. Pages with a cursor, at most 100 a page.
Parameters
Query parameters
- fromtext, up to 10 charactersOptional
- A date, YYYY-MM-DD.
- totext, up to 10 charactersOptional
- A date, YYYY-MM-DD.
- user_iduuidOptional
- Only this person's entries.
- limitinteger, 1 to 100Optional
- Rows per page, 1 to 100. 50 when left out.
- cursorcursorOptional
- next_cursor from the previous page.
Errors
| Status | Code and meaning |
|---|---|
| 400 | bad_requestThe request was not in the expected shape. |
| 401 | unauthorizedThis token was not accepted. |
| 403 | not_allowed, frozen, module_offThis agent is not allowed to do that. This workspace is read only right now, so nothing can be changed. The API is not switched on for this workspace. |
| 404 | not_foundNothing was found with that id, or this agent cannot see it. |
| 405 | bad_request (method_not_allowed)That address does not accept this method. The Allow header lists the ones it does. |
| 429 | rate_limited, send_cappedToo many requests from this token. Wait, then try again. This token has sent its limit of customer emails for now. Try again later. |
| 503 | degradedCurrent is busy. Try again in a minute. |
curl -sS --fail-with-body "https://api.current.day/v1/time-entries?from=2026-11-01&to=2026-11-07&limit=50" \
-H "Authorization: Bearer $CURRENT_API_KEY"
# A refusal exits non-zero and prints the error: read .error.code and .error.reason,
# for example with jq -r '.error.code, .error.reason'{
"data": [
{
"id": "e4b9d2a7-6c38-4f51-a0e8-3d7c5b1f9a26",
"user_id": "8d4b6f1a-2c9e-4e73-b05d-7a1e3c5f9b48",
"user_name": {
"untrusted_text": "Priya Okafor",
"source": "staff"
},
"date": "2026-11-06",
"hours": 1.5,
"summary": {
"untrusted_text": "Imaged two workstations and tested printing.",
"source": "staff"
},
"status": "draft",
"sync": "not_synced",
"task_id": "3d8a5f2c-1e69-4c07-b3d4-7f0e6a9c2b58",
"task_name": {
"untrusted_text": "Image the front desk workstations",
"source": "staff"
},
"project_id": "9b5e1d7c-3a46-4f28-8c0b-6e2a9f4d1c73",
"desk_ticket_id": null,
"desk_ticket_number": null,
"psa_ticket_number": null,
"created_at": "2026-11-06T21:02:10.000Z",
"updated_at": "2026-11-06T21:02:10.000Z"
}
],
"next_cursor": null,
"has_more": false
}/v1/time-entriesNeeds the time:write scope.
Saves a draft time entry for this key's holder on a task or a service desk ticket, under the same rules as Current's own Log time. Desk time goes to the PSA with the desk's sync; project time waits as a draft for its person to submit in Current (psa says which). It never reaches a customer by itself.
Parameters
Header parameters
- Idempotency-KeyuuidOptional
- The same uuid as request_id, if you prefer a header. Send one or the other, or both with the same value.
Body parameters
- request_iduuidOptional
- A uuid you mint for this change. Send the same one again with the same key to retry safely: Current answers the first answer and never writes twice. Kept 24 hours per key; a retry with another key, a rotated one included, runs again. Required unless the Idempotency-Key header is sent.
- task_iduuidOptional
- The task the time is on (or give desk_ticket_id).
- desk_ticket_iduuidOptional
- The service desk ticket the time is on (or give task_id).
- datetext, up to 10 charactersRequired
- A date, YYYY-MM-DD.
- hoursnumberRequired
- Hours worked, more than 0 and at most 24.
- summarytext, up to 2,000 charactersOptional
- What was done. The task's or ticket's name when left out.
Errors
| Status | Code and meaning |
|---|---|
| 400 | bad_requestThe request was not in the expected shape. |
| 401 | unauthorizedThis token was not accepted. |
| 403 | not_allowed, frozen, module_offThis agent is not allowed to do that. This workspace is read only right now, so nothing can be changed. The API is not switched on for this workspace. |
| 404 | not_foundNothing was found with that id, or this agent cannot see it. |
| 405 | bad_request (method_not_allowed)That address does not accept this method. The Allow header lists the ones it does. |
| 409 | conflictSomeone changed this first. Read it again, then retry. |
| 413 | bad_request (body_too_large)The request body is larger than 64 KB. |
| 429 | rate_limited, send_cappedToo many requests from this token. Wait, then try again. This token has sent its limit of customer emails for now. Try again later. |
| 503 | degradedCurrent is busy. Try again in a minute. |
REQUEST_ID=$(uuidgen) # a new id for this change; send the same one again only to retry it
curl -sS --fail-with-body -X POST "https://api.current.day/v1/time-entries" \
-H "Authorization: Bearer $CURRENT_API_KEY" \
-H "Content-Type: application/json" \
-d @- <<EOF
{"request_id":"$REQUEST_ID","task_id":"3d8a5f2c-1e69-4c07-b3d4-7f0e6a9c2b58","date":"2026-11-06","hours":1.5,"summary":"Imaged two workstations and tested printing."}
EOF
# A refusal exits non-zero and prints the error: read .error.code and .error.reason,
# for example with jq -r '.error.code, .error.reason'{
"data": {
"time_entry_id": "e4b9d2a7-6c38-4f51-a0e8-3d7c5b1f9a26",
"status": "draft",
"psa": "waiting_for_you"
}
}/v1/me/time-entriesNeeds the time:read scope.
Lists this key's holder's own time entries in a date range (the last 7 days when left out, at most 31), up to 100. It changes nothing and never shows a billing code, rate or money.
Parameters
Query parameters
- fromtext, up to 10 charactersOptional
- A date, YYYY-MM-DD.
- totext, up to 10 charactersOptional
- A date, YYYY-MM-DD.
Errors
| Status | Code and meaning |
|---|---|
| 400 | bad_requestThe request was not in the expected shape. |
| 401 | unauthorizedThis token was not accepted. |
| 403 | not_allowed, frozen, module_offThis agent is not allowed to do that. This workspace is read only right now, so nothing can be changed. The API is not switched on for this workspace. |
| 404 | not_foundNothing was found with that id, or this agent cannot see it. |
| 405 | bad_request (method_not_allowed)That address does not accept this method. The Allow header lists the ones it does. |
| 429 | rate_limited, send_cappedToo many requests from this token. Wait, then try again. This token has sent its limit of customer emails for now. Try again later. |
| 503 | degradedCurrent is busy. Try again in a minute. |
curl -sS --fail-with-body "https://api.current.day/v1/me/time-entries?from=2026-11-02&to=2026-11-06" \
-H "Authorization: Bearer $CURRENT_API_KEY"
# A refusal exits non-zero and prints the error: read .error.code and .error.reason,
# for example with jq -r '.error.code, .error.reason'{
"data": [
{
"id": "e4b9d2a7-6c38-4f51-a0e8-3d7c5b1f9a26",
"user_id": "8d4b6f1a-2c9e-4e73-b05d-7a1e3c5f9b48",
"user_name": {
"untrusted_text": "Priya Okafor",
"source": "staff"
},
"date": "2026-11-06",
"hours": 1.5,
"summary": {
"untrusted_text": "Imaged two workstations and tested printing.",
"source": "staff"
},
"status": "draft",
"sync": "not_synced",
"task_id": "3d8a5f2c-1e69-4c07-b3d4-7f0e6a9c2b58",
"task_name": {
"untrusted_text": "Image the front desk workstations",
"source": "staff"
},
"project_id": "9b5e1d7c-3a46-4f28-8c0b-6e2a9f4d1c73",
"desk_ticket_id": null,
"desk_ticket_number": null,
"psa_ticket_number": null,
"created_at": "2026-11-06T21:02:10.000Z",
"updated_at": "2026-11-06T21:02:10.000Z"
}
]
}/v1/time-entries/{time_entry_id}Needs the time:write scope.
Changes the hours, date or summary of this key's holder's own unsent draft time on a task; anything already sent, and desk time, answers change_in_current. It never reaches a customer by itself; retry with the same request_id and it is applied once.
Parameters
Path parameters
- time_entry_iduuidRequired
- The time entry's id (read it with GET /v1/me/time-entries or GET /v1/time-entries).
Header parameters
- Idempotency-KeyuuidOptional
- The same uuid as request_id, if you prefer a header. Send one or the other, or both with the same value.
Body parameters
- request_iduuidOptional
- A uuid you mint for this change. Send the same one again with the same key to retry safely: Current answers the first answer and never writes twice. Kept 24 hours per key; a retry with another key, a rotated one included, runs again. Required unless the Idempotency-Key header is sent.
- datetext, up to 10 charactersOptional
- A date, YYYY-MM-DD.
- hoursnumberOptional
- summarytext, up to 2,000 charactersOptional
Errors
| Status | Code and meaning |
|---|---|
| 400 | bad_requestThe request was not in the expected shape. |
| 401 | unauthorizedThis token was not accepted. |
| 403 | not_allowed, frozen, module_offThis agent is not allowed to do that. This workspace is read only right now, so nothing can be changed. The API is not switched on for this workspace. |
| 404 | not_foundNothing was found with that id, or this agent cannot see it. |
| 405 | bad_request (method_not_allowed)That address does not accept this method. The Allow header lists the ones it does. |
| 409 | conflictSomeone changed this first. Read it again, then retry. |
| 413 | bad_request (body_too_large)The request body is larger than 64 KB. |
| 429 | rate_limited, send_cappedToo many requests from this token. Wait, then try again. This token has sent its limit of customer emails for now. Try again later. |
| 503 | degradedCurrent is busy. Try again in a minute. |
REQUEST_ID=$(uuidgen) # a new id for this change; send the same one again only to retry it
curl -sS --fail-with-body -X PATCH "https://api.current.day/v1/time-entries/e4b9d2a7-6c38-4f51-a0e8-3d7c5b1f9a26" \
-H "Authorization: Bearer $CURRENT_API_KEY" \
-H "Content-Type: application/json" \
-d @- <<EOF
{"request_id":"$REQUEST_ID","hours":2,"summary":"Imaged two workstations, tested printing and labelled the cables."}
EOF
# A refusal exits non-zero and prints the error: read .error.code and .error.reason,
# for example with jq -r '.error.code, .error.reason'{
"data": {
"time_entry_id": "e4b9d2a7-6c38-4f51-a0e8-3d7c5b1f9a26",
"status": "draft",
"psa": "waiting_for_you"
}
}