Expenses
Money out that is not a bill: card charges, cash purchases, checks already written. An expense posts to the ledger the moment it is created, debiting each line's expense account and crediting the account it was paid from. The total is always derived from the line items. Requires the money_out scope.
Approval policies
If the company runs an approval policy that matches the expense, create answers 202 instead of 201, with submitted_for_approval: true and posted: false on the object. Nothing is on the ledger until an approver acts in the app. A queued expense cannot be voided; withdraw the approval request instead.
Bank feeds
An expense created through the API is not matched to any bank transaction. If the same money later arrives on a connected bank feed it appears in Review as an unmatched line, and the user matches it to this expense there. Send an Idempotency-Key on every create so a retry never books the same purchase twice.
The Expense Object
| Field | Type | Description |
|---|---|---|
| id | string | Expense UUID |
| object | string | Always 'expense' |
| status | string | open, paid, or voided |
| approval_status | string | null when the expense posted directly; pending_approval, approved, or rejected when the company's approval policy routed it |
| posted | boolean | Whether the expense is on the ledger. False while it waits for approval |
| date | string | ISO 8601 date the money left the account |
| ref_number | string | Reference number (check number, receipt id, etc.) |
| payment_method | string | cash, check, credit_card, debit_card, eft, or other |
| currency | string | ISO currency code (e.g., USD) |
| total_cents | number | Total in cents |
| memo | string | Internal memo |
| payment_account_id | string | Chart account UUID the expense was paid from (bank or credit card) |
| party | object | |
| line_items | string[] | Expense line items |
| created_at | string | ISO 8601 timestamp |
| updated_at | string | ISO 8601 timestamp |
| intercompany_account_overrides | string[] | Owed-between account choices stored on this expense (multi-entity companies; empty otherwise) |
Endpoints
/api/v1/expensesList expenses
Returns a paginated list of expenses for the current organization, newest first.
Path & Query Parameters
| Parameter | Type | Description |
|---|---|---|
| status | string | Filter by status (open, paid, voided) |
| vendor_id | string | Filter by vendor UUID |
| date_from | string | Only expenses dated on or after this date (YYYY-MM-DD) |
| date_to | string | Only expenses dated on or before this date (YYYY-MM-DD) |
| search | string | Search by reference number, vendor name or memo |
| page | number | Page number (default 1) |
| per_page | number | Results per page (1-200, default 50) |
/api/v1/expensesCreate an expense
Creates an expense and posts it to the ledger: debits each line's expense account, credits the payment account. The total is derived from the line items. The expense is not matched to any bank transaction; if the same money arrives on a bank feed it appears in Review for matching.
Body Parameters
| Parameter | Type | Description |
|---|---|---|
| payment_account_idrequired | string | Chart account UUID the expense was paid from (bank or credit card) |
| date | string | Expense date (YYYY-MM-DD, defaults to today) |
| vendor_id | string | Vendor UUID |
| entity_id | string | Entity UUID the expense belongs to. A company that keeps more than one entity must name it, unless the payment account belongs to an entity (that entity is used); otherwise 422 with an entity_id error |
| payment_method | string | cash, check, credit_card, debit_card, eft, or other |
| ref_number | string | Reference number |
| memo | string | Internal memo |
| dimension_values | object | Dimension tagging (dimension_id => value_id) |
| prior_run | string | replace or keep. Needed when a line uses a saved split and this vendor already has documents from it this month (otherwise 422 saved_split_prior_run, listing them in error_data.documents). replace voids the earlier documents in the same transaction; keep leaves them |
| intercompany_account_overrides | array | Multi-entity companies: which account each automatic owed-between line uses, when the expense crosses entities. Omit to keep the current choices; an empty array resets them |
| line_items_attributesrequired | array | Line items (at least one) |
/api/v1/expenses/:idRetrieve an expense
Path & Query Parameters
| Parameter | Type | Description |
|---|---|---|
| idrequired | string | Expense UUID |
/api/v1/expenses/:idUpdate an expense
Updates an expense and reposts it to the ledger. Voided expenses cannot be updated.
Path & Query Parameters
| Parameter | Type | Description |
|---|---|---|
| idrequired | string | Expense UUID |
Body Parameters
| Parameter | Type | Description |
|---|---|---|
| payment_account_id | string | Chart account UUID the expense was paid from |
| date | string | Expense date (YYYY-MM-DD) |
| vendor_id | string | Vendor UUID |
| payment_method | string | cash, check, credit_card, debit_card, eft, or other |
| ref_number | string | Reference number |
| memo | string | Internal memo |
| dimension_values | object | Dimension tagging (dimension_id => value_id) |
| prior_run | string | replace or keep. Needed when a line uses a saved split and this vendor already has documents from it this month (otherwise 422 saved_split_prior_run, listing them in error_data.documents). replace voids the earlier documents in the same transaction; keep leaves them |
| intercompany_account_overrides | array | Multi-entity companies: which account each automatic owed-between line uses, when the expense crosses entities. Omit to keep the current choices; an empty array resets them |
| line_items_attributes | array | Line items. Include each line's id to edit in place (and _destroy to remove one); a set with no ids REPLACES every existing line |
/api/v1/expenses/:id/voidVoid an expense
Voids the expense and reverses its ledger entry.
Path & Query Parameters
| Parameter | Type | Description |
|---|---|---|
| idrequired | string | Expense UUID |