Skip to content
todah
Features Pricing Help About Contact Sign in Start free

Todah for developers and AI apps

Connect Claude or another AI app to your Todah workspace, or build on the Todah REST API. Both are free on every plan, including Free.

Connect an AI app (MCP)

Todah runs a remote Model Context Protocol server. Any AI app that supports remote MCP servers can use it. Its address is:

https://todah.ca/mcp

Claude

  1. In Claude, open Settings → Connectors and choose Add custom connector.
  2. Name it Todah and paste https://todah.ca/mcp as the address.
  3. Choose Connect. Sign in to Todah, then review what Claude may do. Untick Also let it make changes if you want Claude to read only.
  4. Ask Claude things like "which invoices are overdue?", "draft an invoice to Acme for two hours of consulting at $120 plus GST", or "how did revenue compare month to month this year?"

In Claude Code: claude mcp add --transport http todah https://todah.ca/mcp, then run /mcp to sign in.

What an AI app can and cannot do

  • It acts as you, with your role in your workspace, and sees only that workspace.
  • With read access it can look at clients, invoices, quotes, credit notes, bills, vendors, products, recurring invoices and the reports built from them.
  • With change access it can also create and edit clients, vendors, products, draft invoices, quotes and bills, record a payment you have received, and email an invoice or quote to your client. Before any email it must ask you, and at most 30 emails an hour go out this way.
  • It can never see bank transactions or bank connections, delete anything, issue a refund, take or move money, or change your plan, team, settings or sign-in.
  • Disconnect it at any time in Settings → Connected Apps. It loses access at once.
ToolWhat it doesAccess
get_workspaceThe signed-in workspace, plan, person and what this connection may do.Read
get_overviewHeadline numbers: clients, invoices, revenue, outstanding and overdue amounts, expenses.Read
list_clientsClients, newest first. Filter by text in the name or email.Read
get_clientOne client with its contact people.Read
get_client_statementA client's statement: invoices, payments and credits, with the balance owing.Read
list_invoicesInvoices, newest first, with status (Draft, Sent, Overdue, Partially paid, Paid, Cancelled) and balance.Read
get_invoiceOne invoice with its lines, client and payments.Read
list_overdue_invoicesInvoices past their due date with a balance still owing.Read
list_quotesQuotes (estimates), newest first.Read
get_quoteOne quote with its lines and client.Read
list_credit_notesCredit notes issued to clients.Read
list_billsBills and receipts from vendors, newest first.Read
get_billOne bill with its lines and expense categories.Read
list_overdue_billsBills past their due date and still owed.Read
list_vendorsVendors (suppliers).Read
list_productsSaved products and services with default prices.Read
list_expense_categoriesExpense categories for bill lines, each marked COGS or OpEx.Read
list_sales_taxesThe sales taxes set up in this workspace, with rates.Read
list_recurring_invoicesInvoices set to repeat on a schedule.Read
get_reportA financial report built from invoices, bills and credit notes. Some need the Business plan.Read
create_clientAdd a client.Change
update_clientChange a client's details. Fields left out keep their current value.Change
create_vendorAdd a vendor (supplier).Change
update_vendorChange a vendor's details. Fields left out keep their current value.Change
create_productSave a product or service with a default price.Change
update_productChange a saved product or service. Fields left out keep their current value.Change
create_invoiceCreate an invoice as a draft. It is numbered automatically and is not sent.Change
update_invoiceChange a draft invoice. Fields left out keep their current value; items, if given, replace all the lines. Sent invoices cannot be edited.Change
record_invoice_paymentRecord money a client has already paid against an invoice (cash, cheque, e-transfer...). This is bookkeeping: it moves no money.Change
create_quoteCreate a quote (estimate) as a draft. Not sent.Change
update_quoteChange a quote. Fields left out keep their current value; items, if given, replace all the lines.Change
convert_quote_to_invoiceTurn a quote into a draft invoice with the same lines.Change
create_billRecord a bill or receipt from a vendor.Change
update_billChange a bill. Fields left out keep their current value; items, if given, replace all the lines.Change
send_invoiceEmail an invoice to the client's billing contacts, with the PDF attached. Cannot be undone; requires the user to confirm.Change: emails a client, asks you first
send_quoteEmail a quote to the client's contacts, with the PDF attached. Cannot be undone; requires the user to confirm.Change: emails a client, asks you first

REST API

Base address https://todah.ca/api/v1. Requests and responses are JSON. Create a token in Settings → Connected Apps → API Tokens (read only, or read and change) and send it in the Authorization header. A token is shown once; Todah stores only a fingerprint of it.

curl https://todah.ca/api/v1/invoices \
  -H "Authorization: Bearer todah_pat_..."

curl -X POST https://todah.ca/api/v1/clients \
  -H "Authorization: Bearer todah_pat_..." \
  -H "Content-Type: application/json" \
  -d '{"name": "Acme Ltd", "email": "ap@acme.example", "payment_terms": "Net 30"}'

GET /api/v1 lists the endpoints your token can call, and GET /api/v1/me says whose workspace it is. Fields are the same as the Todah app's own: amounts are numbers in your currency, tax_rate and discount are percentages, dates are YYYY-MM-DD, and an invoice line is {"description", "quantity", "unit_price", "tax_rate", "discount"}.

Rules

  • Every request runs through the same checks as the app: your role, your plan's limits, and the rules on each record (for example, only a draft invoice can be edited).
  • Nothing can be deleted through the API (DELETE answers 405), and bank data, refunds, payment links, settings, team and billing are not part of it.
  • Limits: 60 requests a minute per workspace, and 30 client emails an hour. Over a limit you get 429 with Retry-After.
  • Errors are JSON: {"error": "what went wrong and how to fix it"}, with 400 for a bad request, 401 for a missing or revoked token, 403 for a missing permission or scope, 404 for something that is not there or not in the API.
MethodPathScope
GET/api/v1read
GET/api/v1/meread
GET/api/v1/billableread
GET/api/v1/billable/summaryread
GET/api/v1/billsread
POST/api/v1/billswrite
GET/api/v1/bills/overdueread
GET/api/v1/bills/{bill_id}read
PUT/api/v1/bills/{bill_id}write
GET/api/v1/clientsread
POST/api/v1/clientswrite
GET/api/v1/clients/{cid}read
PUT/api/v1/clients/{cid}write
GET/api/v1/clients/{cid}/contactsread
POST/api/v1/clients/{cid}/contactswrite
PUT/api/v1/clients/{cid}/contacts/{contact_id}write
GET/api/v1/clients/{cid}/statementread
GET/api/v1/credit-notesread
GET/api/v1/credit-notes/{cn_id}read
GET/api/v1/expense-categoriesread
GET/api/v1/expenses/summaryread
GET/api/v1/invoicesread
POST/api/v1/invoiceswrite
GET/api/v1/invoices/next-numberread
GET/api/v1/invoices/overdueread
GET/api/v1/invoices/{inv_id}read
PUT/api/v1/invoices/{inv_id}write
GET/api/v1/invoices/{inv_id}/paymentsread
POST/api/v1/invoices/{inv_id}/paymentswrite
POST/api/v1/invoices/{inv_id}/sendwrite
GET/api/v1/productsread
POST/api/v1/productswrite
PUT/api/v1/products/{pid}write
GET/api/v1/quotesread
POST/api/v1/quoteswrite
GET/api/v1/quotes/next-numberread
GET/api/v1/quotes/{quote_id}read
PUT/api/v1/quotes/{quote_id}write
POST/api/v1/quotes/{quote_id}/convertwrite
POST/api/v1/quotes/{quote_id}/sendwrite
GET/api/v1/recurringread
GET/api/v1/recurring/{rid}read
GET/api/v1/reports/ap-agingread
GET/api/v1/reports/ar-agingread
GET/api/v1/reports/cogsread
GET/api/v1/reports/distributionsread
GET/api/v1/reports/expenses-by-vendorread
GET/api/v1/reports/gstread
GET/api/v1/reports/income-by-customerread
GET/api/v1/reports/monthlyread
GET/api/v1/reports/opexread
GET/api/v1/reports/pnlread
GET/api/v1/reports/tax-summaryread
GET/api/v1/sales-taxesread
GET/api/v1/statsread
GET/api/v1/vendorsread
POST/api/v1/vendorswrite
PUT/api/v1/vendors/{vendor_id}write

Building an integration with sign-in (OAuth)

Apps that act for many Todah customers should use OAuth 2.1 instead of asking people for a token. Todah publishes its metadata at https://todah.ca/.well-known/oauth-authorization-server and https://todah.ca/.well-known/oauth-protected-resource. It supports the authorisation code flow with PKCE (S256), public clients, dynamic client registration, client ID metadata documents, refresh-token rotation, revocation, and resource indicators (https://todah.ca/mcp or https://todah.ca/api/v1). Scopes are todah.read and todah.write.

Privacy and your data

When you connect an AI app, what it reads from Todah goes to that app's provider, which may process it outside Canada under its own terms. Connect only apps you trust, and give read-only access where that is enough. See our Privacy Policy and Terms.

Support

Questions, problems or a security report: support@todah.ca.

© A913 Services Inc.
Home · Pricing · Features · Help · FAQ · About · For bookkeepers · Developers · Privacy · Terms