Corgi BankDocumentation
OpenAPI

Opening accounts

An account is one balance in the ledger, opened on one version of a product and owned by one or more verified customers.

Products and versions

A product is a versioned definition of type, currency, interest, fees, limits and statement cycle. GET /products lists every version with its status: draft, approved, live, closed_to_new or retired. An account opens on the highest live version of its product_code and keeps that product_version. Changed terms are a new version. Only products of the deposit family open accounts. Any other code, or one with no live version, answers accounts.product_not_live.

TypeFor a personFor a business
checkingconsumer_checking, and consumer_checking_eur, _gbp, _cad, _jpybusiness_checking, business_analysis_checking
savingsconsumer_savings, and consumer_savings_eur, _gbp, _cad, _jpybusiness_savings
money_marketconsumer_money_market
certificateconsumer_cd_12m, brokered_cd_12mbusiness_cd_3m, _6m, _12m, _24m, _36m, business_jumbo_cd_12m, _24m

A product in a currency other than USD opens only where the ledger holds that currency. Elsewhere the request answers accounts.currency_unsupported.

The request

POST /accounts requires an Idempotency-Key and two fields: owners, a list of distinct customer ids whose first entry is the primary owner, and product_code. Every owner must pass the opening gate, or the request answers accounts.customer_not_eligible. Optional fields are a description (the product's name when omitted), the ownership titling, the acknowledgement below, and screening, a deposit-account screening inquiry that can refuse the opening with accounts.deposit_screening_declined.

Opening creates the ledger account under the product's GL code, a default account number, and an interest plan when the product bears interest. A certificate also gets its certificate terms, among them maturity_date and penalty_days.

Consumer accounts

A product for a person opens only on an acknowledgement of its opening documents. GET /products/{code}/opening-documents serves the deposit agreement and the E-SIGN disclosure, each with a version and the SHA-256 of its text. The request echoes them back:

  • agreement_version and agreement_sha256 must be the ones served for the live version.
  • method is electronic or in_person_signature, and delivery is electronic or paper. Electronic delivery needs the electronic method.
  • An electronic acknowledgement carries e_sign: the disclosure_version and disclosure_sha256 served, accepted set to true, and method electronic. A signature carries no e_sign.
  • An in-person signature is recorded by a staff token only. A staff token cannot record E-SIGN consent, and a customer token acknowledges only for an account it owns. Each of these answers forbidden.

A missing or mismatched acknowledgement answers validation_failed naming the field, such as acknowledgement.e_sign. The accepted acknowledgement is written once with the account, and staff and services read it at GET /accounts/{id}/opening-evidence. On the local stack a business product opens without an acknowledgement.

Titling and ownership

owners says who owns the account. ownership.type says how it is titled: individual, joint, pod, trust, estate, utma, iolta, hsa, ira or custodial. With no ownership, one owner is individual and several are joint. Each type has rules of its own: a pod account names beneficiaries whose share_bps total 10,000. The derived tax_reporting says how the interest is reported. POST /accounts/{id}/ownership retitles an account that is not closed. An ira or hsa title cannot be added or removed this way.

States

statusMeaning
openThe account takes credits and debits.
frozenPOST /accounts/{id}/freeze with a reason stops all activity, and the available balance is reported as locked. /unfreeze returns the account to open.
dormantThe dormancy review found no customer activity for 12 months, the default period. A credit through POST /accounts/{id}/credits reactivates the account.
closedFinal. closed_at is set and the account's numbers are closed.

Each change is published as accounts.account.opened, .frozen, .open, .dormant or .closed, and status_reason keeps the reason given.

Closing

POST /accounts/{id}/close closes an empty account. A posted or available balance, or an outstanding overdraft advance, answers accounts.account_not_empty. To close an account that still holds money, POST /accounts/{id}/closure settles the final interest and pays the balance out. It takes a reason and a payout_method: transfer to a payout_account_id, an open account with the same owners and titling, or official_check.

to move to open esc to close