Bill clients for hours worked with Claude Code
Last updated . Claude Code docs checked 2026-10-08.
The short answer. To bill by the hour you need hours per client: the time you worked on their project in Claude Code, plus the time you spent on it away from Claude Code (a call, testing in a browser), which only you can note. The time Claude spent working falls inside the first number; it is not an extra amount on top. Show the client the hours per day and per ticket, mark what you added by hand, and say how the time was measured. This page gives no advice on rates, tax or contracts.
Which hours: what Claude Code counts
Claude Code reports three kinds of duration, all for one session and none tied to a client:
- Wall time. The status line field
cost.total_duration_msis “Total wall-clock time the session has been running, in milliseconds. Accumulates across resumes and doesn't include time while the session isn't running”. A session left open while you are away still counts. - API time.
cost.total_api_duration_msis “Total time spent waiting for API responses in milliseconds”: the model's share only. - Active time. The telemetry metric
claude_code.active_time.total(monitoring docs) “Tracks actual time spent actively using Claude Code, excluding idle time.” It goes on: “This metric is incremented during user interactions, such as typing and reading responses, and during CLI processing, such as tool execution and AI response generation.”
API time alone leaves out your own reading, reviewing and typing; wall time can include a lunch break. None of the three says which client the time was for, and work on the project away from Claude Code has to be added by you.
Billing without hourslip
Run /usage at the end of each session. Its Session block, from the costs page, starts like this:
Total cost: $0.55 Total duration (API): 6m 20s Total duration (wall): 6h 33m 10s
Note the duration before you start over: “These totals reset when /clear starts a new session”. Write it down per client, by which project folder the session was in, with the time you spent away from Claude Code on the same client. A spreadsheet with a row per day and client, the hours and your rate, gives the amount: hours times rate. A timer that you start and stop per client does the same job and also counts the calls.
The Total cost line is what the session's tokens cost, and “The figure is an estimate”. It says nothing about your hours.
Hours, rate and invoice: hourslip
hourslip is a Claude Code mod (a plugin of function hooks). It records when you send prompts and when Claude's turns start and end, with the folder and the git branch; the folder gives the client and the branch the ticket. How it counts a stretch of work is in the first guide. Every report it makes has three numbers:
- Measured: the stretches built from your prompts and Claude's turns.
- By hand: time you add, such as
/hourslip add 1h30 acme "Call with ACME" --ticket ACME-182(--date YYYY-MM-DDfor another day). Reports label it “added by hand”. - Claude: each turn, from its start to its end. Turns are already inside the measured stretches, so this number is shown next to the billable hours and never added to them.
Billable is measured time plus time added by hand. A rate is set per client, an amount and a three-letter currency: /hourslip client add acme "ACME Corp" --path "<folder>/**" --rate 40 USD, or "rate": { "amount": 40, "currency": "USD" } in rules.json.
/hourslip publish acme previews the report for a calendar month (the current one, or YYYY-MM) and sends nothing. When the client has a rate, the report carries an invoice:
- Number: the client id in capitals and the month, so
ACME-2026-10for October 2026. - Amount: billable minutes at the hourly rate, rounded to the nearest cent.
- Due date: 15 days after the last day of the month.
- Your business name and payment instructions, from
businessinrules.json, when you fill them in.
A client without a rate gets the hours and no invoice.
/hourslip publish acme
hourslip: ACME Corp · 2026-10-01 to 2026-10-31
Billable 1h40 (measured 0h10, by hand 1h30) · Claude 0h00
Invoice ACME-2026-10: 66.67 USD, due 2026-11-15
1 day, 1 ticket
Publish: /hourslip publish acme 2026-10 --confirm
Nothing has been sent yet.
Captured with claude -p in Claude Code 2.1.292 on Windows, 2026-10-08, with a sample client at 40 USD an hour and a local test server. The preview's file path line is left out, and the typed command is shown dim. One prompt measured 0h10, the call added 1h30, and 1h40 at 40 USD an hour is 66.67 USD. Claude shows 0h00 because the sample's only turn was a one-word reply.
What the client sees
The report is a page your client can read without hourslip: /hourslip export acme writes it as a local HTML file (“Print this page to save it as PDF.”), and /hourslip publish acme --confirm publishes it and gives you a link to send. It shows:
- Billable hours, with the measured part, the part added by hand and the time Claude was working.
- The line “Measured from Claude Code activity. Time outside Claude Code, such as meetings or manual testing, appears only where it was added by hand, and is labelled so.”
- By day: measured, by hand, Claude; a day is flagged “overlapping clients” or “capped at 12h” when that applies.
- By ticket: the branches and your commit titles (
--no-commitsleaves the titles out). - Added by hand: each date, your note and the time.
- The invoice, when the client has a rate: “1h40 at 40.00 USD per hour”, the amount and the due date.
The same export writes two CSV files. The days file has the columns Measured hours, Claude hours, Manual hours and Total billable hours; the tickets file has one row per day and ticket, with your notes. See a sample report.
On a published report, whoever holds the link can type a name and confirm the hours. “hourslip does not verify who confirms: anyone with the link can.” The first two published reports are free, no card; unpublishing one does not give it back.
What hourslip does not do
- It gives no advice on rates, tax or contracts, and computes no tax: the invoice holds a number, the currency, the rate, the billable minutes, the amount and a due date, nothing more.
- One rate per client. There is no rate per ticket or per kind of work.
- Invoice numbers are not a running sequence: the number is the client id and the month, so publishing the same month again gives the same number.
- The due date is always 15 days after the month ends; there is no setting for it.
- Time away from Claude Code is not seen unless added by hand with
/hourslip add. - Timestamps come from your own clock and are trusted: a client who doubts the hours is shown a lower bound, not a tamper-proof record.
- Commit titles appear only when you run the commands in the Claude Code CLI; elsewhere, such as the desktop app, the preview and the command's reply say they are unavailable.