Every tool below is scoped to your own organization and checked against your own BonsAI permissions — the same rules the web app enforces. entity_id (and any other id) has to be one you already have access to; list_entities is usually the first call in any conversation.
Pagination note: most list_* tools take page_number (0-indexed) and n_per_page (1–100, default 20), and return has_more/next_page_number — keep n_per_page the same across pages.
Identity, organization & usage
#
| Tool |
Input |
Output |
What it does |
whoami |
(none) |
Name, email, organization, and every entity you belong to with your role/permissions there |
Confirms the connection and shows what you can access — a good first call |
organization_by_external_id |
external_id (Clerk org id, org_...) |
Org id, name, slug, timestamps |
Looks up any organization by its Clerk id (not just your own) |
organization_settings |
(none) |
Email-domain whitelist setting, knowledge-sharing opt-in |
Your org’s settings — requires org admin/owner |
organization_roles |
page_number?, n_per_page? |
Every entity role in your org, with full per-resource permissions |
The role catalog add_entity_member/update_entity_member pick a role_id from |
organization_analytics |
start_date?, end_date? (epoch ms) |
Daily extraction counts by type/source, in-review counts, per-entity usage summary |
Usage dashboards / reporting |
billings |
(none) |
Current plan, AI-extraction usage/limits, entity-count usage/limits, trial status |
“Am I near my plan limit?” |
my_verification_count |
(none) |
Your own verified-invoice counts, last 90 days |
Personal activity stat |
my_prompt_usage |
(none) |
Your own self-prompt / Tofie-prompt counts, all-time |
Personal activity stat |
Entities & members
#
| Tool |
Input |
Output |
What it does |
list_entities |
page_number?, n_per_page? |
Every entity you can access, with your role in each |
Find an entity’s id by name |
get_entity |
entity_id, force_reload? |
Full entity record: settings, accounting config, your role |
Read one entity’s full configuration |
get_entity_me |
entity_id |
Your membership record and permissions for that entity |
“What exactly can I do on this entity?” |
create_entity (write) |
name, slug, country_id, share_knowledge_opt_in, + optional flags (multi_type_extraction_enabled, target_accounting_software, …) |
The created entity, with you added as Manager |
Creates a new entity — needs org-level Entity:Create |
update_entity_settings (write) |
entity_id + only the fields you want to change (name, slug, auto-publish/import flags, invoice-status settings, …) |
The updated entity |
Updates entity settings — needs entity- or org-level Entity:Update. Fields you don’t pass are left untouched; a no-op call returns no_op: true |
add_entity_member (write) |
entity_id, app_user_id (target’s Clerk id), role_id |
The new membership |
Adds an existing org member to an entity — needs Member:Write |
update_entity_member (write) |
entity_id, app_user_id (target’s BonsAI user id), role_id |
The updated membership, incl. previous_role |
Changes a member’s entity role — needs Member:Update |
remove_entity_member (write) |
entity_id, app_user_id (target’s BonsAI user id) |
Confirmation, incl. removed_role |
Removes a member from an entity — needs Member:Delete; refuses to remove the last member |
assign_org_role (write) |
user_id, role (org:system_owner / org:system_admin / org:collaborator / org:contributor / org:billing) |
Previous and new role |
Changes a member’s org-wide Clerk role — needs org:sys_memberships:manage; can’t demote the last owner |
Documents
#
| Tool |
Input |
Output |
What it does |
upload_document (write) |
entity_id, files[] (file_name, mime_type, content_base64), extraction_type?, sync_with_integration? |
Created document(s), status PENDING |
Uploads up to 20 files (≤20MB each, ≤50MB combined). Passing extraction_type auto-triggers extraction on them |
list_documents |
entity_id, timestamp_from?, timestamp_to? (≤3-month range), updated_after?, paging |
Document summaries: file name, status, mime type, size |
Browse recently uploaded documents |
get_document |
document_id, entity_id |
Full document detail, incl. its pages |
One document’s status and page list |
get_document_page |
document_page_id, entity_id |
Page metadata: page number, rotation, bounding box |
One page’s metadata (no image bytes) |
get_document_page_image |
document_page_id, entity_id, size? (xs/sm/md/lg) |
Inline rendered image |
The page as an image the model can look at |
get_document_page_signed_urls |
document_page_id, entity_id |
Short-lived signed URLs, one per size up to xl |
For handing a page to a human to open in a browser — links expire in ~1 hour |
download_document_file |
document_id, entity_id |
The original uploaded file, inline bytes |
The raw source file (PDF/image) — refuses files over 750KB |
Invoices & AP bills / AR invoices
#
| Tool |
Input |
Output |
What it does |
get_invoice |
invoice_id (or extraction_id with is_extraction_id: true), entity_id |
Status, publish/import state, current invoice_data (amounts, dates, contact, line items) |
One invoice’s current data |
get_invoice_data |
invoice_id, entity_id, action_types?, paging |
Version history of the invoice’s data (one row per edit/publish/verify/etc.) |
Audit trail for one invoice |
invoices_search_data |
entity_id, extraction_data_ids[] (1–50, from get_invoice_data/get_invoice) |
The matching invoices’ current data |
Batch-fetch by known invoice-data id (not a search — no filter by contact/amount/date exists yet) |
Direct expenses
#
| Tool |
Input |
Output |
What it does |
get_direct_expense |
extraction_id, entity_id |
Status, publish/import state, current data |
One direct expense’s current data (keyed by extraction id, not a separate direct-expense id) |
get_direct_expense_data |
direct_expense_id, entity_id, action_types?, paging |
Version history of the expense’s data |
Audit trail for one direct expense |
Bank statements
#
| Tool |
Input |
Output |
What it does |
list_bank_statements |
entity_id, paging |
Bank statement summaries |
Browse bank statements |
get_bank_statement |
extraction_id, entity_id |
Every mapped account/data row for the statement (bank name, account number, opening/closing balance, period) |
One statement’s full detail |
| Tool |
Input |
Output |
What it does |
create_extraction (write) |
entity_id, type (AP_BILL/AR_INVOICE/BANK_STATEMENT/DIRECT_EXPENSE), pages[] (from an upload), title?, id? |
The new extraction, status PENDING, then processing starts |
Creates and triggers a new extraction from already-uploaded pages in one call |
trigger_extraction (write) |
entity_id, extraction_id, full_extraction? |
The extraction, intended status: PROCESSING — but the response can be a stale snapshot caught mid-transition (e.g. briefly showing an already-superseded status); poll get_extraction to confirm the real state |
Re-triggers an existing extraction (e.g. after CLASSIFY_AND_REVIEW held it, or to redo a failed run). full_extraction: true discards prior data and starts fresh |
get_extraction |
extraction_id, entity_id |
Status, error info, pages, flattened data summary |
Check on any extraction regardless of type — use get_invoice/get_direct_expense/get_bank_statement for the full typed detail |
list_extractions |
entity_id, types?, statuses?, timestamp_from?/to? (≤3-month range), paging |
Extraction summaries |
Browse/filter extractions by type and status |
Knowledge & learning
#
| Tool |
Input |
Output |
What it does |
create_knowledge_card (write) |
entity_id, contents? (free text; omit to learn from history instead), extraction_type/extraction_types, preferred_language? |
{message: "Knowledge creation job has been queued"} |
Teaches Tofie’s AI extraction a rule for future documents — async, needs entity-level EntityKnowledge:Update |
list_knowledge_conflicts |
entity_id, extraction_type |
Pending conflicts where a new learning contradicts an existing one |
Review learnings that need a human decision |
get_contact_learnings |
entity_id, extraction_type, paging |
Latest learning per contact (vendor name, contact name, learning text) |
What Tofie has learned about each of your vendors/customers |
Integrations & reference data
#
| Tool |
Input |
Output |
What it does |
list_integrations |
entity_id, paging |
Every integration (accounting connections + trigger sources) on the entity |
See what’s connected |
get_integration |
integration_id, entity_id |
Full integration detail incl. accounting tax/rounding config |
One integration’s full config |
get_integration_details |
integration_id, entity_id |
Installation warnings only |
UI-style warnings for one integration |
accounting_tags |
entity_id, paging |
Tags/tracking categories configured on the entity |
e.g. Xero tracking categories |
accounting_tag_usage |
entity_id, tag_id |
Invoice/direct-expense usage counts for that tag |
How much a tag is actually used |
priority_fields |
entity_id, extraction_type, paging |
Priority field names for that entity + document type |
Fields Bonsai-Knowledge prioritizes when extracting |
countries |
page_number?, n_per_page? |
Every ISO 3166-1 alpha-2 country code bonsapi recognizes |
Valid values for country_id |
currencies |
page_number?, n_per_page? |
Every ISO 4217 currency code + tax decimal places |
Valid values for currency fields |
(write) tools change data and require the matching BonsAI permission on your account — you’ll get a clear error, not a silent failure, if you don’t have it.