Journal entries are the atomic unit of the general ledger. Every financial event in CEF Core -- whether posted manually or generated automatically by a subledger -- is recorded as a balanced journal entry with one or more debit and credit lines.
CEF Core distinguishes between two categories of journal entries based on their source.
Created by authorized users through the UI or API for adjustments, corrections, accruals, and reclassifications that are not generated by a subledger.
MANUALGenerated by subledger transactions. When you record a loan payment, issue a note, or process a cash receipt, the subledger posts a balanced journal entry to the GL automatically.
LOANS, INVESTOR_NOTES, CASH, FEESFollow these steps to create a manual journal entry through the UI.
YYYY-MM-DD format. Must fall within an open accounting period. Backdated entries to closed periods will be rejected.gl_code -- The GL account number (e.g., 1200, 6000)debit -- Amount to debit (or 0)credit -- Amount to credit (or 0)Each line must have either a debit or a credit amount, not both. Add as many lines as needed.
POST /api/v1/gl/journal-entries with an idempotency key to prevent duplicate postings.Important: Journal entries over $10,000 automatically trigger the maker-checker approval workflow. The entry will not post immediately. Instead, it is queued for approval and a second authorized user must approve it in Admin → Approvals before it posts to the GL.
CEF Core enforces strict double-entry balance rules at multiple levels. Every journal entry must balance to the penny before it can be posted.
The journal entry form calculates the debit and credit totals in real time. The Save button is disabled until sum(debit) = sum(credit).
The backend Zod schema validates that the lines array contains at least two entries and that debits equal credits. Unbalanced entries return HTTP 400 with a clear error message.
As a final safeguard, a PostgreSQL trigger on the gl.journal_entry_line table rejects any insert batch where debits do not equal credits. This prevents imbalanced entries even if the API validation is bypassed.
Example: To record a $5,000 loan loss provision, create a two-line entry: Debit 6100 (Provision Expense) $5,000 and Credit 1400 (Allowance for Loan Losses) $5,000. Total debits = total credits = $5,000.
When you perform a transaction in a subledger (Loans, Investor Notes, Cash, or Fees), the subledger service automatically creates a journal entry in the GL. You do not need to create these entries manually.
The journal entries list provides filters to locate specific entries. Navigate to Accounting → Journal Entries to access the list.
startDate and endDate to view entries within a specific period. Defaults to the current month.limit and offset parameters. Default limit is 50 entries per page.Click on any entry row to expand it and see the full list of journal lines with GL codes, descriptions, and debit/credit amounts.
CEF Core enforces the four-eyes principle for journal entries exceeding $10,000. This applies to the total debit amount of the entry.
HTTP 202 Accepted with an approval_id. The entry is not yet posted to the GL.Note: The same user who created the entry cannot approve it. The checker must be a different user with ADMIN or TREASURY role.
Journal entries are managed through the GL API. All requests require JWT authentication and an idempotency key header for POST operations.
| Method | Endpoint | Description |
|---|---|---|
GET | /api/v1/gl/journal-entries | List entries (query: ?startDate, endDate, limit, offset) |
POST | /api/v1/gl/journal-entries | Create a new journal entry (idempotency key required) |
GET | /api/v1/gl/journal-entries/:id | Get a single entry with all lines |
{
"description": "Monthly loan loss provision",
"value_date": "2026-03-31",
"lines": [
{ "gl_code": "6100", "debit": 5000.00, "credit": 0 },
{ "gl_code": "1400", "debit": 0, "credit": 5000.00 }
]
}Pro Tip: Always include the x-idempotency-key header with a unique UUID for every POST request. If a network error causes a retry, the idempotency key prevents the entry from being posted twice.
After recording journal entries, use the financial reports to verify account balances and generate statements for stakeholders.
Financial Reports Guide