FreshBooks
Read and write one FreshBooks business - clients, invoices, expenses and payments - with FreshBooks' own totals rather than counted pages.
Connect a FreshBooks business to work its books: list and search clients, invoices, expenses and payments with FreshBooks' own filters, read an invoice with its lines and payments, create clients, invoices and expenses, record payments against invoices, email an invoice to its client, and move an invoice between FreshBooks' visibility states. Every list reports FreshBooks' own count of what matches rather than the size of the page, and the tools state plainly which writes are irreversible.
Connect
Sign in with FreshBooks. Sign in with FreshBooks to read and write the businesses your account belongs to. An organization admin configures the OAuth app once under Integrations → OAuth apps; after that, connecting is a consent screen.
-
Connecting signs in as YOU - every client, invoice, expense and payment this integration writes is created by your FreshBooks user, and your role in the business is the ceiling.
-
If your FreshBooks login belongs to more than one business (an accountant's usually does), set Account ID on this connection afterwards. Get identity lists the memberships with their account ids.
-
Account ID is the SHORT alphanumeric id (like 'zDmNq'), not the numeric business id beside it - they address different halves of the API and swapping them produces a 404.
-
FreshBooks refresh tokens are single-use: each refresh mints a new one, and the old one stops working immediately.
-
For scheduled or triggered automations, connect a dedicated FreshBooks user and bind the automation as a service connection.
| Setting | Required | What it is |
|---|---|---|
Account ID (ACCOUNT_ID) | No | The FreshBooks account id every accounting call acts on - the SHORT alphanumeric one (Get identity lists it per business), not the numeric business id. Leave it empty only when the login belongs to exactly one business. |
Tools
| Tool | Access | What it does |
|---|---|---|
Get identity (yekar.freshbooks.get-identity) | Read | Who this connection signs in as, and every FreshBooks business their login belongs to - with each business's account id. Run this to get the id for the Account ID property: when a login belongs to more than one business, that property is what decides whose books every other tool touches. |
List clients (yekar.freshbooks.list-clients) | Read | The clients in this FreshBooks business, with FreshBooks' own count of how many match the filter. Note the visibility state: a client 'deleted' in FreshBooks has vis_state 1 and still comes back - filter on it when counting who is active. |
Create client (yekar.freshbooks.create-client) | Write | Add a client to this FreshBooks business. NOT idempotent: FreshBooks does not deduplicate on email or name, so calling twice creates two clients that invoices can then be split between. Check List clients first when re-running. |
List invoices (yekar.freshbooks.list-invoices) | Read | Invoices in this FreshBooks business, filtered by client, date, status or outstanding balance, with FreshBooks' own count of how many match. Line items are omitted unless include: ["lines"] asks for them - without it an invoice reads as having no lines rather than as having lines you did not fetch. |
Get invoice (yekar.freshbooks.get-invoice) | Read | One invoice in full - by default with its line items and payments, which lists omit. Amounts come back as STRINGS inside a money object ({amount, code}); they are decimal strings on purpose and turning them into floats is how cents go missing. |
Create invoice (yekar.freshbooks.create-invoice) | Write | Create an invoice for a client. It is created as a DRAFT and nothing is sent - Send invoice is the separate, explicit step that emails it. NOT idempotent: FreshBooks has no idempotency key, so calling twice creates two invoices, each with its own number. |
Update invoice (yekar.freshbooks.update-invoice) | Write | Change an invoice, or move it between FreshBooks' visibility states. 'Deleting' an invoice here sets vis_state to 1: the record survives, stops counting toward totals and stops appearing in lists by default - and setting it back to active restores it. FreshBooks has no hard delete, so nothing here claims one. Sending lines replaces the whole line array. |
Send invoice (yekar.freshbooks.send-invoice) | Write | Email an invoice to its client through FreshBooks. The mail leaves immediately and cannot be recalled, and FreshBooks moves the invoice out of draft into 'sent' - so this is the step that tells a customer they owe money. Put an approval gate in front of it in any automation whose recipient or amount comes from a model. |
List expenses (yekar.freshbooks.list-expenses) | Read | Expenses recorded in this FreshBooks business, with FreshBooks' own count of how many match the filter. An expense marked billable to a client carries billable and clientid; has_receipt says whether a receipt image is attached - this integration reads neither the image nor uploads one. |
Create expense (yekar.freshbooks.create-expense) | Write | Record an expense in this FreshBooks business. NOT idempotent: FreshBooks does not deduplicate, so calling twice books the same cost twice - check List expenses for the date and amount when re-running after an unclear failure. Receipt images cannot be attached through this integration. |
List payments (yekar.freshbooks.list-payments) | Read | Payments recorded against invoices in this FreshBooks business, with FreshBooks' own count of how many match. A payment with vis_state 1 has been deleted and still comes back - exclude it before totalling what was actually received. |
Create payment (yekar.freshbooks.create-payment) | Write | Record a payment against an invoice. This settles real money: the invoice's outstanding balance drops and it moves toward 'paid'. NOT idempotent - FreshBooks has no idempotency key, so calling twice records the payment twice and over-pays the invoice. Read the invoice's outstanding balance first when re-running. |
Notes
- Sign in with FreshBooks - every client, invoice, expense and payment this integration writes is created by your FreshBooks user, and your role in the business is the ceiling.
- If your login belongs to more than one business, run Get identity and put the right account id in Account ID on this connection. With several reachable and none configured, every call refuses rather than guessing whose books to write to.
- Account ID is the SHORT alphanumeric id (like 'zDmNq'), not the numeric business id beside it - the two address different halves of the FreshBooks API and swapping them produces a 404.
- Money is an object whose amount is a decimal STRING: {"amount": "100.00", "code": "USD"}. Send it that way, and read it that way - parsing it into a float loses cents.
- Creating an invoice does not tell the client anything: it is a draft until Send invoice emails it, and that mail cannot be recalled.
- Create payment and Create expense are not idempotent - FreshBooks has no idempotency key, so a re-run books the money twice. Check the invoice's outstanding balance or the expense list before retrying.
- FreshBooks has no hard delete. 'Deleting' an invoice sets vis_state to 1: it stops counting and stops appearing, and setting it back to active restores it.
- FreshBooks refresh tokens are single-use, so each refresh replaces the previous one and an older copy is already dead.