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

bash
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

bash
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} changes date, description and links, and edits lines through line_entry_changes — an object with create, update (by line ID) and delete (by line ID) arrays. The result must still balance.
  • Reverse: POST /api/v1/journal-entries/{journal_entry_id}/reverse with 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 (multipart file).

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": "..."}.