Skip to main content

General Ledger

The general ledger (GL) is the accounting backbone of the platform. It provides a hierarchical chart of accounts, double-entry journal posting with approval workflows, and standing instructions for recurring entries.

Chart of Accounts​

Account Categories​

CategoryNormal BalanceExamples
assetDebitCash, receivables, loans, fixed assets
liabilityCreditCustomer deposits, payables
equityCreditShare capital, reserves
revenueCreditInterest income, fee income
expenseDebitInterest expense, operating expenses

Pre-seeded Account Types​

CodeNameCategoryNormal Balance
CASHCash and Cash Equivalentsassetdebit
RECVReceivablesassetdebit
LOAN_ASSETLoans and Advancesassetdebit
FIXED_ASSETFixed Assetsassetdebit
DEPOSITCustomer Depositsliabilitycredit
PAYABLEPayablesliabilitycredit
CAPITALShare Capitalequitycredit
RESERVESReservesequitycredit
INT_INCOMEInterest Incomerevenuecredit
FEE_INCOMEFee Incomerevenuecredit
INT_EXPENSEInterest Expenseexpensedebit
OP_EXPENSEOperating Expensesexpensedebit

Account Hierarchy​

GL accounts form a tree. Header accounts (non-posting) organize the tree; leaf accounts allow direct posting.

1000 Assets (header)
├── 1100 Cash and Bank (header)
│ ├── 1101 Cash on Hand (posting)
│ └── 1102 Bank Balances (posting)
├── 1200 Loans and Advances (header)
│ ├── 1201 Personal Loans (posting)
│ └── 1202 Business Loans (posting)
2000 Liabilities (header)
├── 2100 Customer Deposits (header)
│ ├── 2101 Savings Deposits (posting)
│ └── 2102 Current Deposits (posting)

Create a GL Account​

POST /api/v1/accounts
{
"account_number": "1103",
"name": "Money Market Instruments",
"description": "Short-term money market holdings",
"account_type_id": "cash-type-uuid",
"parent_id": "1100-header-uuid",
"currency_code": "NGN",
"is_header_account": false,
"is_control_account": false,
"allow_direct_posting": true,
"tags": ["treasury"],
"metadata": {}
}

Requires officer role.

List GL Accounts​

GET /api/v1/accounts?currency=NGN&active=true

Get Account Balance and Ledger​

GET /api/v1/accounts/:id/balance
GET /api/v1/accounts/:id/ledger

Journals​

A journal is a group of balanced debit and credit entries. Every financial event in the system is recorded as a journal.

Journal Lifecycle​

PENDING ──▶ APPROVED ──▶ POSTED
│ │ │
▼ ▼ ▼
REJECTED REJECTED REVERSED
StatusDescription
PENDINGCreated, awaiting approval
APPROVEDApproved, ready to post
POSTEDEntries applied to account balances
REJECTEDRejected by approver
REVERSEDPosted journal reversed (creates a reversing journal)

Create a Journal​

curl -X POST https://api.korastratum.com/api/v1/cba/journals \
-H "Authorization: Bearer $TOKEN" \
-H "X-Tenant-ID: demo_bank" \
-H "Content-Type: application/json" \
-H "X-Idempotency-Key: jnl-$(uuidgen)" \
-d '{
"journal_type": "REVENUE",
"description": "Monthly service charge",
"fiscal_period_id": "period-uuid",
"transaction_date": "2026-02-28",
"effective_date": "2026-02-28",
"source_system": "ACCOUNT_SERVICE",
"source_reference": "FEE20260228001",
"entries": [
{
"account_id": "receivable-uuid",
"amount": 1000.00,
"entry_type": "debit",
"currency_code": "NGN",
"description": "Service charge debit"
},
{
"account_id": "fee-income-uuid",
"amount": 1000.00,
"entry_type": "credit",
"currency_code": "NGN",
"description": "Service charge income"
}
]
}'

Requires teller role. The journal is created with status PENDING.

Validation Rules​

  • Must balance — Total debits must equal total credits.
  • Positive amounts — Entry amounts must be greater than zero. The entry_type (debit/credit) determines direction.
  • Open period — The fiscal_period_id must reference an open fiscal period.
  • Active accounts — All referenced accounts must be active and allow direct posting.
  • Same base currency — All entries must resolve to the same base currency.

Approve and Post​

POST /api/v1/journals/:id/approve   # Requires officer role
POST /api/v1/journals/:id/post # Requires officer role

When a journal is posted:

  1. Account balance snapshots are created for each affected account.
  2. Cached balances are updated atomically.
  3. A transaction.completed event is emitted.

Reject​

POST /api/v1/journals/:id/reject    # Requires officer role

Reverse a Posted Journal​

POST /api/v1/journals/:id/reverse   # Requires manager role

Creates a new reversing journal with opposite entries. The original journal's status changes to REVERSED.

Batch Operations​

Create multiple journals at once:

POST /api/v1/journals/batch         # Requires officer role

Post multiple journals at once:

POST /api/v1/journals/batch/post    # Requires manager role

Inter-Branch Transfer​

Transfer between GL accounts across branches:

POST /api/v1/journals/inter-branch-transfer   # Requires manager role

Multi-Currency Entries​

For non-base currency entries, include the exchange rate:

{
"account_id": "usd-account-uuid",
"amount": 1000.00,
"entry_type": "debit",
"currency_code": "USD",
"exchange_rate": 1580.50,
"base_currency_amount": 1580500.00,
"description": "USD receipt"
}

Standing Instructions​

Recurring journal entries that execute automatically on a schedule.

Create a Standing Instruction​

POST /api/v1/standing-instructions
{
"name": "Monthly depreciation",
"description": "Fixed asset depreciation posting",
"journal_type": "DEPRECIATION",
"frequency": "MONTHLY",
"start_date": "2026-01-01",
"end_date": "2026-12-31",
"max_executions": 12,
"entries": [
{
"account_id": "depreciation-expense-uuid",
"amount": 50000.00,
"entry_type": "debit",
"currency_code": "NGN"
},
{
"account_id": "accumulated-depreciation-uuid",
"amount": 50000.00,
"entry_type": "credit",
"currency_code": "NGN"
}
]
}

Requires officer role. Approval by manager role is required before the instruction becomes active.

Frequencies​

FrequencySchedule
DAILYEvery day
WEEKLYEvery 7 days
BI_WEEKLYEvery 14 days
MONTHLYSame day each month
QUARTERLYEvery 3 months
ANNUALLYOnce per year

Manage Standing Instructions​

POST /api/v1/standing-instructions/:id/approve   # manager role
POST /api/v1/standing-instructions/:id/pause # officer role
POST /api/v1/standing-instructions/:id/resume # officer role
POST /api/v1/standing-instructions/:id/cancel # manager role
POST /api/v1/standing-instructions/execute # admin role — trigger pending executions

Next Steps​