Journal Entries
Journal entries are the foundation of double-entry accounting. Every entry contains debit and credit lines that must balance.
Core Rule
Total Debits = Total Credits — every journal entry must balance, and needs at least two lines. Unbalanced entries are rejected with 400.
Create a Journal Entry
curl -X POST "https://api.ondayzero.com/api/v1/journal-entries" \
-H "Authorization: Bearer dz_your_token_here" \
-H "x-business-id: YOUR_BUSINESS_ID" \
-H "Content-Type: application/json" \
-d '{
"description": "Client payment received",
"date": "2026-03-20",
"line_entries": [
{ "ledger_id": "CASH_LEDGER_UUID", "amount": 100000, "debit_credit": "debit" },
{ "ledger_id": "REVENUE_LEDGER_UUID", "amount": 100000, "debit_credit": "credit" }
]
}'date is a plain YYYY-MM-DD. Optional top-level fields: currency, invoice_id (attach the entry to an invoice), inventory_order_id.
Line Entry Fields
| Field | Type | Required | Description |
|---|---|---|---|
ledger_id |
UUID | Yes | The account (ledger) affected |
amount |
integer | Yes | Amount in cents, always positive |
debit_credit |
string | Yes | debit or credit |
description |
string | No | Line memo |
project_id |
UUID | No | Project dimension for job costing |
class_id |
UUID | No | Class dimension |
location_id |
UUID | No | Location dimension |
See Ledgers for finding ledger IDs and Tags / accounting dimensions for projects, classes and locations.
Entry Sources
Every entry records where it came from (source) and whether a person typed it (creation_method: manual) or the system generated it (creation_method: ai):
source |
Description |
|---|---|
manual |
User-created adjusting entries (what POST /api/v1/journal-entries produces) |
invoice |
AR entries when invoices are finalized |
sales_receipt |
Cash sale / refund receipts |
bank_deposit |
Deposits clearing undeposited funds |
bill |
AP entries when bills are received |
credit_memo / vendor_credit |
Customer and vendor credits |
transaction |
Bank transaction categorization |
stripe |
Payment entries from Stripe webhooks |
shopify / square / ramp / plaid |
Integration-generated entries |
system / teal |
Internal accounting-engine entries |
List Journal Entries
curl "https://api.ondayzero.com/api/v1/journal-entries?limit=25&start_date=2026-03-01&end_date=2026-03-31&source=manual" \
-H "Authorization: Bearer dz_your_token_here" \
-H "x-business-id: YOUR_BUSINESS_ID"Filters: start_date / end_date, ledger_id (entries touching an account), invoice_id, source (one or more, comma-separated), creation_method (ai or manual), description / search, plus the standard pagination parameters.
Each entry in the response carries entry_number, entry_date, source, creation_method, its line_entries, and reversed_by_id if it has been reversed.
Update, Reverse, Delete
- Update:
PUT /api/v1/journal-entries/{journal_entry_id}changesdate,descriptionand links, and edits lines throughline_entry_changes— an object withcreate,update(by line ID) anddelete(by line ID) arrays. The result must still balance. - Reverse:
POST /api/v1/journal-entries/{journal_entry_id}/reversewith an optional{"reversal_date": "2026-04-01", "reason": "..."}creates an offsetting entry with flipped debits and credits — the audit-friendly way to undo a posted entry. - Delete:
DELETE /api/v1/journal-entries/{journal_entry_id}soft-deletes an entry that nothing else depends on — no linked transaction, invoice, inventory order, credit memo or vendor credit. Entries generated by a source record (invoice, bill, transaction…) should be changed through that record instead; if you must remove one, clear the link first or reverse it. - Attach a document:
PATCH /api/v1/journal-entries/{journal_entry_id}/attachment(multipartfile).
Bulk Upload
Download the template with GET /api/v1/journal-entries/bulk-upload/template, upload the filled file (see File Uploads), preview with POST /api/v1/journal-entries/bulk-upload/preview and post with POST /api/v1/journal-entries/bulk-upload/post, both taking {"s3_key": "..."}.