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

  1. 01Log it against the client

    description and amount are required, amount must be greater than zero, and category accepts office, travel, meals, supplies, utilities, software, marketing, professional, insurance, mileage or other.

    Example
    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"
    }
  2. 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.

  3. 03Filter the expense book

    list_expenses filters by category, client, date range, billed (billed, unbilled, all) and billable, and returns totals by currency.

    Example
    list_expenses  {
      "client_name": "Harbor & Lane",
      "billed": "unbilled",
      "billable": true
    }
  4. 04Attach it to an invoice

    The expense id goes into create_invoice as an expense_ids entry. 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

Example
{
  "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_billable and is_billed in list_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_expense while 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.

Expenses and time travel to the invoice the same way, so the monthly run picks both up from one list.

Bill the month