Bookkeeping
Invoices by HelloLedger ID
Create invoices as drafts or posted, then edit, post, void, or delete them by invoice_id.
Which invoice endpoints to use
These endpoints address invoices by the invoice_id HelloLedger returns. If your system has a stable charge ID and you want PUT-to-sync behavior, use Invoices (by external ID) instead. Don't mix the two for the same invoice.
HelloLedger never emails these invoices to the customer.
Create an invoice
Scope: invoices:write. Name the customer by customer_id, or send a customer block that is matched by name or created. Each line uses an item_id from GET /items or an income account_id.
With "post": true the invoice is posted right away (status sent): Accounts Receivable is debited and income is credited. Without it the invoice is saved as a draft.
curl -X POST "https://api.helloledger.ai/v1/companies/{company_id}/invoices" \
-H "Authorization: Bearer $HL_API_KEY" \
-H "Idempotency-Key: inv_3001" \
-H "Content-Type: application/json" \
-d '{
"customer": {
"name": "Wayne Enterprises",
"email": "ap@wayne.example"
},
"date": "2026-10-05",
"due_date": "2026-11-04",
"memo": "October retainer",
"external_id": "inv_3001",
"post": true,
"lines": [
{
"item_id": "66f1a2b3c4d5e6f708091a2b",
"description": "October retainer",
"amount": "1000.00"
}
]
}'{
"invoice_id": "66f1a2b3c4d5e6f708095d01",
"external_id": "inv_3001",
"invoice_number": "1042",
"customer_id": "66f1a2b3c4d5e6f708096e01",
"customer_created": true,
"date": "2026-10-05",
"due_date": "2026-11-04",
"status": "sent",
"total_amount": "1000.00",
"amount_paid": "0.00",
"balance_due": "1000.00",
"tax_amount": "0.00",
"currency": "USD",
"result": "posted"
}Fields
| Field | Notes |
|---|---|
| customer_id or customer | Required on create, one or the other. customer takes name, email, phone, address, and metadata. |
| date | Invoice date (YYYY-MM-DD). Required on create. |
| lines | 1–100 lines, each with item_id or account_id, and amount. Optional description, quantity, unit_price, and taxable. |
| due_date or terms | Optional. terms calculates the due date when due_date is left out. |
| invoice_number | Optional. HelloLedger numbers it when left out; a number in use returns 409 invoice_number_taken. |
| tax_rate | Percent applied to taxable lines. |
| memo, external_id | Optional. |
| post | true posts now. Default false saves a draft. |
List and read invoices
Scope: reports:read.
curl "https://api.helloledger.ai/v1/companies/{company_id}/invoices?overdue_only=true" \
-H "Authorization: Bearer $HL_API_KEY"curl "https://api.helloledger.ai/v1/companies/{company_id}/invoices/66f1a2b3c4d5e6f708095d01" \
-H "Authorization: Bearer $HL_API_KEY"Edit, post, void, or delete
PATCH changes a draft or a posted invoice with no payments. Sending lines replaces all lines and recalculates tax and totals; a posted invoice is re-posted. Invoices with payments or credits return 409 invoice_has_payments.
Voiding reverses the ledger and keeps the invoice with status voided. DELETE removes drafts only.
curl -X PATCH "https://api.helloledger.ai/v1/companies/{company_id}/invoices/66f1a2b3c4d5e6f708095d01" \
-H "Authorization: Bearer $HL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"lines": [
{
"item_id": "66f1a2b3c4d5e6f708091a2b",
"description": "October retainer",
"amount": "1250.00"
}
]
}'curl -X POST "https://api.helloledger.ai/v1/companies/{company_id}/invoices/66f1a2b3c4d5e6f708095d01/post" \
-H "Authorization: Bearer $HL_API_KEY"curl -X POST "https://api.helloledger.ai/v1/companies/{company_id}/invoices/66f1a2b3c4d5e6f708095d01/void" \
-H "Authorization: Bearer $HL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"reason": "Cancelled engagement"
}'curl -X DELETE "https://api.helloledger.ai/v1/companies/{company_id}/invoices/66f1a2b3c4d5e6f708095d01" \
-H "Authorization: Bearer $HL_API_KEY"