Bank Accounts API
A bank account belongs to a link. If the link is a Plaid one, monetr created the bank accounts for you when
you connected your bank, and their names and balances come from there. If it's a manual link, you make them yourself and
you own everything about them, including the balances.
Bank accounts are where the budgeting actually happens. Transactions, spending objects
and funding schedules all hang off a bank account, not off the link.
The bank account object
Balances don't use the sign flip that transaction amounts do. A positive currentBalance means you have money. See
Money for the decimal places problem, which does apply here.
GET List bank accounts
Returns every bank account on your monetr account, across all links.
In the app: The account switcher in the sidebar. Almost every screen needs to know which accounts exist, so this is
one of the first calls the app makes.
Auth: API key, subscription required.
Query parameters
Calling this with no parameters gives you live accounts. Calling it with link_id gives you everything that link has
ever had, archived ones included, because the link details screen needs to show them.
Example
curl --request GET \
--url "https://my.monetr.local/api/bank_accounts" \
--user "$MONETR_API_KEY_ID:$MONETR_API_KEY_SECRET"
[
{
"bankAccountId": "bac_01gds6eqsq7h5mgevwtmw3cyxb",
"linkId": "link_01gds6ecrxq2wq8vmg2mvvv1sh",
"lunchFlowBankAccountId": null,
"currency": "USD",
"availableBalance": 384219,
"currentBalance": 384219,
"limitBalance": 0,
"mask": "4485",
"name": "Checking",
"originalName": "TOTAL CHECKING",
"accountType": "depository",
"accountSubType": "checking",
"status": "active",
"lastUpdated": "2024-08-27T06:00:12.418Z",
"createdAt": "2022-01-14T18:29:03.921Z",
"updatedAt": "2024-08-27T06:00:12.418Z"
},
{
"bankAccountId": "bac_01h9m3kx7vqe4t8n2p5rwd6ycb",
"linkId": "link_01gds6ecrxq2wq8vmg2mvvv1sh",
"lunchFlowBankAccountId": null,
"currency": "USD",
"availableBalance": 1250000,
"currentBalance": 1250000,
"limitBalance": 0,
"mask": null,
"name": "Emergency Fund",
"originalName": "SAVINGS",
"accountType": "depository",
"accountSubType": "savings",
"status": "active",
"lastUpdated": "2024-08-27T06:00:12.418Z",
"createdAt": "2022-01-14T18:29:03.921Z",
"updatedAt": "2024-08-27T06:00:12.418Z"
}
]
GET Get a bank account
Returns one bank account.
In the app: Loading whichever account you currently have selected. The app shows the cached copy from the list
immediately, then confirms it against this.
GET /api/bank_accounts/:bankAccountId
Auth: API key, subscription required.
Path parameters
Example
curl --request GET \
--url "https://my.monetr.local/api/bank_accounts/bac_01gds6eqsq7h5mgevwtmw3cyxb" \
--user "$MONETR_API_KEY_ID:$MONETR_API_KEY_SECRET"
{
"bankAccountId": "bac_01gds6eqsq7h5mgevwtmw3cyxb",
"linkId": "link_01gds6ecrxq2wq8vmg2mvvv1sh",
"lunchFlowBankAccountId": null,
"currency": "USD",
"availableBalance": 384219,
"currentBalance": 384219,
"limitBalance": 0,
"mask": "4485",
"name": "Checking",
"originalName": "TOTAL CHECKING",
"accountType": "depository",
"accountSubType": "checking",
"status": "active",
"lastUpdated": "2024-08-27T06:00:12.418Z",
"createdAt": "2022-01-14T18:29:03.921Z",
"updatedAt": "2024-08-27T06:00:12.418Z"
}
Errors
GET Get balances
Returns the account's balances plus how that money is currently carved up between expenses, goals and what's left over.
This is the endpoint behind the numbers at the top of the app.
In the app: The free-to-use and limit figures at the top of the budgeting sidebar.
GET /api/bank_accounts/:bankAccountId/balances
Auth: API key, subscription required.
Path parameters
Example
curl --request GET \
--url "https://my.monetr.local/api/bank_accounts/bac_01gds6eqsq7h5mgevwtmw3cyxb/balances" \
--user "$MONETR_API_KEY_ID:$MONETR_API_KEY_SECRET"
{
"bankAccountId": "bac_01gds6eqsq7h5mgevwtmw3cyxb",
"currency": "USD",
"current": 384219,
"available": 384219,
"limit": 0,
"free": 121044,
"expenses": 218175,
"goals": 45000
}
Response attributes
This is its own object, not the bank account. The same shape comes back on the transaction create, update and delete
responses.
POST Create a bank account
Adds a bank account by hand. Only works on manual and Lunch Flow links, since Plaid links get their accounts from the
bank.
In the app: Adding an account to a manual link, and both the manual and Lunch Flow setup flows.
Auth: API key, subscription required.
Body
Example
curl --request POST \
--url "https://my.monetr.local/api/bank_accounts" \
--user "$MONETR_API_KEY_ID:$MONETR_API_KEY_SECRET" \
--header "Content-Type: application/json" \
--data '{
"linkId": "link_01j2n8xqvr4kd9wt3m7hbzc5pf",
"name": "Vacation Savings",
"accountType": "depository",
"accountSubType": "savings",
"currentBalance": 250000,
"availableBalance": 250000,
"currency": "USD",
"mask": "0912"
}'
{
"bankAccountId": "bac_01j6b4nqx8ws5rt2m9pked7hvc",
"linkId": "link_01j2n8xqvr4kd9wt3m7hbzc5pf",
"lunchFlowBankAccountId": null,
"currency": "USD",
"availableBalance": 250000,
"currentBalance": 250000,
"limitBalance": 0,
"mask": "0912",
"name": "Vacation Savings",
"originalName": "",
"accountType": "depository",
"accountSubType": "savings",
"status": "active",
"lastUpdated": "2024-08-28T09:14:22.006Z",
"createdAt": "2024-08-28T09:14:22.006Z",
"updatedAt": "2024-08-28T09:14:22.006Z"
}
Errors
PATCH Update a bank account
Changes a bank account. How much you can change depends on what kind of account it is.
In the app: The bank account settings page.
PATCH /api/bank_accounts/:bankAccountId
Auth: API key, subscription required.
Path parameters
Body
On a Plaid account, one field. That's it, because everything else is the bank's to say.
On a manual account, quite a bit more, since nothing is syncing these for you:
On a Lunch Flow account, three: name, currency and mask.
Note status is never editable, on any account type. monetr owns it, and archiving is what changes it.
Every field here is optional, so send only what you're changing. But if you do send one of the non-nullable ones, you
can't send null or an empty string for it. That's on purpose: an empty string would slip past the format checks and
silently wipe the field.
Example
curl --request PATCH \
--url "https://my.monetr.local/api/bank_accounts/bac_01j6b4nqx8ws5rt2m9pked7hvc" \
--user "$MONETR_API_KEY_ID:$MONETR_API_KEY_SECRET" \
--header "Content-Type: application/json" \
--data '{
"name": "Iceland Fund",
"currentBalance": 310000,
"availableBalance": 310000
}'
{
"bankAccountId": "bac_01j6b4nqx8ws5rt2m9pked7hvc",
"linkId": "link_01j2n8xqvr4kd9wt3m7hbzc5pf",
"lunchFlowBankAccountId": null,
"currency": "USD",
"availableBalance": 310000,
"currentBalance": 310000,
"limitBalance": 0,
"mask": "0912",
"name": "Iceland Fund",
"originalName": "",
"accountType": "depository",
"accountSubType": "savings",
"status": "active",
"lastUpdated": "2024-08-28T09:14:22.006Z",
"createdAt": "2024-08-28T09:14:22.006Z",
"updatedAt": "2024-08-29T17:41:55.732Z"
}
Errors
DELETE Archive a bank account
Takes a bank account out of circulation. Despite the verb, this doesn't destroy anything: it sets status to inactive
and stamps deletedAt. Transactions, spending objects and history all stay put.
In the app: Archiving an account from its settings page.
DELETE /api/bank_accounts/:bankAccountId
Auth: API key, subscription required.
Path parameters
Example
curl --request DELETE \
--url "https://my.monetr.local/api/bank_accounts/bac_01j6b4nqx8ws5rt2m9pked7hvc" \
--user "$MONETR_API_KEY_ID:$MONETR_API_KEY_SECRET"
Returns 200 with an empty body. To see the archived record afterwards, list bank accounts with
the link_id filter, which is the only call that includes them.
Errors