Log time from an agent session
log_time records billable time against one client with a description and hours. The rate is optional, an omitted rate is stored as null rather than zero, and a request_id makes the call safe to retry.
Written and reviewed by the Billr team. Published , last reviewed .
- Who this is for
- Anyone whose agent should log work as it happens instead of reconstructing a timesheet later.
- Billr capabilities used
log_timelist_time_entrieslist_unbilled
What you need first
- A client to log against, identified by
client_idor an exactclient_name. - A key with the Read and draft profile, because logging is a write.
- A stable
request_idper intended entry, generated once and reused on retries.
Step by step
01Log the entry
descriptionandhoursare required, and hours must be greater than zero and no more than 24.datedefaults to today, and the entry is billable unless you passbillable: false.log_time { "request_id": "b6f2a94c-7d31-4e58-8c09-5a1e7b3d2f64", "client_name": "Harbor & Lane", "description": "Schema markup fixes", "hours": 1.5, "rate": 150, "date": "2026-09-28" }02Decide about the rate
Passing
ratestores the amount immediately. Omitting it storeshourly_rate: nullandamount: null, which is different from a deliberate zero and is reported as a missing rate bylist_unbilled.03Read the entry back
list_time_entriesfilters by client, date range,billed(billed, unbilled or all) andbillable, so a session can answer "what did I log last week" without guessing.list_time_entries { "billed": "unbilled", "from": "2026-09-01", "to": "2026-09-30" }04Do not invoice from the same call
Logging is deliberately separate from billing. Drafting an invoice attaches the entries and removes them from the unbilled list, so keep the two steps apart unless you mean it.
Worked example
Fictional account, field names as returned by the server
You say
Log 1.5 hours of schema markup fixes for Harbor & Lane at $150/hour.
Your agent calls
log_time { "request_id": "b6f2a94c-7d31-4e58-8c09-5a1e7b3d2f64", "client_name": "Harbor & Lane", "description": "Schema markup fixes", "hours": 1.5, "rate": 150, "date": "2026-09-28" }
Expected response, abridged
{
"summary": "Logged 1.5h for Harbor & Lane",
"time_entry": {
"id": "3f6c1a44-5b2d-4e71-9c08-7a1d3f5b9e22",
"description": "Schema markup fixes",
"date": "2026-09-28",
"hours": 1.5,
"rate": 150,
"amount": 225,
"is_billable": true
},
"app_url": "https://billr.cc/time"
}Limits and gotchas
- One entry covers at most 24 hours, so a mis-scaled value fails rather than creating a monster line.
- Hours are stored as seconds; the amount is computed from seconds and rate, never from a rounded display value.
- Entries logged without a rate cannot be attached to an invoice until a rate is set.
- Non-billable time is recorded for your own reporting and never appears in
list_unbilled.
Troubleshooting
- Two identical entries appeared
- The retry used a new
request_id. Reuse the same id with the same input to get the original entry back. - The agent logged the wrong client
- Correct it with
update_time_entrywhile the entry is unbilled, passing the rightclient_idor exactclient_name. - The entry never shows as billable
- Check
is_billableon the result and remember thatlist_unbilledonly returns billable, uninvoiced entries.
Sources
Reviewed 2026-09-20 against Billr's own tool implementations and the client documentation linked above.
Read next
Logged time is only useful if it gets billed. The monthly run turns it into drafts, and the find-unbilled guide shows what the list reports first.
Bill the month