List account balances
well_list_account_balancesList every account on the workspace with its stored balance. Rows only — this tool holds no definition of cash, and returns no figure the app renders.
Use it when you are computing a cash figure whose RULES you are stating yourself: which accounts belong to the business, which account types count as cash, which stored field is "the balance", what each currency converts at. The server derives no cash position of its own from this call, so a cash figure starts here: state the rules, keep exactly the rows they admit, then put the result on a card with well_render_cash_position — or, when the answer is cash month by month rather than one total, with well_render_cash_forecast.
It applies no scope. Every active account comes back, including ones you will almost certainly exclude. ownership is workspace, counterparty or unknown, and it decides membership together with company_id:
workspace— the business's own, EXCEPT whenown_company_idis set AND the row names a different company. A row with nocompany_idis trusted, because a connector tags a row before any holder is known; so is a row naming a company whileown_company_idis stillnull, because nothing has disproved the pairing yet. Only a tag contradicting a resolved anchor is stale, and counting that one widens the owned scope and overstates the figure.counterparty— not the business's, unconditionally.unknown— unsettled, and settled ONLY by the anchor: own whencompany_idequalsown_company_id, a counterparty's when it names a different one.
own_company_id is null when the workspace has not set one. Nothing is settled against it then — no unknown row, and no workspace row's company pairing either — so say so rather than counting or dropping on a guess. This is the same three-way rule the app's own canvas account scope applies, and a figure that departs from it disagrees with the number the product shows.
It applies no type filter. account_type is one of deposit, credit, loan, investment, payroll, other. A credit or loan account is a liability, so its balance normally nets out of cash rather than adding to it — but that is your decision to state, not a fact about the row, and the sign stored is the sign the provider sent.
It chooses no amount. closing_booked is SETTLED cash; closing_value includes pending and uncleared movements. The two differ by every initiated-but-unsettled payment, so which one you total is the single most consequential choice a cash figure makes: state it. opening_booked is the fallback for a freshly-opened balance with no settled activity yet. Any of them is null when the stored value was absent or not a finite number, which is not a zero balance.
It converts nothing. Each reading carries its own currency, which can differ from the account's own account_currency. Convert per row at a rate you can state, then total — a sum across currencies is denominated in nothing and no field here would say it happened.
It lists each copy of an account. One physical account can arrive once per connector that syncs it. duplicate_of_account_id names the account a row is a second copy of, and is null on every other row. Leave a marked row out of every total and every count: the balance that counts is the named account's, which is the one the app's own figure reads, and the transactions of both copies are counted once. Total both copies and the figure holds that money twice. When the named account has no readable balance, report it as having none rather than taking the copy's reading in its place, or the figure departs from the app's. Marking follows the ownership rule above: only the business's own accounts are marked, and an unknown row only once own_company_id settles it.
balance is null when no row was selected for that account. Two different situations produce it and they must not be reported the same way: verification_rejected: true means the newest balance failed verification and the bounded walk back found no verified one, so the data is repudiated; false means the account simply has no history yet.
months_back adds month_ends to every row: one reading per complete month end, oldest first, keyed YYYY-MM, ending on the last COMPLETE month. This series is where a cash forecast starts — "what will our cash look like", "project our cash forward", "when do we hit zero" — and it is the settled half of well_render_cash_forecast; the projected half is that series' last settled month minus the burn you measure with well_sum_transactions. A null reading is a month no stored row covered — not a zero balance, so never plot it as one and never interpolate between two real points. Omit months_back for the current reading alone; the series is a second query and is not free.
partial: true means the read was cut short BEFORE RETURNING ANYTHING, so it always arrives with an empty rows — it is a fact about the call, never a coverage figure over rows you received. Nothing is known about what is there, so derive no figure from it: say the read was cut short and offer to try again. unreadable_rows is the separate case and the only one that continues: the read finished, and that many rows carried a stored balance that could not be parsed. They hold a null balance, sit in no figure, and make any total a floor, by up to their count: the count covers every row, whatever its owner or type.
When the token authorizes one workspace, call this directly — no other tool call is needed first. When it authorizes several, this read will not guess which one you mean: pass workspace_id on the call.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| months_back | No | How many complete month ends to carry per account, oldest first. Omit for the current reading alone. | |
| workspace_id | No | Target workspace. Omit when the token authorizes one workspace. Required when it authorizes several: this read reports one workspace's own figures and will not choose which. | |
| conversation_id | No | The conversation id returned by the previous Well result, in its meta under well/conversation_id, in its structuredContent, or in its JSON text block. Pass it back on every call in the same conversation, including a call a card makes, so the chosen workspace and the earlier answers still apply. It decides the conversation on its own: nothing the host states about the session replaces it. Omit it only on the first call of a conversation. |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| rows | Yes | ||
| error | No | ||
| partial | Yes | ||
| success | Yes | ||
| base_currency | Yes | ||
| own_company_id | Yes | ||
| conversation_id | No | The conversation this result belongs to. Pass it back as the conversation_id argument on every later Well call in the same conversation. | |
| unreadable_rows | Yes | ||
| resolved_workspace | No | The workspace that answered, when the caller named none and the token authorizes several. | |
| conversation_id_note | No | Present only when the server opened a fresh lane, stating that no choice recorded earlier was read. | |
| conversation_id_source | No | Where the conversation id came from: the host's own request meta, the caller's argument, or a fresh lane the server opened. |