Bookkeeping
Journal entries
Balanced debits and credits for adjustments, accruals, transfers, and anything without its own form.
Create a journal entry
Scope: journals:write. Send 2–200 lines. Each line has an account_id and exactly one of debit or credit above zero, and total debits must equal total credits.
With "post": true the entry goes to the ledger right away. Without it the entry is saved as a draft.
curl -X POST "https://api.helloledger.ai/v1/companies/{company_id}/journal-entries" \
-H "Authorization: Bearer $HL_API_KEY" \
-H "Idempotency-Key: je_2026_10_owner" \
-H "Content-Type: application/json" \
-d '{
"date": "2026-10-31",
"memo": "Owner contribution",
"external_id": "je_2026_10_owner",
"post": true,
"lines": [
{
"account_id": "66f1a2b3c4d5e6f708091d03",
"debit": "5000.00",
"description": "Deposit"
},
{
"account_id": "66f1a2b3c4d5e6f708091d05",
"credit": "5000.00"
}
]
}'{
"journal_id": "48213",
"external_id": "je_2026_10_owner",
"date": "2026-10-31",
"memo": "Owner contribution",
"status": "posted",
"posted": true,
"total": "5000.00",
"lines": [
{ "account_id": "66f1a2b3c4d5e6f708091d03", "account_name": "Operating Checking", "debit": "5000.00", "credit": "0.00", "description": "Deposit" },
{ "account_id": "66f1a2b3c4d5e6f708091d05", "account_name": "Owner Equity", "debit": "0.00", "credit": "5000.00" }
],
"result": "posted"
}List and read journal entries
Scope: journals:read. The list pages with next_cursor; pass it back as cursor. Filter by date with from and to (both required together). Voided entries are listed with status voided.
curl "https://api.helloledger.ai/v1/companies/{company_id}/journal-entries?from=2026-10-01&to=2026-10-31" \
-H "Authorization: Bearer $HL_API_KEY"curl "https://api.helloledger.ai/v1/companies/{company_id}/journal-entries/48213" \
-H "Authorization: Bearer $HL_API_KEY"Edit, post, or delete
PATCH changes a draft or a posted entry. Sending lines replaces all lines, and they must balance. A posted entry is re-posted with the new lines. DELETE removes drafts only.
curl -X PATCH "https://api.helloledger.ai/v1/companies/{company_id}/journal-entries/48213" \
-H "Authorization: Bearer $HL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"memo": "Owner contribution (corrected)",
"lines": [
{
"account_id": "66f1a2b3c4d5e6f708091d03",
"debit": "5500.00"
},
{
"account_id": "66f1a2b3c4d5e6f708091d05",
"credit": "5500.00"
}
]
}'curl -X POST "https://api.helloledger.ai/v1/companies/{company_id}/journal-entries/48213/post" \
-H "Authorization: Bearer $HL_API_KEY"curl -X DELETE "https://api.helloledger.ai/v1/companies/{company_id}/journal-entries/48213" \
-H "Authorization: Bearer $HL_API_KEY"Void a journal entry
Voiding removes the entry from the ledger and keeps it with status voided, so the history stays visible. A voided entry can't be edited or posted again.
curl -X POST "https://api.helloledger.ai/v1/companies/{company_id}/journal-entries/48213/void" \
-H "Authorization: Bearer $HL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"reason": "Booked in the wrong month"
}'What you can't change
- Entries on a date an account has been reconciled through return 409 period_reconciled.
- Entries created by other integrations, including daily revenue journals, return 409 managed_by_integration. Daily revenue has its own endpoint.
- Every account must belong to the company and be open on the entry's date.