Accounting
Accounting workflow coverage, close discipline, and the controls that keep commercial activity translatable into finance truth.
Scope
Accounting is where Keystone has to prove it can carry commercial activity into durable financial truth. This guide keeps the operator-focused workflow coverage while leaving private reference detail out.
Chart of accounts, journal entries, general ledger, budgets, financial statements, LLC members, and monthly/year-end close processes.
Accounting: Chart of Accounts
The Chart of Accounts (COA) is the foundation of the general ledger. Keystone ships with a default COA that includes standard accounts for a small business.
Account Types
| Type | Normal Balance | Examples |
|---|---|---|
asset |
debit | Cash, AR, Equipment |
liability |
credit | AP, Loans, Sales Tax Payable |
equity |
credit | Owner’s Capital, Retained Earnings |
revenue |
credit | Service Revenue, Product Sales |
expense |
debit | Rent, Utilities, Salaries |
List Accounts
Tree View
Returns accounts in a hierarchical tree structure with parent-child relationships.
Get Account with Balance
Returns account details plus current balance. Supports as_of_date query parameter (YYYY-MM-DD format) for historical balance lookups.
Create Account
Fields:
- account_number (required) – must be unique
- name (required)
- description
- normal_balance – auto-derived from account_type if not specified
- tax_category – for tax deduction mapping
- sort_order
User-created accounts are never marked as system accounts.
Update Account
Deactivate Account
Soft-deletes (deactivates) the account. Fails if: - The account is a system account - The account has a non-zero balance (transfer the balance first)
Journal Entries
Journal entries are the core of double-entry bookkeeping. Every financial transaction in Keystone creates journal entries.
Types of Journal Entries
| Type | Source |
|---|---|
manual |
Created by user via API |
auto_invoice_sent |
Invoice sent to customer |
auto_invoice_paid |
Invoice payment received |
auto_invoice_voided |
Invoice voided |
auto_payment |
Payment recorded |
auto_credit |
Credit issued |
auto_refund |
Refund processed |
auto_expense |
Expense approved/paid |
auto_bill |
Bill approved/paid |
closing |
Year-end closing entry |
reversing |
Reversal of another entry |
List Journal Entries
Returns paginated response with items array and total count.
Get Journal Entry Detail
Returns the entry with all lines, including account numbers and names.
Create Manual Journal Entry
Fields:
- entry_date (required) – must fall in an open fiscal period
- description (required)
- lines (required, at least 2):
- description
- debit_cents – exactly one of debit/credit must be non-zero per line
- credit_cents
Validation rules: - Total debits must equal total credits - Each line must have exactly one non-zero side (debit or credit, not both) - The fiscal period for the entry date must exist and be open
Reverse a Journal Entry
Creates a new entry with all debits and credits swapped. Marks the original as reversed.
General Ledger
The GL provides a detailed view of all posted transactions.
Paginated Ledger
Returns all journal lines from posted entries, joined with account details.
Account Activity Detail
All activity for a single account with:
- opening_balance_cents – balance as of the day before date_from
- lines – all transactions in the date range
- closing_balance_cents – computed from opening + net activity
Budgets
Budgets let you plan spending by GL account and month, then compare against actual GL activity.
Create a Budget
Fields:
- name (required) – e.g., “2026 Operating Budget”
- fiscal_year (required) – 2000-2100
- lines – array of budget line items:
- month (required) – 1-12
- amount_cents (required)
No duplicate lines allowed (same account + month).
Budgets start in draft status.
Budget Lifecycle
- Draft: lines can be modified
- Active: locked for tracking; cannot modify lines
- Closed: finalized
Update a Budget
Can update name, status, and lines (lines only on draft budgets).
Budget vs Actual Variance
Compares budgeted amounts against actual GL activity for each account/month combination. Returns: - Per-line: budget, actual, variance (cents and percentage) - Totals: total budget, total actual, total variance
Financial Statements and Reports
Trial Balance
Lists all accounts with their debit and credit totals. Supports as_of_date and optional period_start parameters.
- As of Date: The end date for the trial balance (defaults to today).
- Period Start (optional): When set, revenue and expense accounts show only activity within the
[period_start, as_of_date]range. Balance sheet accounts (asset, liability, equity) always show cumulative balances throughas_of_date. Leave empty for a cumulative trial balance.
Total debits should equal total credits if the books are balanced.
Profit & Loss (Income Statement)
Full ASC 220 multi-step income statement with sections:
1. Revenue – operating revenue accounts (excludes other_revenue, contra_revenue)
2. Cost of Goods Sold – expense accounts with sub_type cogs
3. Gross Profit – revenue minus COGS (subtotal)
4. Operating Expenses – all non-COGS, non-tax, non-other expense accounts
5. Operating Income – gross profit minus operating expenses (subtotal)
6. Other Income – non-operating revenue (sub_type other_revenue)
7. Other Expenses – non-operating expenses (sub_type other_expense)
8. Income Before Tax – operating income + other income - other expenses (subtotal)
9. Tax Expense – tax-related expenses (sub_type tax)
10. Net Income – income before tax minus tax expense (final total)
Each line item and subtotal displays a percentage-of-revenue column showing the item as a percentage of total revenue (e.g., “42.1%”). Zero revenue displays “—”.
Supports compare_period parameter:
- prior_year – same period in the previous year
- prior_period – immediately preceding period of the same length
Balance Sheet
Assets = Liabilities + Equity. Supports as_of_date and compare_date for period comparison.
Returns is_balanced flag – should be true if the books are correct.
Cash Flow Statement
Uses the indirect method (the standard presentation for non-public companies). Sections: - Operating Activities – starts with net income, adds back non-cash expenses (depreciation/amortization), then adjusts for changes in working capital accounts (AR, AP, prepaid expenses, accrued liabilities). An increase in AR reduces operating cash (revenue recognized but not collected); an increase in AP increases operating cash (expenses incurred but not paid). - Investing Activities – changes in fixed asset accounts and accumulated depreciation - Financing Activities – changes in equity accounts and long-term liabilities
Returns method: "indirect", opening/closing cash balances, and net change. The statement “proves out”: opening cash + net change = closing cash.
GL Cash Reconciliation (ASC 230): Below the closing cash balance, the UI displays a reconciliation section comparing computed closing cash (opening + net change) against the actual GL cash balance. When they match, a green “Reconciled” badge appears. When they differ, a warning-highlighted card shows the actual GL balance, the computed balance, and the difference amount in red – indicating unreconciled transactions that need investigation.
AR Aging (Accounting)
Detailed AR aging from unpaid invoices, grouped by customer. Buckets: current (not yet due), 1-30 days, 31-60 days, 90+ days past due.
Cash Position
Real-time cash balances across all bank/cash accounts (accounts starting with “10” or sub_type “cash”). Supports as_of_date.
In-Product Statements Workspace
The the relevant workflow page now consolidates these accounting workflows for operators:
- Trial Balance, P&L, Balance Sheet, and Cash Flow statement generation
- AR Aging and Cash Position reporting
- P&L compare-period review (
prior_periodorprior_year) - Balance sheet comparison-date review
- Fiscal period management (create, close, reopen) for users with
keystone.accounting.manage - Year-end close execution for users with
keystone.accounting.manage
LLC Member Management
For multi-member LLCs and partnerships, Keystone tracks members, ownership percentages, distributions, and K-1 data.
List Members
Filter: active_only (default: true). Tax IDs are always masked in list view.
Add a Member
Fields:
- name (required)
- email
- ownership_percentage (required) – total of all members cannot exceed 100%
- join_date
Adding a member automatically: 1. Creates a Capital sub-account (30xx series) under Owner’s Equity 2. Creates a Draws sub-account (31xx series) for distributions 3. Links both accounts to the member
Update a Member
Ownership percentage changes are validated against other active members to prevent exceeding 100%.
Record a Distribution
Fields:
- amount_cents (required, > 0)
- distribution_date – defaults to today
- notes
Automatically creates a journal entry:
- draw: debit Draws account, credit Cash
- return_of_capital: debit Capital account, credit Cash
K-1 Summary
Returns Schedule K-1 data:
- ownership_percentage
- total_distributions_cents – all distributions in the year
- allocated_income_cents – member’s share of net income (based on ownership %)
- Detailed distribution list
Monthly Close Process
The monthly close ensures all transactions are recorded and verified before locking a period.
Fiscal Periods
Fiscal periods represent months. Every journal entry must fall in an open fiscal period.
Create fiscal period:
Fields:
- year (required)
- month (required, 1-12)
No duplicate year/month combinations allowed.
List fiscal periods:
Close a fiscal period:
Prevents new journal entries in that month. Fiscal periods must be closed in chronological order – you cannot close March if February is still open.
Re-open a fiscal period:
Re-opens a closed period. Locked periods cannot be re-opened.
Close Runs
Close runs are automated checklists that verify the period is ready to close.
Initiate a close run:
Fields:
- variance_threshold_pct – for flagging unusual variances (default from config)
The close engine: 1. Validates the fiscal period is open 2. Runs automated checklists (unreconciled transactions, missing entries, etc.) 3. Computes variance reports 4. Takes a snapshot of account balances
Results in one of:
- completed – all checks passed, period can be closed
- blocked – exceptions found, requires review
View close run results:
Returns checklist results, exception count, variance report, and snapshot data.
In the the relevant workflow workspace, blocked runs now show a readiness summary, source-linked journal-entry drill-down for actionable checklist failures, and account-ledger evidence for variance rows. The evidence links stay read-only; they are there to explain the exception before an override is used.
Approve a blocked close run:
Fields:
- reason (required) – explanation for overriding exceptions
The approval record preserves the reason and approver identity on the close-run detail view. The creator stays separate from the approver.
If a checklist warning does not expose a source record, the UI shows that explicitly instead of pretending there is a drill-down.
Accrual Templates
Set up recurring accruals that are automatically applied during the close process.
List accrual templates:
Create accrual template:
Fields:
- name (required)
- description
- amount_cents (required, > 0)
In the the relevant workflow template modal, the debit and credit account pickers are searchable. Type an account number or name to query active GL accounts through the account lookup API; the picker is no longer limited to the first page of the chart of accounts.
Deactivate template:
Soft-deletes (deactivates).
Recommended Monthly Close Workflow
- Ensure all invoices for the month are sent
- Record all payments received
- Approve and pay all expenses/bills
- Import and reconcile bank transactions
- Review trial balance
- Initiate a close run
- Resolve any exceptions (or approve with reason)
- Close the fiscal period
Year-End Close
Year-end closing zeros all revenue and expense accounts into retained earnings.
Fields:
- fiscal_year (required)
Prerequisites: - All 12 fiscal periods for the year must be closed - No existing closing entries for the year (idempotent check)
What it does: 1. Calculates net income (revenue minus expenses) for the year 2. Creates closing journal entries: - Zeros each revenue account (debit Revenue, credit Income Summary) - Zeros each expense account (credit Expense, debit Income Summary) - Transfers net income to Retained Earnings (account 3200) 3. Returns the closing entries created and net income
Deferred Revenue Dashboard
Navigation: Sidebar > Financials > Accounting > Deferred Revenue
The Deferred Revenue page provides full visibility into ASC 606 revenue recognition:
Summary Cards
At the top of the page, four cards show: - Total Deferred Balance — the current GL 2600 balance (unrecognized revenue liability) - Active Schedules — count of schedules still being recognized - Next Recognition — the date the next automated recognition will run (end of current month) - Recognized YTD — total revenue recognized so far this calendar year
Schedules Tab
Lists all deferred revenue schedules with: - Customer name and invoice number - Total deferred amount, recognized amount, and remaining amount - Visual progress bar showing recognition percentage - Service period (start and end dates) - Status badge (Active, Fully Recognized, Cancelled)
Click any schedule row to open a detail modal showing all recognition entries, GL account mapping, and recognition method.
Use the status filter dropdown to show only active, fully recognized, or cancelled schedules.
Waterfall Tab
Projects expected revenue recognition over the next 12 months: - Visual bar chart showing monthly projected amounts - Tabular breakdown with monthly totals - Uses the same day-based pro-rata logic as the automated recognition engine
Recognition History Tab
Shows recent recognition entries across all schedules: - Date, customer, invoice, recognition period, amount, and status - Newest entries first (up to 50)
How Schedules Are Created
Deferred revenue schedules are created automatically when an invoice with a service period (service_start_date / service_end_date) is sent. No manual creation is needed.
How Recognition Works
The daily scheduler runs recognize_deferred_revenue() which:
1. Finds all active schedules
2. For each elapsed month in the service period, calculates the pro-rata amount
3. Posts a journal entry (DR Deferred Revenue 2600 / CR Revenue 4000)
4. Creates a recognition entry record
5. Marks the schedule as fully_recognized when complete