# Journal Entries

> Double-entry bookkeeping with the journal entries API.

- **Category:** Guides
- HTML version: https://www.ondayzero.com/docs/guides/journal-entries
- All guides: https://www.ondayzero.com/docs/guides/index.md
- Endpoint catalog: https://www.ondayzero.com/docs/reference/index.md

---

# 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](/docs/guides/ledgers) for finding ledger IDs and [Tags](/docs/guides/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](/docs/guides/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](/docs/guides/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": "..."}`.
