Corgi BankDocumentation
OpenAPI

Ledger, journals and holds

The ledger is double entry. Money moves only as a journal whose debits equal its credits, and a hold reserves part of a balance without moving it.

Journals

A journal has a kind, a source_service and source_ref, an effective_date and at least two entries. Each entry names a ledger_account_id, a direction of debit or credit, and a positive amount with its currency_code. Debits must equal credits, or the journal is refused with ledger.journal_unbalanced. Journals and entries are append-only.

Services post the journals: a book transfer posts one of kind transfer. POST /ledger/journals needs the ledger:post scope, which only services hold. A repeated idempotency key returns the original journal, or conflict if the instruction differs. Each posting publishes ledger.journal.posted.

Business dates and closing

The business date is the Eastern calendar date. After the cutoff, currently 4:00 p.m., and on weekends and Federal Reserve holidays, it is the next banking day. See GET /ledger/business-date. A journal's posting_date is the business date it was recorded on, and its effective_date cannot be later. An earlier one makes the journal backdated: it needs a reason and reaches back 30 days at most.

End of day closes a date, expires the holds that are due, snapshots every balance and proves the trial balance. Once a date is closed, a journal reaches it only by backdating (ledger.business_date_closed otherwise). The month-end close seals a YYYY-MM period, after which no journal may carry an effective date inside it (ledger.period_closed). A correction posts in the open period and names the sealed one in adjusts_period.

Holds and available balance

Available is posted less active holds. A hold has a kind (card_authorization, reg_cc_availability, pending_debit or legal), an amount, an optional expires_at and a status of active, released or expired. On an account that may not go negative, a hold larger than the available balance, or a journal that would leave the posted balance below the active holds, is refused with ledger.insufficient_available.

A journal can name a release_hold_id, so the hold is released in the same transaction as the posting. Only the service that placed a hold may release it.

Reversals

POST /ledger/journals/{id}/reverse posts a journal of kind reversal with the entries mirrored and reversal_of set. A journal is reversed once (ledger.journal_already_reversed), and a reversal cannot itself be reversed.

Manual postings

A journal of kind manual needs posted_by and a different approved_by, or it is refused with ledger.maker_checker_required. Staff submit a request of kind manual_journal, a second person decides it (the maker is answered operations.same_person), and the operations service posts the journal with both names.

Every field is listed in the Journal object and the Hold object.

to move to open esc to close