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

# Account Statements

> Generate transaction history and balances for ledger accounts

## Overview

**Account Statements** (also called **Ledger Account Statements**) show the complete transaction history for any ledger account, including opening balance, all debits and credits during the period, and closing balance.

<Note>
  **Permission required**: `ledger:read`

  Statements can be generated for any ledger account: member savings, bank accounts, loans, revenue, expenses, assets, or liabilities.
</Note>

***

## API Endpoint

**Get account statements:**

```http theme={null}
POST /ledger-accounts/statements
Headers:
  x-organization-id: {organizationId}
Body:
{
  "accountIds": ["acc-123", "acc-456"],
  "from": "2026-01-01",
  "to": "2026-06-30",
  "option": "period",
  "excludeZeroTransactionAccounts": false
}
```

**Request body:**

| Field                            | Type              | Required | Description                                                                  |
| -------------------------------- | ----------------- | -------- | ---------------------------------------------------------------------------- |
| `accountIds`                     | string\[]         | Yes      | Array of ledger account UUIDs                                                |
| `from`                           | string (ISO date) | Yes      | Statement period start date                                                  |
| `to`                             | string (ISO date) | Yes      | Statement period end date                                                    |
| `option`                         | enum              | Yes      | Statement option: `'all'`, `'current'`, `'period'`, `'custom'`               |
| `excludeZeroTransactionAccounts` | boolean           | No       | If true, exclude accounts with no transactions in period. Defaults to false. |

**Statement options:**

| Option      | Description                                         |
| ----------- | --------------------------------------------------- |
| `'all'`     | All transactions from account creation to `to` date |
| `'current'` | Current period (typically current month)            |
| `'period'`  | Specific date range from `from` to `to`             |
| `'custom'`  | Custom date range (same as `'period'`)              |

**Example request:**

```bash theme={null}
curl -X POST "https://api.agatabo.com/ledger-accounts/statements" \
  -H "x-organization-id: org-abc123" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "accountIds": ["acc-789"],
    "from": "2026-06-01",
    "to": "2026-06-30",
    "option": "period",
    "excludeZeroTransactionAccounts": false
  }'
```

***

## Response Structure

```json theme={null}
[
  {
    "accountId": "acc-789",
    "accountName": "Jane Smith - Savings",
    "accountRole": "SAVINGS",
    "accountType": "LIABILITY",
    "accountStatus": "Active",
    "periodStart": "2026-06-01T00:00:00.000Z",
    "periodEnd": "2026-06-30T00:00:00.000Z",
    "rows": [
      {
        "date": "2026-06-01T00:00:00.000Z",
        "description": "Opening Balance",
        "debit": null,
        "credit": null,
        "balance": 500000.00
      },
      {
        "date": "2026-06-05T00:00:00.000Z",
        "description": "Savings Deposit",
        "debit": null,
        "credit": 20000.00,
        "balance": 520000.00
      },
      {
        "date": "2026-06-10T00:00:00.000Z",
        "description": "Savings Deposit",
        "debit": null,
        "credit": 15000.00,
        "balance": 535000.00
      },
      {
        "date": "2026-06-20T00:00:00.000Z",
        "description": "Loan Disbursement",
        "debit": 200000.00,
        "credit": null,
        "balance": 335000.00
      },
      {
        "date": "2026-06-25T00:00:00.000Z",
        "description": "Savings Deposit",
        "debit": null,
        "credit": 10000.00,
        "balance": 345000.00
      }
    ],
    "totalDebit": 200000.00,
    "totalCredit": 45000.00,
    "closingBalance": 345000.00
  }
]
```

**Response fields:**

| Field            | Type                  | Description                                               |
| ---------------- | --------------------- | --------------------------------------------------------- |
| `accountId`      | string                | Ledger account UUID                                       |
| `accountName`    | string                | Account name (e.g., "Jane Smith - Savings")               |
| `accountRole`    | string                | Account role (SAVINGS, CASH, LOAN\_RECEIVABLE, etc.)      |
| `accountType`    | string                | Account type (ASSET, LIABILITY, EQUITY, REVENUE, EXPENSE) |
| `accountStatus`  | string                | "Active" or "Inactive"                                    |
| `periodStart`    | string (ISO datetime) | Statement period start                                    |
| `periodEnd`      | string (ISO datetime) | Statement period end                                      |
| `rows`           | array                 | Transaction rows (includes opening balance if applicable) |
| `totalDebit`     | number                | Sum of all debits in period (excludes opening balance)    |
| `totalCredit`    | number                | Sum of all credits in period (excludes opening balance)   |
| `closingBalance` | number                | Ending balance                                            |

**Row fields:**

| Field         | Type                  | Description                                       |
| ------------- | --------------------- | ------------------------------------------------- |
| `date`        | string (ISO datetime) | Transaction date                                  |
| `description` | string                | Transaction description (from journal entry kind) |
| `debit`       | number \| null        | Debit amount (null if credit transaction)         |
| `credit`      | number \| null        | Credit amount (null if debit transaction)         |
| `balance`     | number                | Running balance after this transaction            |

***

## Understanding Debits and Credits

**CRITICAL**: Debit and credit directions depend on account type. For member savings accounts (LIABILITY type), the directions are **opposite** of what you might expect:

**For SAVINGS accounts (LIABILITY type):**

* **CREDIT** = Increase (deposits add to balance) ✓
* **DEBIT** = Decrease (withdrawals, loan disbursements reduce balance) ✓

**For CASH accounts (ASSET type):**

* **DEBIT** = Increase (money in) ✓
* **CREDIT** = Decrease (money out) ✓

**For LOAN\_RECEIVABLE accounts (ASSET type):**

* **DEBIT** = Increase (loan granted) ✓
* **CREDIT** = Decrease (payment received) ✓

**For REVENUE accounts:**

* **CREDIT** = Increase (income earned) ✓
* **DEBIT** = Decrease (rare) ✓

**For EXPENSE accounts:**

* **DEBIT** = Increase (expense incurred) ✓
* **CREDIT** = Decrease (rare) ✓

**Tip**: Focus on the **balance** column, not debit/credit. The balance shows the actual amount in the account.

***

## How It Works

The account statements endpoint:

1. **Validates account IDs**
   * Checks that all accountIds exist in organization
   * Returns 404 if any account not found

2. **For each account, gets journal entries in date range**
   * Filters by transactionDate between `from` and `to`
   * Only includes POSTED entries (excludes DRAFT)
   * Excludes reversed entries (reversedEntryId = null)
   * Sorts by transaction date ascending

3. **Finds opening balance**
   * Looks for journal entry with transactionDate = null (opening balance entry)
   * Calculates balance after that entry
   * Includes as first row if appropriate

4. **Creates transaction rows**
   * For each journal entry:
     * Extracts debit or credit amount for this account
     * Gets running balance from ledger
     * Formats description from journal entry kind

5. **Calculates totals**
   * Sums all debits (excludes opening balance row)
   * Sums all credits (excludes opening balance row)
   * Gets closing balance from last row

6. **Filters zero-transaction accounts (optional)**
   * If `excludeZeroTransactionAccounts = true`
   * Removes accounts where no debits or credits occurred in period

***

## Common Use Cases

### Member Savings Statements

**Generate statements for all members:**

```http theme={null}
POST /ledger-accounts/statements
{
  "accountIds": ["acc-001", "acc-002", "acc-003"],  // All member SAVINGS account IDs
  "from": "2026-04-01",
  "to": "2026-06-30",
  "option": "period",
  "excludeZeroTransactionAccounts": true  // Exclude members with no activity
}
```

**Use case**: Quarterly member statements for distribution at meetings

**What members see:**

* Opening balance at start of quarter
* All deposits made
* All withdrawals (if any)
* Loan disbursements from their savings
* Dividend distributions
* Closing balance

***

### Bank Account Reconciliation

**Generate Agatabo bank statement:**

```http theme={null}
POST /ledger-accounts/statements
{
  "accountIds": ["acc-bank-123"],  // Bank CASH account ID
  "from": "2026-06-01",
  "to": "2026-06-30",
  "option": "period"
}
```

**Compare to actual bank statement:**

1. Download bank statement from bank
2. Generate Agatabo statement for same period
3. Compare line by line:
   * Agatabo DEBITS = Bank deposits (money in)
   * Agatabo CREDITS = Bank withdrawals (money out)
4. Identify differences:
   * Uncleared checks
   * Bank fees not yet recorded
   * Deposits in transit
   * Errors

See: [Monthly Closing Checklist](/tontines/workflows/monthly-closing-checklist)

***

### Loan Account Analysis

**Track loan principal changes:**

```http theme={null}
POST /ledger-accounts/statements
{
  "accountIds": ["acc-loan-456"],  // Specific LOAN_RECEIVABLE account
  "from": "2026-01-01",
  "to": "2026-06-30",
  "option": "period"
}
```

**Analysis:**

* Opening balance: Principal at start of period
* DEBITS: Additional loans granted (increases receivable)
* CREDITS: Payments received (decreases receivable)
* Closing balance: Outstanding principal

***

### Revenue/Expense Statements

**Track interest income:**

```http theme={null}
POST /ledger-accounts/statements
{
  "accountIds": ["acc-interest-income"],  // INTEREST_INCOME account
  "from": "2026-01-01",
  "to": "2026-12-31",
  "option": "period"
}
```

**Shows:**

* All interest earned during year
* Breakdown by transaction date
* Total interest income (totalCredit for revenue accounts)

***

## Statement Options Explained

**`option: 'all'`**

* Includes ALL transactions from account creation to `to` date
* Ignores `from` parameter
* `periodStart` set to account creation date or earliest transaction
* Use for: Complete account history

**`option: 'current'`**

* Typically current month (implementation may vary)
* Uses `from` and `to` dates provided
* Use for: Monthly statements

**`option: 'period'`**

* Specific date range from `from` to `to`
* Use for: Custom periods (quarterly, annual, etc.)

**`option: 'custom'`**

* Same as `'period'`
* Specific date range from `from` to `to`

***

## Bulk Statement Generation

**Generate statements for all member savings accounts:**

**Step 1**: Get all member savings account IDs

```http theme={null}
GET /ledger-accounts?role=SAVINGS
```

**Step 2**: Extract accountIds from response

```typescript theme={null}
const accountIds = accounts.map(account => account.id);
```

**Step 3**: Request statements

```http theme={null}
POST /ledger-accounts/statements
{
  "accountIds": accountIds,
  "from": "2026-04-01",
  "to": "2026-06-30",
  "option": "period",
  "excludeZeroTransactionAccounts": true
}
```

**Step 4**: Process response

Response contains array of statements (one per account). Use this data to:

* Generate PDF statements for printing
* Create CSV exports for analysis
* Send email statements to members
* Display in web interface

***

## Filtering Zero-Transaction Accounts

**Problem**: When generating bulk member statements, some members may have no activity during the period. Including them creates unnecessary empty statements.

**Solution**: Use `excludeZeroTransactionAccounts: true`

**Example:**

```http theme={null}
POST /ledger-accounts/statements
{
  "accountIds": ["acc-001", "acc-002", "acc-003", "acc-004"],
  "from": "2026-06-01",
  "to": "2026-06-30",
  "option": "period",
  "excludeZeroTransactionAccounts": true  // ← Exclude inactive accounts
}
```

**Result**: Only accounts with at least one debit or credit transaction in the period are returned.

**Use case**: Quarterly statements - only send statements to members who had activity.

***

## Opening Balance Calculation

**Opening balance** appears as first row if:

1. Account has an opening balance entry (journal entry with transactionDate = null)
2. Statement includes the first dated transaction for this account

**Why conditional?**

If statement period starts mid-year (e.g., June 1), and account was created January 1:

* Opening balance entry exists (from January 1)
* But statement doesn't include first dated transaction (which was in January)
* So opening balance row is NOT included
* Instead, first row shows balance as of June 1

**When opening balance IS included:**

Statement with `option: 'all'` includes all transactions from account creation:

* Opening balance entry exists
* First dated transaction is included
* Opening balance row appears

***

## Transaction Descriptions

**Description** field comes from journal entry `kind` field, formatted for readability:

| Journal Entry Kind     | Description           |
| ---------------------- | --------------------- |
| SAVINGS\_DEPOSIT       | Savings Deposit       |
| LOAN\_DISBURSEMENT     | Loan Disbursement     |
| LOAN\_PAYMENT          | Loan Payment          |
| LOAN\_PENALTY          | Loan Penalty          |
| EXPENSE\_PAYMENT       | Expense Payment       |
| DIVIDEND\_DISTRIBUTION | Dividend Distribution |
| RESERVE\_TOP\_UP       | Reserve Top Up        |
| BANK\_CHARGE           | Bank Charge           |
| PERIOD\_CLOSE          | Period Close          |

***

## Best Practices

<Note>
  **Generating account statements:**

  **For members:**

  * ✅ Generate quarterly statements for all active members
  * ✅ Use `excludeZeroTransactionAccounts: true` to skip inactive accounts
  * ✅ Print and distribute at member meetings for transparency
  * ✅ Verify spot-check statements against deposit records

  **For reconciliation:**

  * ✅ Generate bank statements monthly after downloading bank records
  * ✅ Use exact date range matching bank statement
  * ✅ Document all differences (uncleared checks, bank fees, etc.)
  * ✅ Post adjusting entries before closing period

  **For analysis:**

  * ✅ Use `option: 'all'` for complete account history
  * ✅ Use `option: 'period'` for specific date ranges
  * ✅ Export to CSV for spreadsheet analysis
  * ✅ Compare period-over-period to identify trends

  **Security:**

  * ✅ Member savings statements contain sensitive data
  * ✅ Only generate for authorized personnel
  * ✅ Don't email unencrypted statements
  * ✅ Hand-deliver printed statements to members
  * ✅ Store exports in password-protected folders
</Note>

***

## Troubleshooting

**Q: Balance doesn't match what I expect**

A: Check:

* Correct account selected? (Names can be similar)
* Date range includes all expected transactions?
* Compare to deposit/withdrawal records
* Verify with Balance Sheet total for all member savings

**Q: Missing transactions in statement**

A: Possible causes:

* Transaction date outside selected date range
* Transaction posted to different account by mistake
* Transaction in closed period (check earlier date ranges)
* Journal entry reversed or deleted (check audit logs)

**Q: Can't find member's savings account**

A: Solutions:

* Verify member actually has savings account created
* Search by partial name (account name format: "{Name} - Savings")
* Check that account is active (inactive accounts may be hidden)
* Use GET /ledger-accounts?role=SAVINGS to list all

**Q: Opening balance seems wrong**

A: Opening balance = closing balance of previous period. If wrong:

* Check if prior periods reconciled correctly
* Generate statement for prior period to trace error
* Verify opening balance entry (transactionDate = null) is correct
* May need adjusting journal entry

**Q: Why are debits and credits backwards for member savings?**

A: Member savings accounts are LIABILITY type (money the organization owes to members). In double-entry accounting:

* LIABILITY accounts INCREASE with CREDIT
* LIABILITY accounts DECREASE with DEBIT

This is correct. Focus on the balance column instead.

***

## Example: Monthly Member Statements

**Scenario**: Generate statements for all members for June 2026

**Step 1**: Get member savings account IDs

```http theme={null}
GET /ledger-accounts?role=SAVINGS
```

**Step 2**: Generate statements

```http theme={null}
POST /ledger-accounts/statements
{
  "accountIds": ["acc-001", "acc-002", "acc-003", ...],
  "from": "2026-06-01",
  "to": "2026-06-30",
  "option": "period",
  "excludeZeroTransactionAccounts": true
}
```

**Step 3**: Process response

```json theme={null}
[
  {
    "accountId": "acc-001",
    "accountName": "Jane Smith - Savings",
    "accountRole": "SAVINGS",
    "accountType": "LIABILITY",
    "periodStart": "2026-06-01T00:00:00.000Z",
    "periodEnd": "2026-06-30T00:00:00.000Z",
    "rows": [...],
    "totalDebit": 0,
    "totalCredit": 60000,
    "closingBalance": 560000
  },
  {
    "accountId": "acc-002",
    "accountName": "Peter Kalisa - Savings",
    ...
  }
]
```

**Step 4**: Generate PDFs and distribute

Use statement data to create formatted PDFs for each member, print, and hand out at monthly meeting.

***

## Related Topics

<CardGroup cols={2}>
  <Card title="Ledger Accounts" icon="book" href="/tontines/general-ledger/ledger-accounts">
    Understanding chart of accounts
  </Card>

  <Card title="Journal Entries" icon="book-open" href="/tontines/general-ledger/viewing-journal-entries">
    Transaction details behind statements
  </Card>

  <Card title="Monthly Closing Checklist" icon="check-double" href="/tontines/workflows/monthly-closing-checklist">
    Reconciliation and closing procedures
  </Card>

  <Card title="Understanding Double-Entry" icon="scale-balanced" href="/tontines/general-ledger/understanding-double-entry">
    Accounting principles for statements
  </Card>
</CardGroup>
