Track a billable expense
log_expense records a cost with an optional client. Attaching a client makes it billable by default, gives it the client currency, and makes it eligible for list_unbilled and a source-linked invoice.
Written and reviewed by the Billr team. Published , last reviewed .
- Who this is for
- People who pay for something on a client project and need it on the next invoice.
- Billr capabilities used
log_expenselist_expensesupdate_expense
What you need first
- A client if the cost is going to be rebilled, because that is what makes it billable.
- A key with the Read and draft profile.
- The amount, the date and a category from the accepted set.
Step by step
01Log it against the client
descriptionandamountare required,amountmust be greater than zero, and category accepts office, travel, meals, supplies, utilities, software, marketing, professional, insurance, mileage or other.log_expense { "request_id": "e8c1d47a-9b26-4f30-8a15-2c7d5e9b1f08", "client_name": "Harbor & Lane", "description": "Client lunch", "amount": 47.5, "category": "meals", "date": "2026-09-29" }02Understand the billable default
With a client attached the expense is billable unless you say otherwise. With no client it is recorded as non-billable, because a cost that belongs to nobody cannot ride on a client invoice.
03Filter the expense book
list_expensesfilters by category, client, date range,billed(billed, unbilled, all) andbillable, and returns totals by currency.list_expenses { "client_name": "Harbor & Lane", "billed": "unbilled", "billable": true }04Attach it to an invoice
The expense id goes into
create_invoiceas anexpense_idsentry. The server checks the client and currency match and writes one line at the exact amount.
Worked example
Fictional account, field names as returned by the server
You say
Log the $47.50 client lunch on Harbor & Lane to be rebilled.
Your agent calls
log_expense { "request_id": "e8c1d47a-9b26-4f30-8a15-2c7d5e9b1f08", "client_name": "Harbor & Lane", "description": "Client lunch", "amount": 47.5, "category": "meals", "date": "2026-09-29" }
Expected response, abridged
{
"summary": "Logged $47.50 expense for Harbor & Lane",
"expense": {
"id": "d41b8e93-2a70-4c15-9b6f-5e8a1c3d7f08",
"description": "Client lunch",
"amount": 47.5,
"currency": "USD",
"category": "meals",
"is_billable": true
}
}Limits and gotchas
- Expense currency follows the client, falling back to the business currency. It cannot be attached to an invoice in another currency.
- Categories are a fixed list; an unusual cost belongs in "other" rather than a made-up value.
- Once attached to an invoice, the expense is immutable while that invoice exists.
- Billr records the cost, vendor, category and notes. Receipt files are not part of the product today, and nothing pays a vendor on your behalf.
Troubleshooting
- The expense is missing from list_unbilled
- It is probably non-billable, or already attached to a draft. Check
is_billableandis_billedinlist_expenses. - Attaching it fails with a currency error
- The expense currency does not match the invoice. Log or update it in the invoice currency, which normally means the client currency.
- The wrong amount was logged
- Correct it with
update_expensewhile it is unbilled; the amount is a single value, so pass the corrected total.
Sources
Reviewed 2026-09-20 against Billr's own tool implementations and the client documentation linked above.
Read next
Expenses and time travel to the invoice the same way, so the monthly run picks both up from one list.
Bill the month