List the billing contexts a reader can count as recurring
well_list_recurring_contextsList the billing contexts a reader can count as recurring revenue over one window, each with what counting it would add. This is what the recurring-contexts card offers; it measures nothing well_sum_invoices did not already measure, but it does judge each context by the months it billed.
Each entry in groups is one billing context's revenue in the window: context_key (the id a selection is matched on), label (the context as the product writes it), amounts (one entry per currency, each already net of credit notes and never converted) and count (the invoices behind it). The named contexts are sorted biggest first in the currency that carries the most invoices, so the biggest decision reads first. A context whose window nets to nothing in every currency is NOT listed — counting it would add nothing, so it is not a choice. A context that nets NEGATIVE stays on the list: its credit notes outweighed its invoices, which is a real state, and hiding it would move the figure by an amount nobody saw.
The last entry may be context_key: "unclassified", labelled "No billing context". It is the invoices whose billing_context is null: extraction fills the field rather than a billing system, so on most workspaces it holds most of the revenue. It is a choice like the others. A business that bills only subscriptions can count it as recurring; a business with one-off work usually cannot. When it is counted, apply it to the well_sum_invoices rows whose billing_context is null — no row carries the key itself. State its amount whenever it is listed, counted or not, because it is the part of the figure extraction could not describe.
totals is the sum of the groups' amounts per currency: the window's whole readable issued revenue. This read converts nothing and never adds one currency to another. The reader decides per context, so the choice needs no single total; convert once, in the arithmetic, at a rate you state.
measured is the read's own view on which contexts are recurring: each listed context is judged by the months it billed in the window, under the same schedule rule the subscription detector applies on the bank side — monthly, bimonthly, quarterly or yearly. measured.contexts carries every verdict (cadence, missed_rule, months_billed) so the answer can be checked, and measured.policy states the rule in one line for the answer to restate. This is a measurement of the invoices, not a fact about the reader's business — a retainer is recurring for one company and a one-off engagement for another — so the card stays open for a correction, and a pick the reader records replaces the measured set on the next call.
recurring_contexts is the set this call settled on, and reuse_stored_choice: true says the card asks nothing: the answer applies as it stands. choice_source names what settled it — "recorded_pick" when the pick this conversation recorded applies, "measured" when the cadence verdicts did. When reuse_stored_choice is false — a read cut short, or a context whose months the rows did not carry — the card asks as before and recurring_contexts is empty.
invoice_basis is the window's issued revenue under the applied set, ready for the arithmetic: totals and monthly_average per currency (the average divides by every month of the window, dark ones included), per_month the same per month, months_in_window, months_with_revenue, invoice_count, the unclassified_count and unattributed_count the sum reported, and excluded (one_off is the invoices under contexts not counted, credit_notes the ones netted into the figure, unreadable_rows the defective rows). by_client answers the value per client on the same basis — every issued invoice in the window, counted or not under the recurring rule — one line per client per currency, largest first, the rest folded into an is_other line whose client_count says how many. by_client_truncated: true means the client grouping hit its cap, so the folded line may hold more than client_count names.
Apply the answer this result already carries when reuse_stored_choice is true: keep only the well_sum_invoices rows whose billing_context is in recurring_contexts, reading "unclassified" as the rows whose billing_context is null, pass the same keys to well_render_mrr as recurring_contexts, and state measured.policy in one line when choice_source is "measured" — a recorded pick is the reader's own rule, so name the contexts it counted instead. An EMPTY recurring_contexts beside reuse_stored_choice: true is the verdict that nothing in the window recurs under the rule: say no recurring revenue was found, never render a zero, and ask nothing. When reuse_stored_choice is false the card asks: take the reader's answer from it — its Continue records the pick with well_switch_workspace as recurring_contexts, and you read it back with well_wait_for_selection (kind "recurring_contexts").
The window is whole months: from and to are both the first day of a month, YYYY-MM-01, from inclusive and to EXCLUSIVE. window echoes both back exactly as you sent them. When a comparison will be measured, read the list over BOTH windows, from the start of the earlier one to the end of this one, so a context that stopped billing between them is still offered.
partial: true means the aggregate was cut short: every amount here is a FLOOR, a context's real share can only be larger, and a choice made because a share looked small may not survive the full read. Say so before presenting the list as a basis for the decision. A cut-short read never settles the recurring set either: the verdicts stay in measured as evidence, and the card asks. unreadable_rows counts invoices whose net amount or currency could not be read at all; they are in no figure here. It is null when that count could not be read, which is not zero: say it is unmeasured.
Read party_scope: when party_scope.side_unknown is true the workspace has no resolved own company, so no side filter was applied and the list covers invoices on both sides, purchase invoices included. Say the side is unknown and never offer the list as recurring revenue; resolve the own company, then list again.
Read success before groups: a failed read returns no contexts, which looks exactly like a window with nothing to choose.
When the token authorizes one workspace, call this directly — no workspace 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 |
|---|---|---|---|
| to | Yes | EXCLUSIVE end of the window: the first day of the month after the last one you want, YYYY-MM-01. | |
| from | Yes | Inclusive start of the window: the first day of a month, YYYY-MM-01. | |
| 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. | |
| workspace_scope | No | Restrict this call to the family: the token's primary workspace plus the company workspaces under it that you are a member of. Unrelated authorized workspaces drop out of the read; row reads merge across the family, while a per-workspace figure still reports exactly one workspace. |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| error | No | ||
| groups | Yes | ||
| totals | Yes | ||
| window | Yes | ||
| partial | Yes | True when the aggregate behind these figures was cut short. Every amount is then a FLOOR rather than a measurement, and the recurring set is never settled by one. | |
| success | Yes | ||
| measured | Yes | The read's own cadence verdicts. Null on a refused read; always present on a successful one, partial included. | |
| next_step | No | What to do with the card this result renders. Added by the dispatcher when the card asks for a click. | |
| party_scope | Yes | What the receivable side resolved to. `side_unknown: true` means the workspace resolved no own company, so NO side filter was applied (`applied: false`) and the list covers invoices on both sides — say the side is unknown, never that these are the contexts the workspace issued. `null` when the read reported no scope resolution. | |
| choice_source | Yes | What settled `recurring_contexts`: the pick this conversation recorded, or the cadence the read measured. Null when the card still asks. | |
| invoice_basis | Yes | The window's issued revenue under the applied recurring set. Null when no set applies — the card still asks. | |
| 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. | |
| newly_connected | No | Tools that connected to this workspace since the last result and that no session was told about yet, oldest first. Present only when at least one tool is new. The connected-line rule says when to tell an entry; when it does, one line per entry, in the person's language: "<name> is connected.". Never fold several entries into one sentence. Each entry comes back once, on one result only: never repeat its line later. | |
| unreadable_rows | Yes | Invoices in the window whose net amount or currency could not be read. They are in no figure here, including the no-billing-context one. Null when the count could not be read. | |
| recurring_contexts | Yes | The settled set: the keys the figure counts as recurring, applied as they stand when `reuse_stored_choice` is true. Empty when the card still asks — and also when the verdict is that nothing recurs, which `reuse_stored_choice` tells apart. | |
| resolved_workspace | No | The workspace that answered, when the caller named none and the token authorizes several. | |
| reuse_stored_choice | Yes | True when the card asks nothing this call: the recurring set is already settled — by the pick this conversation recorded, or by the cadence the read measured. Apply `recurring_contexts` as they stand and wait for nothing. An empty set beside `true` is the verdict that nothing in the window recurs: say so plainly, never render a zero. | |
| 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. |