Voder
Your Xero, in plain English. Has a customer paid you. Who owes you money. Your cash position. What's outstanding. All in plain language, without opening Xero. Read-only: Voder looks, never touches.
- Integration type
- Plugin
- Verification status
- Not applicable
- Platform
- ChatGPT
- Primary Subcategory
- Self-Serve BI & Conversational Analytics
- Secondary Subcategories
- Accounting & Bookkeeping
- Brand
- Voder
- Access
- Account required
- First tracked
- 2026-06-06
- Tool count
- 21
- Geography
- US
The Primary Subcategory used for this profile’s headline score.
Other Subcategories where the Integration is visible.
ChatGPT Plugin Discoverability Score
ChatGPT organic discovery is not live yet
Voder is tracked in the ChatGPT Plugin registry. Public organic-discovery measurement is not live for ChatGPT yet, so there is no score to publish today.
Get notified when your score goes live
Enter your work email and we’ll notify you when ChatGPT Plugin organic discovery scoring launches.
No spam. Unsubscribe any time.
Competing in ChatGPT Self-Serve BI & Conversational Analytics
View CategoryHow the Discoverability Score works
Organic discovery scoring for Voder on ChatGPT is not live yet. The score will use measured agent conversations when it launches.
Organic discovery scoring is pending. Your Plugin score will appear on this scale when measurement goes live.
FoundDiagnostic
Whether Claude found your Plugin in connector search. It must be Found before it can reach the picker, but the score counts picker appearances—not search results.
PickedMain score
How often your Plugin appeared in the picker, or Claude invoked it directly, across contested conversations. This percentage is the Discoverability Score; the headline number is rounded.
PositionedDiagnostic
What position your Plugin appeared in when it was shown in the picker. This shows prominence, but it does not affect the score.
21 tools agents can invoke
QUESTION-DRIVEN ANSWER POLICY (read before picking a tool to answer any payables question): this tool is the question-shaped surface for payables DRILL-DOWN to a single named supplier — "how much do we owe <named supplier>?", "is the Acme bill overdue?", "give me the aged payables breakdown for <supplier>". For the cross-supplier headline ("What do I owe suppliers?", "How much is outstanding in payables?", "What bills are about to be paid vs awaiting approval?"), prefer `xero_list_invoices` — its `apBreakdown` carrier already pre-aggregates the answer across all suppliers, splitting `approved` (AUTHORISED — about to leave the bank) from `pendingApproval` (SUBMITTED — awaiting your approval). Use THIS tool ONLY when the question names a specific supplier OR when the caller has already identified a ContactID and wants the aged-bucket breakdown for that one supplier. Aged payables report for a specific contact. Shows what we owe them and how overdue. PROBLEM-DETAILS ANSWER POLICY (read FIRST — applies whenever this response carries a `type` field whose value starts with `https://voder.ai/problems/`): the response is an RFC 9457 Problem Details object — a structured action request, not the normal success carrier. The user needs to take an action; your job is to RENDER that action, not narrate it. Render ONLY these fields, in this order: 1. The `title` field as a short heading. 2. The `detail` field as the explanatory sentence, VERBATIM. 3. A SINGLE markdown hyperlink in the exact form `[voderAction.label](voderAction.url)` — substitute the literal `voderAction.label` string as the link text and the literal `voderAction.url` string as the target. This is the button the user clicks. 4. The `voderAction.hint` field as a brief framing sentence below the link, VERBATIM. DO NOT surface ANY of the following fields to the user — they are internal metadata and have no meaning to a non-developer: `status` (an HTTP-shape integer), `type` (an internal URI), `instance` (an internal reference). The user must NEVER see "409" or "424" or any URI starting with `https://voder.ai/problems/` in your answer. DO NOT narrate or paraphrase the action ("Voder needs you to..." / "The system returned a status code..." / "and gives a 424 with action Connect Voder to Xero at the Voder dashboard"). RENDER the markdown hyperlink so the user can click it directly. DO NOT retry this tool, and do NOT call any other Xero tool to work around the problem — they will all return the same Problem Details response until the user follows the `voderAction.url` link and completes the action.
xero_aged_payables_by_contact
QUESTION-DRIVEN ANSWER POLICY (read before picking a tool to answer any receivables question): this tool is the question-shaped surface for receivables DRILL-DOWN to a single named contact — "how much does <named customer> owe me?", "how overdue is Acme's invoice?", "give me the aged receivables breakdown for <customer>". For the cross-customer headline ("Who owes us money?", "How much do customers owe me, and how much is overdue?", "What's outstanding in receivables?"), prefer `xero_list_invoices` — its `arBreakdown` carrier already pre-aggregates the answer across all customers, including a `byContact` rollup that names the biggest owers; you do NOT need to walk per-contact aged-receivables calls to assemble it. Use THIS tool ONLY when the question names a specific contact OR when the caller has already identified a ContactID and wants the aged-bucket breakdown for that one contact. Aged receivables report for a specific contact. Shows what they owe and how overdue. PROBLEM-DETAILS ANSWER POLICY (read FIRST — applies whenever this response carries a `type` field whose value starts with `https://voder.ai/problems/`): the response is an RFC 9457 Problem Details object — a structured action request, not the normal success carrier. The user needs to take an action; your job is to RENDER that action, not narrate it. Render ONLY these fields, in this order: 1. The `title` field as a short heading. 2. The `detail` field as the explanatory sentence, VERBATIM. 3. A SINGLE markdown hyperlink in the exact form `[voderAction.label](voderAction.url)` — substitute the literal `voderAction.label` string as the link text and the literal `voderAction.url` string as the target. This is the button the user clicks. 4. The `voderAction.hint` field as a brief framing sentence below the link, VERBATIM. DO NOT surface ANY of the following fields to the user — they are internal metadata and have no meaning to a non-developer: `status` (an HTTP-shape integer), `type` (an internal URI), `instance` (an internal reference). The user must NEVER see "409" or "424" or any URI starting with `https://voder.ai/problems/` in your answer. DO NOT narrate or paraphrase the action ("Voder needs you to..." / "The system returned a status code..." / "and gives a 424 with action Connect Voder to Xero at the Voder dashboard"). RENDER the markdown hyperlink so the user can click it directly. DO NOT retry this tool, and do NOT call any other Xero tool to work around the problem — they will all return the same Problem Details response until the user follows the `voderAction.url` link and completes the action.
xero_aged_receivables_by_contact
QUESTION-DRIVEN ANSWER POLICY (read before picking a tool to answer any GST or BAS question): this tool is the question-shaped surface for two AU SMB-owner question classes — (1) "what's my current quarter GST liability / how much GST do I owe this quarter?" and (2) "have my prior BAS submissions been lodged / when's my next BAS due / what's the status of my recent BAS forms?". Pick THIS tool first for either question class; do NOT fall back to `xero_trial_balance` (which returns YTD GST only, not per-quarter) or `xero_list_invoices` for these specific GST/BAS questions. Returns a structured carrier — `organisation` (jurisdiction, GST registration, basis, salesTaxPeriod, periodLockDate), `currentPeriod` (period bounds, `basDueDate`, `bas`), `derivedEstimate` (fallback figure), `publishedHistory`, and `historyCaveat`. Each field's shape and per-field rule is documented on the output schema; the answer policies below cover how to use them. RECONNECT-REQUIRED POLICY (read FIRST): if the response is `{ status: 'reconnect_required', message, reconnectUrl }` rather than the normal carrier, Voder's Xero connection is missing the GST/BAS reports permission. Relay the `message` to the user and render `reconnectUrl` as a clickable link to re-grant access (about 10 seconds); do NOT attempt to answer the GST/BAS question until they have reconnected. BAS-LODGEMENT HONESTY (read before answering any "is this BAS lodged?" question): Xero does NOT expose ATO-acknowledged lodgement state — `publishedHistory` is what the user Published inside Xero's UI, NOT what the ATO has acknowledged. NEVER answer "BAS lodged" / "submitted to the ATO" from this carrier alone; surface the verbatim `historyCaveat` field (its full framing is on the output schema) so the user sees the qualification. `periodLockDate` is a secondary, non-guaranteeing signal. CURRENT-PERIOD ANSWER POLICY (read before answering any "current quarter GST" question): you have a number to answer with when EITHER `currentPeriod.bas.available === true` OR `derivedEstimate.currentQuarter.available === true`. When `currentPeriod.bas.available === true`, a finalised BAS for the quarter EXISTS in Xero (finalised on {finalisedAt}) — say so and quote the statutory due date {basDueDate}. Voder does NOT read the BAS dollar amount (the carrier's `gstNet` is null on this branch), so do NOT state a specific "net GST of $X" as if read from the BAS; for an indicative figure use `derivedEstimate.currentQuarter` (quote its disclaimer) and point the user to the Xero Activity Statement screen for the exact lodged amount. When `currentPeriod.bas.available === false` but `derivedEstimate.currentQuarter.available === true`, fall through to the DERIVED-ESTIMATE ANSWER POLICY below and answer with the derived number — do NOT redirect to Xero. ONLY when `currentPeriod.bas.available === false` AND `derivedEstimate.currentQuarter.available === false` (no finalised BAS AND no qualifying transactional data) suggest the Xero Activity Statement screen as a fallback. When `currentPeriod` is null (the org's salesTaxPeriod is not one of the recognised AU values, e.g. a non-AU org), answer that Xero's reported salesTaxPeriod is {organisation.salesTaxPeriod} and the tool cannot compute period boundaries — direct the user to the Xero Activity Statement screen. BAS-DUE-DATE ANSWER POLICY (read before stating any BAS due date to the user): surface the statutory `basDueDate`, framed as "The statutory ATO BAS due date is {basDueDate}." You MUST NOT present it as authoritative for the user's specific situation — if the user lodges through a registered tax or BAS agent the date is typically extended, and final dates come from the user's agent or current ATO guidance, never from Voder. Add: "If you lodge through a registered tax or BAS agent your due date is usually later — confirm the exact date with your agent or the ATO." The carrier-provided date reflects the ATO's documented schedule at the time of publishing; if you have any reason to doubt it (e.g. an unusual reporting cycle the user has mentioned), tell the user to check with their agent or the ATO. DERIVED-ESTIMATE ANSWER POLICY (read before answering any per-quarter or YTD GST question when the authoritative BAS figure is unavailable): the `derivedEstimate` carrier is the fallback answer surface when Xero has no finalised BAS for the in-progress quarter AND/OR no published BAS history. It carries `currentQuarter`, `priorQuarter`, and `ytd` sub-shapes; each names its `source` and carries a verbatim `disclaimer` you MUST quote alongside the figure. Surface the org's basis (from `organisation.salesTaxBasis`) when answering so the user can interpret the figure correctly. `currentQuarter` and `priorQuarter` (when `available: true`) carry `gstCollected`, `gstPaid`, and `netLiability`. `ytd` (when `available: true`) is the year-to-date GST read from Xero's GST liability account ledger balance — it carries `gstNet`, `candidateLines` (the GST accounts that contributed), and its own `disclaimer`; quote that disclaimer VERBATIM because the ledger balance is derived on a different basis than the per-quarter invoice sums. When `currentPeriod.bas.available === false` and `derivedEstimate.currentQuarter.available === true`, answer: "For the quarter ending {periodEnd}, your finalised BAS isn't in Xero yet, but based on the invoices and bills reconciled this quarter, your net GST liability is about ${netLiability.toFixed(2)} (${gstCollected.toFixed(2)} GST collected on customer invoices minus ${gstPaid.toFixed(2)} GST paid on supplier bills). {disclaimer}" — `disclaimer` quoted VERBATIM. Use the per-quarter shape for `priorQuarter`; for `ytd` lead with `gstNet` and quote its `disclaimer`. When the relevant sub-carrier carries `available: false`, say so honestly ("this period had no qualifying transactions reconciled in Xero" / "the trial balance has no GST liability account I can read") and only THEN suggest the Xero Activity Statement screen as a fallback. You MUST NOT redirect to Xero when a derived figure IS available — answer with the derived number and the disclaimer. NON-AU JURISDICTION POLICY: when `organisation.jurisdiction !== 'AU'`, the tool's BAS-specific logic does not apply (BAS is an Australian Tax Office concept). Answer that this tool covers AU GST/BAS only; for UK VAT or US sales tax, no Voder tool is available today. PROBLEM-DETAILS ANSWER POLICY (read FIRST — applies whenever this response carries a `type` field whose value starts with `https://voder.ai/problems/`): the response is an RFC 9457 Problem Details object — a structured action request, not the normal success carrier. The user needs to take an action; your job is to RENDER that action, not narrate it. Render ONLY these fields, in this order: 1. The `title` field as a short heading. 2. The `detail` field as the explanatory sentence, VERBATIM. 3. A SINGLE markdown hyperlink in the exact form `[voderAction.label](voderAction.url)` — substitute the literal `voderAction.label` string as the link text and the literal `voderAction.url` string as the target. This is the button the user clicks. 4. The `voderAction.hint` field as a brief framing sentence below the link, VERBATIM. DO NOT surface ANY of the following fields to the user — they are internal metadata and have no meaning to a non-developer: `status` (an HTTP-shape integer), `type` (an internal URI), `instance` (an internal reference). The user must NEVER see "409" or "424" or any URI starting with `https://voder.ai/problems/` in your answer. DO NOT narrate or paraphrase the action ("Voder needs you to..." / "The system returned a status code..." / "and gives a 424 with action Connect Voder to Xero at the Voder dashboard"). RENDER the markdown hyperlink so the user can click it directly. DO NOT retry this tool, and do NOT call any other Xero tool to work around the problem — they will all return the same Problem Details response until the user follows the `voderAction.url` link and completes the action.
xero_gst_status
List the user's recent feedback entries — including any status updates or follow-up questions the Voder team attached. Read-only. **When to call**: (a) at the start of a new session if the user has previously submitted feedback, to check for updates from the team; (b) after the user expresses satisfaction OR frustration that might relate to a prior entry; (c) when the user asks "what happened to that thing I told you?", "did anything happen with my feedback?", or similar. **Relay mandate**: when a returned entry has `triageState: 'triaged-awaiting-reply'` AND a non-null `pendingQuestion`, you MUST relay that question to the user openly at the start of your response, using the team's words rather than paraphrasing. Frame it openly — e.g. "About your earlier feedback: the Voder team is asking..." Offer a clear "yes / no / not now" option. Do NOT silently filter or hide pending questions. If the user replies, record their reply via `voder_record_feedback` with `inReplyTo` set to the original entry's `entryId`. If the user declines the loop ("don't bring that up again", "I'm done with that thread"), honour it for the remainder of the session — do not call this tool again in this session. **Team-message relay**: an entry may carry a pendingMessage — a team message with a kind of either question or statement. If it is a question, relay it exactly like the pendingQuestion mandate above (open, verbatim, offer yes / no / not now). If it is a statement, the team is telling the user something — a thank-you, or a status update such as a shipped fix — so relay its text openly and verbatim as a statement and do NOT ask the user a question or press for a reply (they may still reply if they wish). Never silently hide a team message. **Status relay**: every returned entry also carries a plain-English `statusText` describing where the feedback stands (for example, "We have read your feedback and saved it."). When the user asks what happened to their feedback, relay the `statusText` in plain language rather than the raw `triageState` token. **Boundary**: this is a status-and-follow-up surface tied to feedback the user themselves submitted; it is NOT a "did you try X yet?" nudge or a session-opening recommendation. Field shape: triageState (optional filter; default returns everything except dismissed entries), since (optional ISO date lower bound, defaults to roughly the last month), limit (optional, default 20, max 50). Returns `{ entries: [...] }` newest first — each entry includes entryId, recordedAt, category, summary, triageState, statusText, pendingQuestion, pendingMessage, and (when applicable) linkedProblemIds + inReplyTo.
voder_list_feedback
QUESTION-DRIVEN ANSWER POLICY (read before picking a tool): this tool is the question-shaped surface for the EXECUTIVE OVERVIEW question class — "where do we stand?", "give me a cash overview", "what's the state of play?", "how are we looking financially?", "give me the headline finance picture". Pick THIS tool first for any cross-cutting "snapshot of the whole business" question; do NOT fall back to multiple atomic calls (`xero_trial_balance` + `xero_list_invoices` + `xero_aged_receivables_by_contact` + `xero_aged_payables_by_contact`) when the user asks any of these question shapes — the executive overview pre-aggregates the same answers in one call. When the user asks for PER-CONTACT drill-down ("how much does Acme owe me?", "is the Acme bill overdue?"), redirect to `xero_aged_receivables_by_contact` / `xero_aged_payables_by_contact` — the executive overview surfaces top-N headlines only. When the user asks a single-question shape (just cash, or just AR, or just AP), prefer the atomic tool (`xero_trial_balance` / `xero_list_invoices`) — this composite is for the cross-cutting headline picture. Returns a composite carrier with: (1) `cashPosition` — sub-carrier per the cash-position answer surface (positive = money in the bank, negative = overdraft, one entry per currency); (2) `receivables` — `{ total, overdueTotal, overdueCount, byContactTopN }` where `byContactTopN` lists up to 5 customers ranked by overdue balance descending (each with `balance`, `overdueBalance`, `overdueCount`, `oldestInvoiceDueDate`, `daysOverdue`); (3) `payables` — same shape, ranked by overdue balance descending across suppliers whose bills are AUTHORISED (about to leave the bank — SUBMITTED awaiting-approval bills are NOT surfaced as top-N headlines); (4) `overdueRedFlags` — severity-tagged headlines (`high` for cash overdraft or overdue payables exceeding cash on hand; `medium` for single-customer overdue concentration > 25% of receivables or hard-stale bank reconciliation); (5) `reconciliationCaveats` — `{ lastReconciledDate, unreconciledTransactionCount, daysSinceLastReconciliation, source, caveat }` flagging how stale the underlying bank reconciliation is so the owner never acts on a confidently-presented but stale cash picture; (6) `asOf` — ISO date the snapshot was computed for. RECONCILIATION-CAVEATS ANSWER POLICY (read before surfacing any cash or aged figure from this carrier): the `reconciliationCaveats.caveat` field is verbatim prose you MUST quote alongside the cash + AR + AP headlines whenever it is non-null. The caveat fires when the bank account has not been reconciled in Xero for 4 or more days (soft caveat) or 15+ days (hard caveat) or when no reconciled bank transactions appear at all (unknown-staleness caveat). When the caveat is null, the figures are fresh enough to take at face value — do not invent a caveat that is not present. `reconciliationCaveats.source` names how `lastReconciledDate` was derived (most recent reconciled bank transaction observed in this organisation, since Xero does not expose a clean "bank reconciliation last run" timestamp); surface this when the user asks how you know. RED-FLAGS ANSWER POLICY (read before composing the answer): when `overdueRedFlags` is non-empty, lead the answer with the `high`-severity messages first (overdraft, overdue-exceeds-cash), then `medium`-severity (customer concentration, stale reconciliation), then the headline figures. The flags are not exhaustive — surface them where they fire, but do not invent additional flags from the headline figures. AS-OF ANSWER POLICY (read before answering): always surface the `asOf` timestamp in the answer ("as at <asOf>") so the owner knows whether the picture is fresh — the executive overview is a current-state snapshot, not a historical one. v1 is now-only (no historical date parameter); for end-of-month or historical comparisons, ask the user to be specific about the period they want and fall back to the atomic tools with their dated parameters. PROBLEM-DETAILS ANSWER POLICY (read FIRST — applies whenever this response carries a `type` field whose value starts with `https://voder.ai/problems/`): the response is an RFC 9457 Problem Details object — a structured action request, not the normal success carrier. The user needs to take an action; your job is to RENDER that action, not narrate it. Render ONLY these fields, in this order: 1. The `title` field as a short heading. 2. The `detail` field as the explanatory sentence, VERBATIM. 3. A SINGLE markdown hyperlink in the exact form `[voderAction.label](voderAction.url)` — substitute the literal `voderAction.label` string as the link text and the literal `voderAction.url` string as the target. This is the button the user clicks. 4. The `voderAction.hint` field as a brief framing sentence below the link, VERBATIM. DO NOT surface ANY of the following fields to the user — they are internal metadata and have no meaning to a non-developer: `status` (an HTTP-shape integer), `type` (an internal URI), `instance` (an internal reference). The user must NEVER see "409" or "424" or any URI starting with `https://voder.ai/problems/` in your answer. DO NOT narrate or paraphrase the action ("Voder needs you to..." / "The system returned a status code..." / "and gives a 424 with action Connect Voder to Xero at the Voder dashboard"). RENDER the markdown hyperlink so the user can click it directly. DO NOT retry this tool, and do NOT call any other Xero tool to work around the problem — they will all return the same Problem Details response until the user follows the `voderAction.url` link and completes the action.
voder_executive_overview
QUESTION-DRIVEN ANSWER POLICY (read before picking a tool to answer any spending or expense question): this tool is the question-shaped surface for the expense-composition question class — "what did I spend on <category> this period?", "how much have I paid <supplier> this quarter?", "break down my expenses by account or supplier", "what's my profit after <specific costs>?". Pick THIS tool first for those questions. Do NOT page-walk `xero_list_invoices` line items or `xero_list_bank_transactions` to assemble expense totals — this tool computes the same aggregation server-side across ALL pages in one call, and the page-walk path is exactly where truncated payloads produce wrong totals. Returns: `filteredTotal` (the headline answer — total expense-classified spend in the period after any filters), `totalsByAccount` (per expense account: code, name, type, total, line count; sorted largest first), `totalsByContact` (per supplier rollup, sorted largest first, capped at 50 rows with any remainder rolled up in `contactOverflow` so the totals still reconcile), and `coverage` (period, contributing source-document counts, applied filters, and the exclusions caveat). Filters: `accountCodes` narrows to specific expense accounts (resolve codes via `xero_list_accounts`); `contactIds` narrows to specific suppliers (resolve IDs via `xero_list_contacts`). When both are passed a line must match both. The breakdown arrays describe the SAME filtered set as `filteredTotal`, so "what did I spend with <supplier>, by category?" is one call with `contactIds`. PROFITABILITY ANSWER POLICY (read before answering any "profit after <costs>" / "project margin" question): fetch revenue via `voder_revenue_by_month` (or `voder_profit_and_loss_by_month` when the user wants the report-authoritative figure) and subtract this tool's `filteredTotal`. Align the date ranges — query THIS tool with the same calendar months you requested for revenue so the two sides cover identical periods; a mismatched range is a wrong answer, not an approximation. Name the cost categories you included (from `totalsByAccount` / `totalsByContact`) when presenting the margin so the user can see what was and wasn't counted. COVERAGE ANSWER POLICY (read before presenting any figure): the response's `coverage.exclusions` field carries a verbatim caveat describing what these figures include and exclude (manual journals, expense claims, supplier credit notes, payroll journals, and unreconciled bank activity are NOT included). You MUST surface that caveat alongside the figures whenever the user's decision depends on completeness or the figures are being compared against the Xero Profit and Loss report — the two can legitimately differ. AUTHORITATIVE-FIGURE REDIRECT: when the user wants the figure "as per my P&L" — report-authoritative by-category totals, gross or net profit, or month-on-month cost comparatives — use `voder_profit_and_loss_by_month` instead: it reads Xero's Profit and Loss report directly, covering the items excluded here. THIS tool remains the right surface for filterable composition — by-supplier breakdowns and specific-account drill-downs, dimensions the P&L report does not carry. This tool also takes ONE date range per call, so for multi-period trend questions prefer `voder_profit_and_loss_by_month`'s monthly comparatives. PROBLEM-DETAILS ANSWER POLICY (read FIRST — applies whenever this response carries a `type` field whose value starts with `https://voder.ai/problems/`): the response is an RFC 9457 Problem Details object — a structured action request, not the normal success carrier. The user needs to take an action; your job is to RENDER that action, not narrate it. Render ONLY these fields, in this order: 1. The `title` field as a short heading. 2. The `detail` field as the explanatory sentence, VERBATIM. 3. A SINGLE markdown hyperlink in the exact form `[voderAction.label](voderAction.url)` — substitute the literal `voderAction.label` string as the link text and the literal `voderAction.url` string as the target. This is the button the user clicks. 4. The `voderAction.hint` field as a brief framing sentence below the link, VERBATIM. DO NOT surface ANY of the following fields to the user — they are internal metadata and have no meaning to a non-developer: `status` (an HTTP-shape integer), `type` (an internal URI), `instance` (an internal reference). The user must NEVER see "409" or "424" or any URI starting with `https://voder.ai/problems/` in your answer. DO NOT narrate or paraphrase the action ("Voder needs you to..." / "The system returned a status code..." / "and gives a 424 with action Connect Voder to Xero at the Voder dashboard"). RENDER the markdown hyperlink so the user can click it directly. DO NOT retry this tool, and do NOT call any other Xero tool to work around the problem — they will all return the same Problem Details response until the user follows the `voderAction.url` link and completes the action.
xero_get_expenses_by_account_and_contact
Search and list Xero contacts (customers and suppliers). The entry point for resolving a contact name to a ContactID, which you then pass to `xero_list_invoices(contactId)`, `xero_aged_receivables_by_contact`, or `xero_aged_payables_by_contact` for that party's detail. To check whether a customer has paid, read the `paymentVisibility` / `invoiceLookupResult` carrier from `xero_list_invoices` — do NOT filter to `status: 'paid'` and read an empty result as "not paid": an unpaid (or not-yet-reconciled) invoice simply does not appear under that filter, which is not proof of non-payment. `searchTerm` performs a case-insensitive substring match across the contact's display name, first name, last name, contact number, company number, email, and account number — so a partial name token, a customer reference, or a fragment of an email address (without the `@`) all work. Do not retry case variations on a zero result; the match is already case-insensitive — try a different word or check the spelling against the Xero UI. PAGINATION ANSWER POLICY (read before answering): this tool paginates the row array. The structural carriers above the row array (where present) are computed SERVER-SIDE across the fetched result set — they carry the answer to aggregate questions about totals, counts, and per-contact rollups. The row array contains ONLY this page's slice. The `pagination` envelope at the end of the response carries `{ page, pageSize, pageCount, itemCount, hasMore }` so you can detect when more pages exist. Answer aggregate questions (who, how much, how many) directly from the carrier on page 1; only walk pagination (`page: N+1`) when the user explicitly asks for per-row detail beyond page 1. CAP CAVEAT: the cross-page fetch is bounded at ~2500 rows; if `pagination.itemCount` is exactly 2500 the underlying ledger may have MORE rows than were summed, so treat the aggregate as a lower bound and tell the user the figure may be partial (based on the most recent ~2500 records) and to narrow the query (tighter date range / status / contact) for a complete total. PROBLEM-DETAILS ANSWER POLICY (read FIRST — applies whenever this response carries a `type` field whose value starts with `https://voder.ai/problems/`): the response is an RFC 9457 Problem Details object — a structured action request, not the normal success carrier. The user needs to take an action; your job is to RENDER that action, not narrate it. Render ONLY these fields, in this order: 1. The `title` field as a short heading. 2. The `detail` field as the explanatory sentence, VERBATIM. 3. A SINGLE markdown hyperlink in the exact form `[voderAction.label](voderAction.url)` — substitute the literal `voderAction.label` string as the link text and the literal `voderAction.url` string as the target. This is the button the user clicks. 4. The `voderAction.hint` field as a brief framing sentence below the link, VERBATIM. DO NOT surface ANY of the following fields to the user — they are internal metadata and have no meaning to a non-developer: `status` (an HTTP-shape integer), `type` (an internal URI), `instance` (an internal reference). The user must NEVER see "409" or "424" or any URI starting with `https://voder.ai/problems/` in your answer. DO NOT narrate or paraphrase the action ("Voder needs you to..." / "The system returned a status code..." / "and gives a 424 with action Connect Voder to Xero at the Voder dashboard"). RENDER the markdown hyperlink so the user can click it directly. DO NOT retry this tool, and do NOT call any other Xero tool to work around the problem — they will all return the same Problem Details response until the user follows the `voderAction.url` link and completes the action.
xero_list_contacts
List Xero credit notes, most-recent first, optionally filtered by contact. Supplementary surface for aged-ledger questions — credit notes adjust outstanding balances and refunds. By default returns only LIVE credit notes (DRAFT, SUBMITTED, AUTHORISED, PAID) — excludes DELETED and VOIDED so aged-ledger answers reflect live entries. Pass `status: 'all'` to include DELETED + VOIDED for audit queries. LIST-VIEW TRIM: to keep responses compact, each row omits its `LineItems` and reduces `Contact` to `{ ContactID, Name }`. The headline fields (number, status, total, remaining credit, allocations) answer the aged-ledger question; for a contact's other details pass the row's `Contact.Name` to `xero_list_contacts`. PAGINATION ANSWER POLICY (read before answering): this tool paginates the row array. The structural carriers above the row array (where present) are computed SERVER-SIDE across the fetched result set — they carry the answer to aggregate questions about totals, counts, and per-contact rollups. The row array contains ONLY this page's slice. The `pagination` envelope at the end of the response carries `{ page, pageSize, pageCount, itemCount, hasMore }` so you can detect when more pages exist. Answer aggregate questions (who, how much, how many) directly from the carrier on page 1; only walk pagination (`page: N+1`) when the user explicitly asks for per-row detail beyond page 1. CAP CAVEAT: the cross-page fetch is bounded at ~2500 rows; if `pagination.itemCount` is exactly 2500 the underlying ledger may have MORE rows than were summed, so treat the aggregate as a lower bound and tell the user the figure may be partial (based on the most recent ~2500 records) and to narrow the query (tighter date range / status / contact) for a complete total. PROBLEM-DETAILS ANSWER POLICY (read FIRST — applies whenever this response carries a `type` field whose value starts with `https://voder.ai/problems/`): the response is an RFC 9457 Problem Details object — a structured action request, not the normal success carrier. The user needs to take an action; your job is to RENDER that action, not narrate it. Render ONLY these fields, in this order: 1. The `title` field as a short heading. 2. The `detail` field as the explanatory sentence, VERBATIM. 3. A SINGLE markdown hyperlink in the exact form `[voderAction.label](voderAction.url)` — substitute the literal `voderAction.label` string as the link text and the literal `voderAction.url` string as the target. This is the button the user clicks. 4. The `voderAction.hint` field as a brief framing sentence below the link, VERBATIM. DO NOT surface ANY of the following fields to the user — they are internal metadata and have no meaning to a non-developer: `status` (an HTTP-shape integer), `type` (an internal URI), `instance` (an internal reference). The user must NEVER see "409" or "424" or any URI starting with `https://voder.ai/problems/` in your answer. DO NOT narrate or paraphrase the action ("Voder needs you to..." / "The system returned a status code..." / "and gives a 424 with action Connect Voder to Xero at the Voder dashboard"). RENDER the markdown hyperlink so the user can click it directly. DO NOT retry this tool, and do NOT call any other Xero tool to work around the problem — they will all return the same Problem Details response until the user follows the `voderAction.url` link and completes the action.
xero_list_credit_notes
QUESTION-DRIVEN ANSWER POLICY (read before picking a tool): this is the question-shaped surface for THREE invoice-related question classes — pick this tool first when the user is asking any of them: (A) "Has invoice <NN> been paid?" / "Did <customer> pay invoice <NN>?" → call with the `invoiceNumber` filter; read the `invoiceLookupResult` carrier as the structural answer. (B) "Who owes us money?" / "How much do customers owe me?" / "What's outstanding in receivables?" / "How much is overdue?" → call WITHOUT `invoiceNumber`; read the `arBreakdown` carrier (it pre-aggregates customer-by-customer with a `byContact` rollup naming the biggest owers and an overdue split). (C) "What do I owe suppliers?" / "How much is outstanding in bills?" / "What's about to leave the bank account?" / "What's awaiting my approval?" → call WITHOUT `invoiceNumber`; read the `apBreakdown` carrier (it splits `approved` / `pendingApproval` / `combined` so the answer distinguishes "about to be paid" from "awaiting your decision"). DO NOT pick this tool when the user names a SPECIFIC customer/supplier and asks for that one party's drill-down — for "how much does Acme owe me?" or "is the Acme bill overdue?", prefer `xero_aged_receivables_by_contact` / `xero_aged_payables_by_contact` (cheaper, single Xero call). Use this tool when the answer needs the headline aggregate or per-row detail. Lists invoices most-recent first, optionally filtered by contact, invoice number, and status. Xero invoice status (AUTHORISED, PAID, etc.) reflects what Xero has RECONCILED — for 'did <contact> pay?' an AUTHORISED (unpaid) invoice does not prove non-payment, because a recent payment may have landed but not yet been reconciled in Xero. By default returns only LIVE invoices (DRAFT, SUBMITTED, AUTHORISED, PAID) — excludes DELETED and VOIDED so payment-status answers are not polluted by historical voided entries. Pass `status: 'all'` to include DELETED + VOIDED for audit queries, or a specific status to narrow further. PAYMENT-STATUS ANSWER POLICY (read before answering any 'has X paid / did X pay / has the invoice been paid?' question): Xero shows ONLY reconciled bank activity, so an invoice that is AUTHORISED or has no payments recorded is NOT evidence of non-payment — a payment may have landed in the bank and simply not been matched yet. There are only TWO valid answers to a payment-status question: (1) PAID — when the invoice status is PAID or a reconciled payment exists; or (2) UNKNOWN — when Xero shows AUTHORISED / unpaid / no payments recorded. You MUST NOT answer 'No', 'not paid', 'still unpaid', 'no payment received', or otherwise state the invoice is unpaid — Xero cannot distinguish 'unpaid' from 'paid-but-not-yet-reconciled'. Do NOT lead with 'No'. Instead lead with the UNKNOWN framing, e.g.: "I can't confirm from Xero — the invoice shows AUTHORISED (Xero only sees reconciled payments), so a payment may have arrived but not been matched yet. Check the bank or chase the customer to be sure." Recent payments (last 1-3 days especially) are the common unreconciled case. Each invoice row carries an explicit `paymentStatus` field (`paid` or `unknown`) — use it as the authoritative answer token. INVOICE-LOOKUP ANSWER POLICY (read before answering any "does invoice <NN> exist / has invoice <NN> been paid?" question): when the caller passes an `invoiceNumber` filter, the response carries a structural `invoiceLookupResult: { invoiceNumber, status: 'not_found' | 'found_paid' | 'found_unpaid' }` carrier. Read the carrier as the load-bearing answer token. When `invoiceLookupResult.status === 'not_found'`, the answer is simply "invoice <NN> doesn't exist in this Xero org" — full stop. You MUST NOT hedge with phrases like "the invoice number may be different in Xero", "may belong to another organisation", "the payment hasn't been reconciled yet", or any other plausible-but-wrong explanation that would erode the customer's trust in the answer. The not-found token means the requested invoice number is genuinely absent from this Xero organisation: an `invoiceNumber` lookup searches ALL statuses (DRAFT, SUBMITTED, AUTHORISED, PAID, VOIDED, DELETED), so a voided or deleted invoice is still FOUND — `not_found` is therefore authoritative. Each question is already scoped to a single organisation per call, so there is no other-organisation hedge to fall back on. When `invoiceLookupResult.status === 'found_paid'` answer "invoice <NN> is PAID"; when `invoiceLookupResult.status === 'found_unpaid'`, FIRST check the matched invoice row's `Status`: if it is VOIDED or DELETED, the invoice EXISTS but was voided/cancelled in Xero — say exactly that (do NOT apply the paid/unpaid or payment-pending framing to a cancelled invoice); otherwise apply the UNKNOWN framing from the payment-status policy above. AR-BREAKDOWN ANSWER POLICY (read before answering any "who owes us money / how much do customers owe me / what's outstanding in receivables / how much is overdue?" question): when ACCREC (customer-invoice) rows appear in the response, the response also carries a structural `arBreakdown: { approved: {count, total, overdueCount, overdueTotal}, byContact: [{contactId, contactName, count, total, overdueCount, overdueTotal}] }` carrier. Read `arBreakdown` as the load-bearing answer token. `approved` covers customer invoices where Xero status is AUTHORISED with AmountDue > 0 — the customer owes us per Xero's ledger. `byContact` rolls up the same segment per customer, sorted by `total` descending so the biggest owers appear first; this is the AUTHORITATIVE answer to "WHO owes us money" — you MUST use `byContact` rather than aggregating from the raw `Invoices` array, because the bulk response may be truncated by the LLM client. The flat `approved` fields answer "how much" and "how much is overdue"; the `byContact` array answers "who". Honest-uncertainty caveat: `arBreakdown` reflects gross outstanding AR per Xero's ledger; open ACCRECCREDIT credit notes (visible via `xero_list_credit_notes`) can adjust net receivables. Mention this caveat when the answer materially depends on it. DRAFT, SUBMITTED, PAID, VOIDED, and DELETED ACCREC rows are excluded from the segment. AP-BREAKDOWN ANSWER POLICY (read before answering any "how much do I owe suppliers / what bills do I owe / what's outstanding to pay?" question): when ACCPAY (bill) rows appear in the response, the response also carries a structural `apBreakdown: { approved: {count, total, overdueCount, overdueTotal}, pendingApproval: {count, total, overdueCount, overdueTotal}, combined: {count, total, overdueCount, overdueTotal} }` carrier. Read `apBreakdown` as the load-bearing answer token. `approved` covers bills where Xero status is AUTHORISED (the bill has been approved for payment and Xero's ledger still shows an outstanding balance); `pendingApproval` covers bills where Xero status is SUBMITTED (someone drafted the bill but you have not approved it yet); `combined` is the union of both segments. You MUST surface BOTH `approved` and `pendingApproval` segments in your answer — do not aggregate to a single "outstanding bills" total unless the user explicitly asks for a single number. The two segments answer different questions for the owner: `approved` is "what payments are about to leave the bank account" and `pendingApproval` is "what is sitting in my queue waiting for me to decide". `total` is the sum of `AmountDue` (the still-owed portion of the bill, not the original face value) and `overdueCount`/`overdueTotal` is the subset where `DueDate` is before today. Honest-uncertainty caveat: "outstanding per Xero" is what Xero's ledger shows; if bank reconciliation is behind, a payment may have already left the bank without yet being matched to the bill — surface this when the answer materially depends on it. DRAFT bills, PAID bills, VOIDED bills, and DELETED bills are excluded from every segment; if the owner is asking about drafts specifically, say so and refer them to the Xero drafts surface. PAYMENT-VISIBILITY ANSWER POLICY (read before answering any "has invoice X been paid?" or similar payment-status question): every invoice row in the response carries a structural `paymentVisibility` field with two values: `'paid'` — Xero records this invoice as fully reconciled (safe to answer "paid"); `'unknown'` — Xero's ledger shows an outstanding balance OR the invoice is in a state where payment cannot be determined. The companion `paymentVisibilityReason` field carries a human-readable explanation you MUST use to frame the answer. Use `paymentVisibility` as the load-bearing answer token, NOT the raw `AmountDue` or `AmountPaid` fields. When `paymentVisibility === 'unknown'`, the customer may have paid through a channel Xero has not yet matched (bank reconciliation lag); answer with UNKNOWN framing — "Xero shows this as outstanding; if the bank reconciliation is behind, the payment may already have left the bank but not yet been matched" — NEVER "No" or "has not been paid". Raw `AmountDue` / `AmountPaid` fields exist for callers that need exact amounts (e.g. payment reminders, balance summaries); they are NOT a payment-status proxy — `AmountDue > 0` is not the same as "has not been paid". Use `paymentVisibility` for the binary answer; cite `paymentVisibilityReason` for the framing. BULK-RESPONSE PAYLOAD-TRIM CONTRACT: when the response carries more than 5 invoices the per-row `paymentVisibilityReason` value is REPLACED with a short stable token — one of `'paid'`, `'ledger-outstanding'`, `'voided-or-deleted'`, `'draft'`, `'unknown-catchall'`. The response then carries a top-level `paymentVisibilityGuide` carrier mapping each token to the full prose. When the trim is active, read `paymentVisibilityGuide[token]` for the framing prose you MUST use; the per-row `paymentVisibility` (paid|unknown) field is unchanged and remains the load-bearing binary answer token. For single-invoice / small responses (≤5 rows) the per-row `paymentVisibilityReason` remains the full prose; `paymentVisibilityGuide` is absent. LIST-VIEW TRIM + LINE-ITEM DRILL-DOWN: to keep list responses compact, the multi-invoice list view omits each invoice's `LineItems` and reduces `Contact` to `{ ContactID, Name }`. When you need an invoice's full line items, call this tool with the `invoiceNumber` filter — the single-invoice response keeps its complete `LineItems` and full `Contact`. For more about a contact from a list row, look it up with `xero_list_contacts` using the row's `Contact.Name` as the `searchTerm` (that tool matches on name, not on ContactID). PAGINATION ANSWER POLICY (read before answering): this tool paginates the row array. The structural carriers above the row array (where present) are computed SERVER-SIDE across the fetched result set — they carry the answer to aggregate questions about totals, counts, and per-contact rollups. The row array contains ONLY this page's slice. The `pagination` envelope at the end of the response carries `{ page, pageSize, pageCount, itemCount, hasMore }` so you can detect when more pages exist. Answer aggregate questions (who, how much, how many) directly from the carrier on page 1; only walk pagination (`page: N+1`) when the user explicitly asks for per-row detail beyond page 1. CAP CAVEAT: the cross-page fetch is bounded at ~2500 rows; if `pagination.itemCount` is exactly 2500 the underlying ledger may have MORE rows than were summed, so treat the aggregate as a lower bound and tell the user the figure may be partial (based on the most recent ~2500 records) and to narrow the query (tighter date range / status / contact) for a complete total. PROBLEM-DETAILS ANSWER POLICY (read FIRST — applies whenever this response carries a `type` field whose value starts with `https://voder.ai/problems/`): the response is an RFC 9457 Problem Details object — a structured action request, not the normal success carrier. The user needs to take an action; your job is to RENDER that action, not narrate it. Render ONLY these fields, in this order: 1. The `title` field as a short heading. 2. The `detail` field as the explanatory sentence, VERBATIM. 3. A SINGLE markdown hyperlink in the exact form `[voderAction.label](voderAction.url)` — substitute the literal `voderAction.label` string as the link text and the literal `voderAction.url` string as the target. This is the button the user clicks. 4. The `voderAction.hint` field as a brief framing sentence below the link, VERBATIM. DO NOT surface ANY of the following fields to the user — they are internal metadata and have no meaning to a non-developer: `status` (an HTTP-shape integer), `type` (an internal URI), `instance` (an internal reference). The user must NEVER see "409" or "424" or any URI starting with `https://voder.ai/problems/` in your answer. DO NOT narrate or paraphrase the action ("Voder needs you to..." / "The system returned a status code..." / "and gives a 424 with action Connect Voder to Xero at the Voder dashboard"). RENDER the markdown hyperlink so the user can click it directly. DO NOT retry this tool, and do NOT call any other Xero tool to work around the problem — they will all return the same Problem Details response until the user follows the `voderAction.url` link and completes the action.
xero_list_invoices
List Xero payment records, optionally filtered by invoice or reference. Most-recent first. Each payment object links to one invoice — use as a **secondary** lookup AFTER `xero_list_invoices` has identified the invoice, e.g. "how was INV-1234 paid?" or "which payments came in this week?". By default returns only AUTHORISED (live) payments — excludes DELETED so payment-status answers are not polluted by reversed payment entries. Pass `status: 'all'` to include DELETED for audit queries. PAYMENT-STATUS ANSWER POLICY (read before answering any 'has X paid / did X pay / has the invoice been paid?' question): Xero shows ONLY reconciled bank activity, so an invoice that is AUTHORISED or has no payments recorded is NOT evidence of non-payment — a payment may have landed in the bank and simply not been matched yet. There are only TWO valid answers to a payment-status question: (1) PAID — when the invoice status is PAID or a reconciled payment exists; or (2) UNKNOWN — when Xero shows AUTHORISED / unpaid / no payments recorded. You MUST NOT answer 'No', 'not paid', 'still unpaid', 'no payment received', or otherwise state the invoice is unpaid — Xero cannot distinguish 'unpaid' from 'paid-but-not-yet-reconciled'. Do NOT lead with 'No'. Instead lead with the UNKNOWN framing, e.g.: "I can't confirm from Xero — the invoice shows AUTHORISED (Xero only sees reconciled payments), so a payment may have arrived but not been matched yet. Check the bank or chase the customer to be sure." Recent payments (last 1-3 days especially) are the common unreconciled case. Each invoice row carries an explicit `paymentStatus` field (`paid` or `unknown`) — use it as the authoritative answer token. PAGINATION ANSWER POLICY (read before answering): this tool paginates the row array. The structural carriers above the row array (where present) are computed SERVER-SIDE across the fetched result set — they carry the answer to aggregate questions about totals, counts, and per-contact rollups. The row array contains ONLY this page's slice. The `pagination` envelope at the end of the response carries `{ page, pageSize, pageCount, itemCount, hasMore }` so you can detect when more pages exist. Answer aggregate questions (who, how much, how many) directly from the carrier on page 1; only walk pagination (`page: N+1`) when the user explicitly asks for per-row detail beyond page 1. CAP CAVEAT: the cross-page fetch is bounded at ~2500 rows; if `pagination.itemCount` is exactly 2500 the underlying ledger may have MORE rows than were summed, so treat the aggregate as a lower bound and tell the user the figure may be partial (based on the most recent ~2500 records) and to narrow the query (tighter date range / status / contact) for a complete total. PROBLEM-DETAILS ANSWER POLICY (read FIRST — applies whenever this response carries a `type` field whose value starts with `https://voder.ai/problems/`): the response is an RFC 9457 Problem Details object — a structured action request, not the normal success carrier. The user needs to take an action; your job is to RENDER that action, not narrate it. Render ONLY these fields, in this order: 1. The `title` field as a short heading. 2. The `detail` field as the explanatory sentence, VERBATIM. 3. A SINGLE markdown hyperlink in the exact form `[voderAction.label](voderAction.url)` — substitute the literal `voderAction.label` string as the link text and the literal `voderAction.url` string as the target. This is the button the user clicks. 4. The `voderAction.hint` field as a brief framing sentence below the link, VERBATIM. DO NOT surface ANY of the following fields to the user — they are internal metadata and have no meaning to a non-developer: `status` (an HTTP-shape integer), `type` (an internal URI), `instance` (an internal reference). The user must NEVER see "409" or "424" or any URI starting with `https://voder.ai/problems/` in your answer. DO NOT narrate or paraphrase the action ("Voder needs you to..." / "The system returned a status code..." / "and gives a 424 with action Connect Voder to Xero at the Voder dashboard"). RENDER the markdown hyperlink so the user can click it directly. DO NOT retry this tool, and do NOT call any other Xero tool to work around the problem — they will all return the same Problem Details response until the user follows the `voderAction.url` link and completes the action.
xero_list_payments
Returns the chart of accounts — the full chart in a single response. Each account row carries its classification in the `Type` field (REVENUE, OTHERINCOME, EXPENSE, DIRECTCOSTS, OVERHEADS, CURRENT, FIXED, EQUITY, etc.) — use `Type` to resolve which accounts are revenue-classified, expense-classified, or balance-sheet-classified rather than guessing from the account name. Account names alone are unreliable signals — the same account name can be classified differently across organisations. Always cross-check the `Type` before treating a row in a Xero report as revenue, expense, or anything else. (The `accountType` INPUT filter below takes the same set of values.) Filter to a single `accountType` to narrow a large chart of accounts. Default `status: 'active'` excludes ARCHIVED accounts; pass `status: 'all'` to include them. PROBLEM-DETAILS ANSWER POLICY (read FIRST — applies whenever this response carries a `type` field whose value starts with `https://voder.ai/problems/`): the response is an RFC 9457 Problem Details object — a structured action request, not the normal success carrier. The user needs to take an action; your job is to RENDER that action, not narrate it. Render ONLY these fields, in this order: 1. The `title` field as a short heading. 2. The `detail` field as the explanatory sentence, VERBATIM. 3. A SINGLE markdown hyperlink in the exact form `[voderAction.label](voderAction.url)` — substitute the literal `voderAction.label` string as the link text and the literal `voderAction.url` string as the target. This is the button the user clicks. 4. The `voderAction.hint` field as a brief framing sentence below the link, VERBATIM. DO NOT surface ANY of the following fields to the user — they are internal metadata and have no meaning to a non-developer: `status` (an HTTP-shape integer), `type` (an internal URI), `instance` (an internal reference). The user must NEVER see "409" or "424" or any URI starting with `https://voder.ai/problems/` in your answer. DO NOT narrate or paraphrase the action ("Voder needs you to..." / "The system returned a status code..." / "and gives a 424 with action Connect Voder to Xero at the Voder dashboard"). RENDER the markdown hyperlink so the user can click it directly. DO NOT retry this tool, and do NOT call any other Xero tool to work around the problem — they will all return the same Problem Details response until the user follows the `voderAction.url` link and completes the action.
xero_list_accounts
List Xero BankTransactions — Xero's RECONCILED view of bank-account activity. **Returns ONLY reconciled (matched + categorised) entries** — a recent payment that has landed in the bank but not yet been reconciled (typically the last 1-3 days) is **NOT visible** via this tool, because Xero sees only the reconciled subset of bank-account transactions. Use this tool for: confirming a known payment has been reconciled in Xero, listing categorised bank activity across accounts, or cross-referencing Xero's matched view. Most-recent first. The `isReconciled` filter operates on Xero's category-match axis (`isReconciled: false` mostly returns DELETED historical entries — NOT recent payments). Default returns AUTHORISED (live) lines; `status: 'all'` includes DELETED for audit. PAYMENT-STATUS ANSWER POLICY (read before answering any 'has X paid / did X pay / has the invoice been paid?' question): Xero shows ONLY reconciled bank activity, so an invoice that is AUTHORISED or has no payments recorded is NOT evidence of non-payment — a payment may have landed in the bank and simply not been matched yet. There are only TWO valid answers to a payment-status question: (1) PAID — when the invoice status is PAID or a reconciled payment exists; or (2) UNKNOWN — when Xero shows AUTHORISED / unpaid / no payments recorded. You MUST NOT answer 'No', 'not paid', 'still unpaid', 'no payment received', or otherwise state the invoice is unpaid — Xero cannot distinguish 'unpaid' from 'paid-but-not-yet-reconciled'. Do NOT lead with 'No'. Instead lead with the UNKNOWN framing, e.g.: "I can't confirm from Xero — the invoice shows AUTHORISED (Xero only sees reconciled payments), so a payment may have arrived but not been matched yet. Check the bank or chase the customer to be sure." Recent payments (last 1-3 days especially) are the common unreconciled case. Each invoice row carries an explicit `paymentStatus` field (`paid` or `unknown`) — use it as the authoritative answer token. PAGINATION ANSWER POLICY (read before answering): this tool paginates the row array. The structural carriers above the row array (where present) are computed SERVER-SIDE across the fetched result set — they carry the answer to aggregate questions about totals, counts, and per-contact rollups. The row array contains ONLY this page's slice. The `pagination` envelope at the end of the response carries `{ page, pageSize, pageCount, itemCount, hasMore }` so you can detect when more pages exist. Answer aggregate questions (who, how much, how many) directly from the carrier on page 1; only walk pagination (`page: N+1`) when the user explicitly asks for per-row detail beyond page 1. CAP CAVEAT: the cross-page fetch is bounded at ~2500 rows; if `pagination.itemCount` is exactly 2500 the underlying ledger may have MORE rows than were summed, so treat the aggregate as a lower bound and tell the user the figure may be partial (based on the most recent ~2500 records) and to narrow the query (tighter date range / status / contact) for a complete total. PROBLEM-DETAILS ANSWER POLICY (read FIRST — applies whenever this response carries a `type` field whose value starts with `https://voder.ai/problems/`): the response is an RFC 9457 Problem Details object — a structured action request, not the normal success carrier. The user needs to take an action; your job is to RENDER that action, not narrate it. Render ONLY these fields, in this order: 1. The `title` field as a short heading. 2. The `detail` field as the explanatory sentence, VERBATIM. 3. A SINGLE markdown hyperlink in the exact form `[voderAction.label](voderAction.url)` — substitute the literal `voderAction.label` string as the link text and the literal `voderAction.url` string as the target. This is the button the user clicks. 4. The `voderAction.hint` field as a brief framing sentence below the link, VERBATIM. DO NOT surface ANY of the following fields to the user — they are internal metadata and have no meaning to a non-developer: `status` (an HTTP-shape integer), `type` (an internal URI), `instance` (an internal reference). The user must NEVER see "409" or "424" or any URI starting with `https://voder.ai/problems/` in your answer. DO NOT narrate or paraphrase the action ("Voder needs you to..." / "The system returned a status code..." / "and gives a 424 with action Connect Voder to Xero at the Voder dashboard"). RENDER the markdown hyperlink so the user can click it directly. DO NOT retry this tool, and do NOT call any other Xero tool to work around the problem — they will all return the same Problem Details response until the user follows the `voderAction.url` link and completes the action.
xero_list_bank_transactions
List the organisations you can ask about, each with a human-readable name and an id. Use this when you need to know which organisations are available, or when a question could apply to more than one of them: show the names, let the user pick, then pass the chosen organisation's `id` as the `organisationId` argument to the data tools. If only one organisation is available, the data tools already use it by default and you do not need to call this first. Returns `{ organisations: [{ id, name }] }` — `name` is what to show the user; `id` is the value to pass as `organisationId`. Only the organisations you have access to are listed. EMPTY-RESPONSE ANSWER POLICY (read before responding when the response is `{ organisations: [] }`): an empty list means the user has not yet completed the Connect Voder to Xero step. Tell the user: "You are not connected to a Xero organisation yet. Open https://app.voder.ai and click Connect Voder to Xero to authorise Voder to read your Xero books, then ask again." Pass the URL through as a clickable link. Do NOT call any Xero data tool when the organisations list is empty — they will all return the same connect-required Problem Details response.
voder_list_organisations
QUESTION-DRIVEN ANSWER POLICY (read before picking a tool to answer any revenue question): this is the question-shaped surface for revenue-by-month questions — "what was revenue in February?", "show me monthly revenue", "how is revenue tracking month-on-month?", "what's the revenue trend over the last N months?". Pick THIS tool first for those. It returns each month's revenue from Xero's profit-and-loss report plus a per-account breakdown so you can see which revenue-classified accounts contribute. HOW TO ASK: give the month as `month` in YYYY-MM form (e.g. "2026-02") and earlier months as `comparativePeriods` (0 to 23). ANY month is valid — there are no date rules to get right. Returns `periods` (one entry per month, most recent first: `{period, revenue, accounts}`) and `coverage`. Always present the per-account breakdown alongside the aggregate so a classification surprise is visible — an account named in a revenue-suggesting way but classified non-revenue, or one account contributing far more than expected. RECENT-MONTHS HONESTY POLICY: recent months — especially the current month — can still move as invoices and bank activity land; say so when the user reads recent figures as final. FULL-STATEMENT REDIRECT: for the whole P&L (costs, gross/net profit, not just revenue) use `voder_profit_and_loss_by_month`. PROBLEM-DETAILS ANSWER POLICY (read FIRST — applies whenever this response carries a `type` field whose value starts with `https://voder.ai/problems/`): the response is an RFC 9457 Problem Details object — a structured action request, not the normal success carrier. The user needs to take an action; your job is to RENDER that action, not narrate it. Render ONLY these fields, in this order: 1. The `title` field as a short heading. 2. The `detail` field as the explanatory sentence, VERBATIM. 3. A SINGLE markdown hyperlink in the exact form `[voderAction.label](voderAction.url)` — substitute the literal `voderAction.label` string as the link text and the literal `voderAction.url` string as the target. This is the button the user clicks. 4. The `voderAction.hint` field as a brief framing sentence below the link, VERBATIM. DO NOT surface ANY of the following fields to the user — they are internal metadata and have no meaning to a non-developer: `status` (an HTTP-shape integer), `type` (an internal URI), `instance` (an internal reference). The user must NEVER see "409" or "424" or any URI starting with `https://voder.ai/problems/` in your answer. DO NOT narrate or paraphrase the action ("Voder needs you to..." / "The system returned a status code..." / "and gives a 424 with action Connect Voder to Xero at the Voder dashboard"). RENDER the markdown hyperlink so the user can click it directly. DO NOT retry this tool, and do NOT call any other Xero tool to work around the problem — they will all return the same Problem Details response until the user follows the `voderAction.url` link and completes the action.
voder_revenue_by_month
QUESTION-DRIVEN ANSWER POLICY (read before picking a tool to answer any quarterly profit-and-loss question): this is the question-shaped surface for the quarterly P&L question class — "how did Q1 go?", "profit and loss for last quarter", "show me the September quarter", "how is profit tracking quarter-on-quarter?". Pick THIS tool first for quarterly P&L questions. Figures are read straight from Xero's Profit and Loss report (summed across the quarter's three calendar months), so this is the report-authoritative source: when the user wants the number "as per my P&L", answer from here. HOW TO ASK: give the quarter as `calendarQuarter` in YYYY-Qn form. These are CALENDAR quarters: Q1 = January-March, Q2 = April-June, Q3 = July-September, Q4 = October-December. Add `comparativePeriods` for prior quarters (0 for that quarter alone, up to 11). IMPORTANT — financial vs calendar quarters: if the user asks about a FINANCIAL quarter, their financial year may not start in January (for example a 30-September year-end makes financial Q1 = October-December), so translate the financial quarter to the matching CALENDAR quarter first — use the organisation's financial-year start (available from `xero_organisation_details` if you are unsure) — and pass that calendar quarter. Returns: `periods` (the quarter labels, most recent first), `summaries` (the headline lines — Gross Profit, Net Profit — read these FIRST), `sections` (Income, Cost of Sales, Operating Expenses, and so on — each with its per-account rows and the section's per-quarter totals), and `coverage` (the requested quarter and how many were returned). Every `amounts` / `totals` array aligns position-for-position with `periods`. LEAD-WITH-HEADLINES ANSWER POLICY (read before presenting any answer): lead with Net Profit, Gross Profit, and the section totals — the headline figures, not 80 line items. Reach into the per-account rows only when the user drills in. RECENT-PERIOD HONESTY POLICY: the most recent quarter — especially one still in progress — can still move as invoices, bills, and bank activity land. Say so when the user reads the latest quarter as final. OTHER-GRANULARITY REDIRECT: for a single month use `voder_profit_and_loss_by_month`; for a full financial year use `voder_profit_and_loss_by_year`. PROBLEM-DETAILS ANSWER POLICY (read FIRST — applies whenever this response carries a `type` field whose value starts with `https://voder.ai/problems/`): the response is an RFC 9457 Problem Details object — a structured action request, not the normal success carrier. The user needs to take an action; your job is to RENDER that action, not narrate it. Render ONLY these fields, in this order: 1. The `title` field as a short heading. 2. The `detail` field as the explanatory sentence, VERBATIM. 3. A SINGLE markdown hyperlink in the exact form `[voderAction.label](voderAction.url)` — substitute the literal `voderAction.label` string as the link text and the literal `voderAction.url` string as the target. This is the button the user clicks. 4. The `voderAction.hint` field as a brief framing sentence below the link, VERBATIM. DO NOT surface ANY of the following fields to the user — they are internal metadata and have no meaning to a non-developer: `status` (an HTTP-shape integer), `type` (an internal URI), `instance` (an internal reference). The user must NEVER see "409" or "424" or any URI starting with `https://voder.ai/problems/` in your answer. DO NOT narrate or paraphrase the action ("Voder needs you to..." / "The system returned a status code..." / "and gives a 424 with action Connect Voder to Xero at the Voder dashboard"). RENDER the markdown hyperlink so the user can click it directly. DO NOT retry this tool, and do NOT call any other Xero tool to work around the problem — they will all return the same Problem Details response until the user follows the `voderAction.url` link and completes the action.
voder_profit_and_loss_by_quarter
QUESTION-DRIVEN ANSWER POLICY (read before picking a tool to answer any annual profit-and-loss question): this is the question-shaped surface for the financial-year P&L question class — "show me this year's P&L", "how did FY2026 compare to FY2025?", "annual profit and loss", "how is profit tracking year-on-year?". Pick THIS tool first for annual P&L questions. Figures are read straight from Xero's Profit and Loss report, aligned to the organisation's financial year, so this is the report-authoritative source. HOW TO ASK: give `year` as the 4-digit year the financial year ENDS in (e.g. "2026" = the financial year ending in 2026 — for a 30-June year-end that is July 2025 to June 2026; the tool reads the organisation's actual year-end, so you do not need to know it). Add `comparativePeriods` for prior financial years (0 for that year alone, up to 10). Returns: `periods` (the year labels, most recent first), `summaries` (the headline lines — Gross Profit, Net Profit — read these FIRST), `sections` (Income, Cost of Sales, Operating Expenses, and so on — each with its per-account rows and per-year totals), and `coverage`. Every `amounts` / `totals` array aligns position-for-position with `periods`. LEAD-WITH-HEADLINES ANSWER POLICY (read before presenting any answer): lead with Net Profit, Gross Profit, and the section totals — the headline figures, not 80 line items. RECENT-PERIOD HONESTY POLICY: the current financial year, if it is still in progress, is partial and can still move as activity lands — say so when the user reads it as a full-year figure. OTHER-GRANULARITY REDIRECT: for a single month use `voder_profit_and_loss_by_month`; for a quarter use `voder_profit_and_loss_by_quarter`. PROBLEM-DETAILS ANSWER POLICY (read FIRST — applies whenever this response carries a `type` field whose value starts with `https://voder.ai/problems/`): the response is an RFC 9457 Problem Details object — a structured action request, not the normal success carrier. The user needs to take an action; your job is to RENDER that action, not narrate it. Render ONLY these fields, in this order: 1. The `title` field as a short heading. 2. The `detail` field as the explanatory sentence, VERBATIM. 3. A SINGLE markdown hyperlink in the exact form `[voderAction.label](voderAction.url)` — substitute the literal `voderAction.label` string as the link text and the literal `voderAction.url` string as the target. This is the button the user clicks. 4. The `voderAction.hint` field as a brief framing sentence below the link, VERBATIM. DO NOT surface ANY of the following fields to the user — they are internal metadata and have no meaning to a non-developer: `status` (an HTTP-shape integer), `type` (an internal URI), `instance` (an internal reference). The user must NEVER see "409" or "424" or any URI starting with `https://voder.ai/problems/` in your answer. DO NOT narrate or paraphrase the action ("Voder needs you to..." / "The system returned a status code..." / "and gives a 424 with action Connect Voder to Xero at the Voder dashboard"). RENDER the markdown hyperlink so the user can click it directly. DO NOT retry this tool, and do NOT call any other Xero tool to work around the problem — they will all return the same Problem Details response until the user follows the `voderAction.url` link and completes the action.
voder_profit_and_loss_by_year
QUESTION-DRIVEN ANSWER POLICY (read before picking a tool to answer any profit-and-loss or financial-statement question): this is the question-shaped surface for the P&L question class — "show me my P&L", "how did February go?", "profit and loss for last quarter", "what were my monthly costs?", "how is net profit tracking month-on-month?", "what's my gross margin?". Pick THIS tool first for those questions. The figures are read straight from Xero's Profit and Loss report — section totals and the Gross Profit / Net Profit lines come from the report itself, never recomputed — so this is the report-authoritative source: when the user wants the number "as per my P&L", answer from here. HOW TO ASK: give the month you want as `month` in YYYY-MM form (e.g. "2026-02" for February 2026) and how many earlier months to show alongside it as `comparativePeriods` (0 for that month alone, up to 23 for two years of history). ANY month is valid — February, April, June, September and November included. There are no date rules to get right; just name the month. Returns: `periods` (the month labels, most recent first), `summaries` (the headline lines — Gross Profit, Operating Profit, Net Profit — read these FIRST), `sections` (Income, Cost of Sales, Operating Expenses, and so on — each with its per-account rows and the section's per-month totals), and `coverage` (the requested month and how many were returned). Every `amounts` / `totals` array aligns position-for-position with `periods`: amounts[0] belongs to periods[0], and so on. LEAD-WITH-HEADLINES ANSWER POLICY (read before presenting any P&L answer): lead with Net Profit, Gross Profit, and the section totals — the headline figures, not 80 line items. Reach into the per-account rows only when the user drills in ("ok, what drove that?"). QUARTER / YEAR ANSWER POLICY (read before answering any quarterly or yearly question): this returns monthly columns. For a quarter or a year, request the relevant months (a quarter = its last month with `comparativePeriods: 2`; a year = its last month with `comparativePeriods: 11`), sum the monthly figures, and SAY which months you included. WHOLE-MONTHS-ONLY ANSWER POLICY (read before answering any question whose range does not fall on month boundaries): figures are whole calendar months only. For a partial-month range (e.g. "1 April to 9 June"), say plainly that this works in whole months, offer the nearest whole-month comparison instead, and NEVER scale, pro-rata, or approximate a partial month — an approximated figure presented as the P&L is a wrong answer. RECENT-MONTHS HONESTY POLICY: the report reflects what has been entered and reconciled in Xero so far. Recent months — especially the current month — can still move as invoices, bills, and bank activity land. Say so when the user is reading recent-month figures as final. BY-SUPPLIER REDIRECT: P&L rows are ledger accounts (by-category); the report has no supplier dimension. For "how much did I spend with <supplier>?" or filtered expense composition, use `xero_get_expenses_by_account_and_contact`. PROBLEM-DETAILS ANSWER POLICY (read FIRST — applies whenever this response carries a `type` field whose value starts with `https://voder.ai/problems/`): the response is an RFC 9457 Problem Details object — a structured action request, not the normal success carrier. The user needs to take an action; your job is to RENDER that action, not narrate it. Render ONLY these fields, in this order: 1. The `title` field as a short heading. 2. The `detail` field as the explanatory sentence, VERBATIM. 3. A SINGLE markdown hyperlink in the exact form `[voderAction.label](voderAction.url)` — substitute the literal `voderAction.label` string as the link text and the literal `voderAction.url` string as the target. This is the button the user clicks. 4. The `voderAction.hint` field as a brief framing sentence below the link, VERBATIM. DO NOT surface ANY of the following fields to the user — they are internal metadata and have no meaning to a non-developer: `status` (an HTTP-shape integer), `type` (an internal URI), `instance` (an internal reference). The user must NEVER see "409" or "424" or any URI starting with `https://voder.ai/problems/` in your answer. DO NOT narrate or paraphrase the action ("Voder needs you to..." / "The system returned a status code..." / "and gives a 424 with action Connect Voder to Xero at the Voder dashboard"). RENDER the markdown hyperlink so the user can click it directly. DO NOT retry this tool, and do NOT call any other Xero tool to work around the problem — they will all return the same Problem Details response until the user follows the `voderAction.url` link and completes the action.
voder_profit_and_loss_by_month
Read the full detail of one feedback entry the user submitted. Read-only. **When to call**: after `voder_list_feedback` identifies an entry the user wants to discuss in detail — for example, "tell me more about that one" or "what was the question they asked?". Returns the same fields as the list response plus the original `toolContext` captured at submission time and any `triageNote` the team wrote when classifying the entry. Field shape: entryId (the id from voder_list_feedback). **Boundary**: this only reads entries under the caller's organisation; an unknown id returns `{ entry: null }` — surface that as "I can't find that feedback under your organisation" rather than as a server error.
voder_get_feedback_detail
Record an observation of user-facing friction, error, annoyance — OR a positive observation — for the Voder team's research loop. The co-discovery experiment depends on both kinds of signal. Invoke when ONE of these specific in-session signals occurred: (a) a Xero or bank-data tool returned an unexpected error, or an empty/partial result that is genuinely surprising given what the user expected — but a normal, answerable empty state is NOT friction: an organisation with no bank accounts connected, an empty ledger, or zero transactions in the period is an expected result you should answer plainly ("no bank accounts are connected yet — connect one in Xero and ask again") without recording feedback; (b) the user expressed confusion, repeated themselves, or asked for something the toolset cannot do; (c) you noticed a mismatch between what was asked and what the available tools can answer; (d) the user expressed a suggestion or wish for a capability that doesn't exist yet; (e) something worked well that the team should know about — a clear answer landed first call, the user expressed satisfaction ("that's exactly what I needed", "great, thanks"), a tool surface answered cleanly without back-and-forth, OR the user confirmed a previously reported issue is now fixed. **Openness mandate**: when you invoke this tool, you MUST tell the user openly in the same chat reply — e.g. "I'm noting this for the Voder team so they can improve the tool." This applies symmetrically to positive recordings — e.g. "I'm letting the Voder team know this worked well." Do NOT invoke this tool silently or describe its result without telling the user. If the user objects ("don't log that", "stop", "I don't want feedback recorded"), STOP invoking the tool for the remainder of the session and acknowledge the objection openly. **Boundary**: do NOT invoke at session-initiation or when nothing notable happened — this is a signal-response surface, not a session-opening or session-closing nudge. **Replies to follow-up questions**: if the Voder team previously asked the user a follow-up question (relayed to the user from a voder_list_feedback response) and the user is now answering it, pass the prior entry id in `inReplyTo` so the reply threads into the original entry's audit trail rather than arriving as an orphan. Confirmations that a fix worked ("yes, the cash answer is right now") are positive replies — use category 'positive' with inReplyTo set to the original entry id. **Avoid duplicates**: before recording a NEW observation (one that is not a reply), check whether a recent voder_list_feedback entry you already saw this session covers the same theme. If one does, thread the new detail onto it by setting inReplyTo to that entry's entryId (the id voder_list_feedback returned) instead of recording a second standalone entry about the same issue. Only voder_list_feedback returns entry ids, so thread this way only for an entry you have already seen listed this session; if no matching entry is in view, record a fresh one. **Data hygiene**: `summary` and `toolContext` MUST NOT contain real Xero IDs, real bank-line UUIDs, customer revenue figures, organisation identifiers, or any payload data. Describe the OBSERVATION (e.g. "user asked for monthly recurring revenue but no tool surfaces it") not the PAYLOAD ("INV-1234 returned $5,874.00 from contact ABC-789"). **Length cap**: `summary` and `toolContext` each accept up to 2000 characters. If a single observation exceeds this, summarise the most important issue first and split additional issues into separate invocations (each call records one observation). Do NOT silently truncate substantive detail to fit one call. Field shape: category (one of error/annoyance/friction/suggestion/positive), summary (one-line observation, 1-2000 chars), toolContext (optional context string describing what the user was trying to do, 0-2000 chars), inReplyTo (optional entry id of a prior feedback entry this reply threads into).
voder_record_feedback
QUESTION-DRIVEN ANSWER POLICY (read before picking a tool to answer cash questions): this tool is the question-shaped surface for cash-position questions — "How much cash do I have?", "What's our cash position?", "How much is in the bank?", "Are we cash-positive right now?". The structural `cashPosition` carrier (described below) pre-computes the answer; you should pick THIS tool first for any cash-position question and read the carrier rather than walking the chart of accounts yourself. Trial balance report as at a specific date. **For 'how much cash do we have right now' questions, use the structural `cashPosition` carrier — DO NOT infer the sign from Xero's `Debit`/`Credit` column labels.** The carrier shape is `cashPosition: { accounts: [{accountId, name, signedAmount, currency}], totals: [{currency, signedAmount}] }`. `signedAmount` uses the customer's perspective: **positive = money the customer HAS in the bank, negative = overdraft / amount owed to the bank**. Read `cashPosition.totals` directly to answer the cash-position question (one entry per currency for multi-currency organisations). The raw trial-balance report continues to be returned alongside for general-purpose questions, but the credit/debit column orientation in that raw report is NOT a reliable signal for cash position — `cashPosition.totals` is the authoritative answer token. EMPTY-OR-ZERO CARRIER POLICY (read before answering any cash-position question): when `cashPosition.totals` is an empty array (no bank accounts found on the chart of accounts), the answer MUST say "no bank accounts are connected on the chart of accounts — open the Xero dashboard or ask your finance team to confirm the bank feed is connected" — DO NOT fabricate a dollar figure. When `cashPosition.totals` carries one or more entries but every entry's `signedAmount === 0` AND every account in `cashPosition.accounts` has `signedAmount === 0`, the answer MUST say "all bank accounts on the chart of accounts have a zero balance as at this date — open the Xero dashboard to confirm the trial-balance report ran for the right date" — again, DO NOT fabricate a dollar figure. You MUST NOT invent, estimate, or approximate any cash amount when the carrier is empty or all-zero; the only valid responses are the two phrasings above. A non-zero `signedAmount` on any account is the only signal that licenses a numeric cash answer. PROBLEM-DETAILS ANSWER POLICY (read FIRST — applies whenever this response carries a `type` field whose value starts with `https://voder.ai/problems/`): the response is an RFC 9457 Problem Details object — a structured action request, not the normal success carrier. The user needs to take an action; your job is to RENDER that action, not narrate it. Render ONLY these fields, in this order: 1. The `title` field as a short heading. 2. The `detail` field as the explanatory sentence, VERBATIM. 3. A SINGLE markdown hyperlink in the exact form `[voderAction.label](voderAction.url)` — substitute the literal `voderAction.label` string as the link text and the literal `voderAction.url` string as the target. This is the button the user clicks. 4. The `voderAction.hint` field as a brief framing sentence below the link, VERBATIM. DO NOT surface ANY of the following fields to the user — they are internal metadata and have no meaning to a non-developer: `status` (an HTTP-shape integer), `type` (an internal URI), `instance` (an internal reference). The user must NEVER see "409" or "424" or any URI starting with `https://voder.ai/problems/` in your answer. DO NOT narrate or paraphrase the action ("Voder needs you to..." / "The system returned a status code..." / "and gives a 424 with action Connect Voder to Xero at the Voder dashboard"). RENDER the markdown hyperlink so the user can click it directly. DO NOT retry this tool, and do NOT call any other Xero tool to work around the problem — they will all return the same Problem Details response until the user follows the `voderAction.url` link and completes the action.
xero_trial_balance
The connected Xero organisation: legal name, country, base currency, financial-year-end. PROBLEM-DETAILS ANSWER POLICY (read FIRST — applies whenever this response carries a `type` field whose value starts with `https://voder.ai/problems/`): the response is an RFC 9457 Problem Details object — a structured action request, not the normal success carrier. The user needs to take an action; your job is to RENDER that action, not narrate it. Render ONLY these fields, in this order: 1. The `title` field as a short heading. 2. The `detail` field as the explanatory sentence, VERBATIM. 3. A SINGLE markdown hyperlink in the exact form `[voderAction.label](voderAction.url)` — substitute the literal `voderAction.label` string as the link text and the literal `voderAction.url` string as the target. This is the button the user clicks. 4. The `voderAction.hint` field as a brief framing sentence below the link, VERBATIM. DO NOT surface ANY of the following fields to the user — they are internal metadata and have no meaning to a non-developer: `status` (an HTTP-shape integer), `type` (an internal URI), `instance` (an internal reference). The user must NEVER see "409" or "424" or any URI starting with `https://voder.ai/problems/` in your answer. DO NOT narrate or paraphrase the action ("Voder needs you to..." / "The system returned a status code..." / "and gives a 424 with action Connect Voder to Xero at the Voder dashboard"). RENDER the markdown hyperlink so the user can click it directly. DO NOT retry this tool, and do NOT call any other Xero tool to work around the problem — they will all return the same Problem Details response until the user follows the `voderAction.url` link and completes the action.
xero_organisation_details
How do I improve a ChatGPT Plugin's discoverability?
The levers are the listing surface agents actually read: names, descriptions, keywords, tool metadata, and registry health. Which lever matters depends on where discovery breaks, which is what continuous measurement shows.
What are Voder alternatives on ChatGPT?
As of 2026-08-14, Voder competes with Alteryx Insights, Azadea One, Bark AI, BlazeSQL, Bloom Profit Analytics, Book Report, Carbon Arc, Catalyst by Zoho, ChartMogul, Cleverbridge, Corporate Weather, Coupler.io, DataAssist-IO, Deepnote, Evidence Studio, Ezoic Analytics, Flourish, Fr8Labs Analytics, Fullmetrix, Hex, Keypup, Metorik, Omni, OWOX Data Marts, Prism by Crossdeck, Sportily, Steep, Sweet Analytics, Tableau, Tenzo, Tessie, ThoughtSpot Spotter, Wednesday.app, Winnow, WitCloud, XAPP Analyst in ChatGPT Self-Serve BI & Conversational Analytics, ranked by public Discoverability Score.
Where is this profile measured?
This profile uses the geography attached to the latest public registry snapshot: US. Locale tags are intentionally omitted.