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.
| Type | For a person | For a business |
|---|---|---|
checking | consumer_checking, and consumer_checking_eur, _gbp, _cad, _jpy | business_checking, business_analysis_checking |
savings | consumer_savings, and consumer_savings_eur, _gbp, _cad, _jpy | business_savings |
money_market | consumer_money_market | |
certificate | consumer_cd_12m, brokered_cd_12m | business_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_versionandagreement_sha256must be the ones served for the live version.methodiselectronicorin_person_signature, anddeliveryiselectronicorpaper. Electronic delivery needs the electronic method.- An electronic acknowledgement carries
e_sign: thedisclosure_versionanddisclosure_sha256served,acceptedset totrue, andmethodelectronic. A signature carries noe_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
status | Meaning |
|---|---|
open | The account takes credits and debits. |
frozen | POST /accounts/{id}/freeze with a reason stops all activity, and the available balance is reported as locked. /unfreeze returns the account to open. |
dormant | The dormancy review found no customer activity for 12 months, the default period. A credit through POST /accounts/{id}/credits reactivates the account. |
closed | Final. 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.