> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dualentry.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Journal Entries: Reference

> Reference for DualEntry journal entries - required fields, posting rules, intercompany entries, recurring entries, and classifications.

Journal entries are the core transaction record in DualEntry. Every financial event, whether entered manually, created by a sub-ledger, or synced from an [integration](../../integrations/index), posts to the General Ledger as a journal entry with balanced debits and credits.

## Header fields

Each journal entry has a header that sets the context for the transaction. The table below lists all header-level fields, their types, and whether they are required.

| Field              | Type    | Required | Description                                                                                        |
| ------------------ | ------- | -------- | -------------------------------------------------------------------------------------------------- |
| `date`             | date    | Yes      | The accounting date the entry posts to. Must fall within an unlocked [period](./period-locking).   |
| `transaction_date` | date    | No       | The actual date the transaction occurred, if different from the accounting date.                   |
| `company_id`       | string  | Yes      | The legal entity this entry belongs to.                                                            |
| `memo`             | string  | No       | A description of the entry, visible in reports and search.                                         |
| `currency`         | string  | No       | ISO 4217 currency code. Defaults to the company's base currency.                                   |
| `exchange_rate`    | decimal | No       | Exchange rate to base currency. Required when `currency` differs from the company's base currency. |
| `reversal_date`    | date    | No       | If set, DualEntry automatically creates a reversing entry on this date. Used for accruals.         |
| `record_status`    | enum    | Yes      | One of `draft`, `posted`, or `archived`. Only `posted` entries affect account balances.            |
| `approval_status`  | enum    | No       | Tracks approval workflow state. Entries requiring approval cannot be posted until approved.        |

The `date` field determines which period an entry belongs to. If the period for that date is [locked](./period-locking), the entry cannot be created or modified. Change the date to an open period or unlock the period first.

## Line fields

Each entry contains two or more lines. Total debits must equal total credits before the entry can be posted. The table below lists all line-level fields.

| Field             | Type    | Required    | Description                                                                                                             |
| ----------------- | ------- | ----------- | ----------------------------------------------------------------------------------------------------------------------- |
| `account_number`  | string  | Yes         | The GL account to debit or credit. Must exist in your [chart of accounts](./chart-of-accounts).                         |
| `debit`           | decimal | Conditional | Debit amount. Provide either `debit` or `credit` per line, not both.                                                    |
| `credit`          | decimal | Conditional | Credit amount. Provide either `debit` or `credit` per line, not both.                                                   |
| `position`        | integer | No          | Sort order of the line within the entry. Defaults to insertion order.                                                   |
| `memo`            | string  | No          | Line-level description. Useful for identifying individual line items in multi-line entries.                             |
| `classifications` | array   | No          | Dimension tags (department, location, project) applied to this line. See [Classifications](#classifications).           |
| `customer_id`     | string  | No          | Links this line to a specific customer for sub-ledger reporting in [Accounts Receivable](../accounts-receivable/index). |
| `vendor_id`       | string  | No          | Links this line to a specific vendor for sub-ledger reporting in [Accounts Payable](../accounts-payable/index).         |
| `currency`        | string  | No          | Line-level currency override. When omitted, inherits the header currency.                                               |

Linking a line to a `customer_id` or `vendor_id` makes the entry appear in that customer's or vendor's sub-ledger, which feeds into aging reports and [account reconciliation](../close-management/account-reconciliation).

### Exclude a journal entry from AR or AP aging

Some journal entries touch a customer or vendor sub-ledger for reconciliation or reclassification purposes but shouldn't be treated as an open receivable or payable. Examples include a reclass between AR accounts, a bad debt write-off, or a correcting entry that offsets an existing invoice outside the normal payment flow. In these cases, keep the `customer_id` or `vendor_id` on the line so the entry still shows in the sub-ledger and reconciles cleanly, but remove it from the aging report.

Open the journal entry, toggle **Exclude from AR aging** (or **Exclude from AP aging**) on, and save. The entry stays visible on the customer or vendor sub-ledger and in the General Ledger, but DualEntry omits it from the [AR aging](../../reporting-analytics/aging-reports#ar-aging) and [AP aging](../../reporting-analytics/aging-reports#ap-aging) buckets and from the allowance-for-doubtful-accounts calculation. This keeps aging reports focused on true open receivables and payables without editing the underlying entry. Toggle it off at any time to reintroduce the entry to aging.

## Create, post, and list entries

To create an entry via the API, send a `POST` to `/public/v2/journal-entries/` with header and line data. Set `record_status` to `draft` to save without affecting balances, or `posted` to apply immediately.

The following example creates a posted accrual entry with an automatic reversal:

```json theme={null}
{
  "date": "2026-04-30",
  "company_id": "comp_abc123",
  "memo": "April rent accrual",
  "record_status": "posted",
  "reversal_date": "2026-05-01",
  "lines": [
    { "account_number": "6200", "debit": 5000.00, "memo": "Rent expense" },
    { "account_number": "2100", "credit": 5000.00, "memo": "Accrued liabilities" }
  ]
}
```

When `reversal_date` is set, DualEntry creates a mirror entry on that date with debits and credits swapped. This is the standard pattern for month-end accruals that reverse on the first day of the next period.

Retrieve journal entries with `GET /public/v2/journal-entries/`. The endpoint supports the following filters:

| Parameter              | Description                                        |
| ---------------------- | -------------------------------------------------- |
| `company_id`           | Filter by legal entity.                            |
| `account_id`           | Filter to entries containing a specific account.   |
| `customer_id`          | Filter to entries tagged with a specific customer. |
| `vendor_id`            | Filter to entries tagged with a specific vendor.   |
| `date_from`, `date_to` | Filter by accounting date range.                   |
| `record_status`        | Filter by `draft`, `posted`, or `archived`.        |
| `approval_status`      | Filter by approval workflow state.                 |
| `amount`               | Filter by line amount (exact match or range).      |

Combine filters to narrow results, such as all posted entries for a single vendor within a date range. Pagination defaults to 100 entries per page; use `page` and `page_size` parameters to navigate larger result sets.

## Classifications

Classifications are multi-dimensional tags you apply to journal entry lines for segmented reporting. Common classifications include Department, Location, Project, and Class. Manage classifications through **Settings → Classifications** or via `GET /public/v2/classifications/`.

When you assign a classification to a line, the balance for that line rolls up into dimension-specific reports. This enables analysis like revenue by department or expenses by project without maintaining separate accounts. You can require classifications on specific accounts by enabling the **Require classification** setting on the account. DualEntry blocks posting if a required classification is missing. Classifications are also available as filters in the [flux analysis](../close-management/flux-analysis) and [financial statements](../../reporting-analytics/standard-financial-statements) modules, so the tags you apply at the line level carry through to period-end reporting. You can manage classification values (add, rename, deactivate) through **Settings → Classifications** or the API at any time without affecting historical entries. Deactivated values remain on existing entries but are hidden from selection dropdowns for new entries.

## Recurring and intercompany entries

For entries that repeat on a schedule (monthly rent, depreciation, insurance amortization), use recurring journal entries. Create a template via `POST /public/v2/recurring/journal-entries/` with the same header and line structure, plus a recurrence schedule (frequency, start date, end date). DualEntry generates a draft journal entry from each template on the scheduled date. Review and post the drafts, or configure auto-posting if the amounts are fixed and don't require review.

Intercompany journal entries record transactions that span two or more legal entities. Use `POST /public/v2/intercompany-journal-entries/` to create them. Lines on an intercompany entry reference accounts across different companies, and the entry must balance in aggregate: total debits across all entities equal total credits. DualEntry automatically creates the corresponding intercompany receivable and payable on each entity's books so that individual company trial balances remain in balance. Intercompany eliminations are handled during [consolidation](../../reporting-analytics/standard-financial-statements).

<Info>
  Recurring entries generate drafts by default. Enable auto-posting only for entries with fixed amounts that don't need period-over-period review, such as depreciation on a straight-line asset.
</Info>

## Attachments and locked-period behavior

You can attach supporting documents (scanned invoices, contracts, approvals) to any journal entry. Attachments are stored at the header level and accessible from the entry detail view. Use attachments to maintain the audit trail without relying on external file storage. Supported file types include PDF, PNG, JPEG, and CSV. Each entry supports up to 25 attachments with a maximum file size of 10 MB per attachment.

Entries posted to a [locked period](./period-locking) cannot be edited or voided. If you need to correct an entry in a locked period, unlock the period (requires admin or controller permission) or post an adjusting entry in the current open period. The lock applies to the `date` field. Changing the date on a draft entry to an open period lets you post it even when the original date's period is locked.

<Warning>
  Entries posted to a [locked period](./period-locking) cannot be edited or voided. If you need to correct an entry in a locked period, unlock the period (requires admin or controller permission) or post an adjusting entry in the current open period.
</Warning>

For step-by-step account setup, see [Chart of Accounts](./chart-of-accounts). To protect closed periods from unintended changes, see [Period Locking](./period-locking). For anomaly detection on posted entries, see [Anomaly Detection](../../ai-automation/anomaly-detection).
