Docs

Give your agent books.

AI3 Ledger is double-entry accounting for an agent whose work is done by agents. Any agent, on any runtime, keeps them with one key over HTTP or MCP: it reports what it spends, raises and sends invoices, records what is paid, and reads its own runway. It needs nothing else from AI3.

What it is

  • Real books. A chart of accounts, journals, periods, invoices in any currency with hosted pages, bills, bank and wallet feeds, reconciliation proposed by a model, profit and loss, a balance sheet that is checked rather than assumed.
  • Never estimated. Every figure is posted from a document or a cost record. An amount that is not known is refused, not booked as zero.
  • One agent per key. A key reads and writes one agent's books and nothing else. A person's token may act across every agent they own.
  • The same tools everywhere. The 35 tools below are the same on the HTTP API, on the MCP, and behind the finance screens. One core, three doors.

From nothing to books

Four calls. The first needs a personal token (or a signed-in browser); the rest use the agent key it returns.

curl -X POST https://ai3.co/api/ledger/v1/organisations \
  -H "authorization: Bearer ai3t_YOUR_TOKEN" -H "content-type: application/json" \
  -d '{ "name": "Lovelace Analytical", "currency": "USD", "platform": "claude-code" }'
# → { "organisation": { "id", "slug", "companyId", "books" }, "key": "ai3k_…", "scopes": ["read","write"] }
curl -X POST https://ai3.co/api/ledger/v1/costs \
  -H "authorization: Bearer ai3k_YOUR_KEY" -H "content-type: application/json" \
  -d '{ "costs": [{ "ref": "run-8f2a", "amountMinor": 125, "category": "model", "biller": "anthropic" }] }'
# → { "posted": 1, "duplicates": 0, "transactionIds": ["…"] }
curl -X POST https://ai3.co/api/ledger/v1/tools/create-invoice \
  -H "authorization: Bearer ai3k_YOUR_KEY" -H "content-type: application/json" \
  -d '{ "customer": "Babbage & Co", "customerEmail": "charles@babbage.example", "lines": [{ "description": "Analysis", "unitAmount": "2500.00" }], "sendTo": "charles@babbage.example" }'
# → issued, given a page at https://ai3.co/i/…, and emailed
curl -X POST https://ai3.co/api/ledger/v1/tools/balance-sheet -H "authorization: Bearer ai3k_YOUR_KEY" -d '{}'

Every tool is POST /api/ledger/v1/tools/<name> with its parameters as JSON, and answers { content, data } or { error }. Amounts you send are in major units with two decimals, as the tools have always taken them; costs are in minor units, because that is what a platform reports. The full contract is openapi.json; the skill an agent can be handed is skill.md.

Report what you spend

POST /api/ledger/v1/costs takes one cost or { costs: [ … ] }, up to 500 at a time. Each one is ref (your own id for it), amountMinor (an integer), and optionally category (model, tool, compute, other), biller, occurredAt, description, and agent, project or work references. Each posts debit the expense account for its category, credit treasury, under the platform your key declares.

A repeated ref is the same transaction, returned again: retry as often as you like. A cost without an amount is refused. This is the same path every agent's run costs and Managed Agents' sessions take; the only difference is who does the reading.

Keys and scopes

CredentialSpeaks forScopes
Agent keyai3k_…One agent's booksread the reports and documents; write documents, costs and reconciliation decisions; admin keys, settings and period close. write implies read; admin implies both.
Personal tokenai3t_…A person, across every agent they own or administerEverything, naming the agent with ?org=<slug> when they own more than one.

Keys are issued and revoked under Books → Settings → Keys for agents, or with POST /api/ledger/v1/keys and DELETE /api/ledger/v1/keys/<id> (admin). Only a hash is kept; the secret is shown once. A revoked key is refused from the next request.

The tools

Read tools need read; the rest need write. * marks a required parameter; the schemas are in the contract.

ToolWhat it does
positionreadWhat the company holds and burns right now: treasury (cash across bank accounts), receivables owed by customers, month-to-date income and expense, trailing 30-day burn, and runway in days. Use this before deciding anything that spends or collects money.
invoicesreadInvoices the company has raised, newest first, with status, totals, outstanding amount, days overdue, and whether the customer opened the online copy. Filter by status or ask for overdue only.status overdueOnly limit
invoicereadOne invoice in full: lines, payments received, payment options printed on it, the online link, and sent/opened status.invoice*
customersreadThe customers the company has invoiced or set up, with ids and emails.
create-invoicewriteRaise an invoice for a customer. Names a customer (created if new), lists what is being billed, and by default issues it immediately, which posts the receivable and creates the online copy. Pass sendTo to email it in the same step. Amounts are in the invoice currency; a non-base currency is converted at the published rate unless rateToBase is given.customer* customerEmail currency rateToBase lines* dueInDays notes issue sendTo message
send-invoicewriteEmail an issued invoice to the customer from the company owner’s Gmail, with a link to the online copy. Opens are tracked. Requires the company to be connected to ai3.co.invoice* to cc message
record-paymentwriteRecord money received against an invoice. Defaults to the full outstanding amount. Books the cash, clears the receivable, and any exchange difference goes to currency gains and losses.invoice* amount date reference rateToBase
void-invoicewriteCancel an invoice that was raised in error. A draft is simply voided; an issued one is reversed so the receivable disappears. Cannot be undone.invoice* reason
write-off-invoicewriteGive up on collecting what is outstanding on an invoice: the receivable moves to bad debt expense.invoice* reason
creditsreadThe company’s prepaid model credits at ai3.co: balance left, what was put in, what model usage has been charged (at cost plus the platform markup), and how to top up (pathUSD to the platform wallet with the credit memo, which the pay-invoice tool can send). Pass sync true to book the latest grants and usage into the ledger now.sync
bank-accountsreadThe company’s bank accounts and wallets with the balance in the books, the last statement balance, and how many statement lines still need reconciling.
reconcile-queuereadStatement lines not yet explained in the books, each with the ledger’s proposal (match an existing transaction, create a new one against an account, a transfer between accounts, or a question with options) and its confidence and reason. Work through these with the reconcile tool.bankAccountId limit
reconcilewriteSettle one statement line. Either accept the proposal as shown in the queue, or give a decision: match (transactionIds), create (accountCode, description, contactName), transfer (otherBankAccountId), or exclude (reason). A confirmed decision teaches a rule for the same payee next time.lineId* accept decision
reconcile-allwriteRun the matcher over every unreconciled line and post every proposal at or above the confidence threshold (default 90). Returns what was posted and what still needs a decision.bankAccountId threshold
profit-and-lossreadIncome and expense by account for a period. Defaults to the current month to date. Optionally grouped by agent or project.from to groupBy
balance-sheetreadAssets, liabilities and equity as of a date (default today).asOf
walletwriteThe company’s stablecoin wallet on Tempo (Stripe’s payments chain, testnet): address, pathUSD balance, explorer link. It is printed on invoices as a payment option and its feed reconciles itself. Pass topUp true to ask the testnet faucet for more test money.topUp sync
pay-invoicewritePay an invoice the company received. Two rails: pathUSD from the company wallet on Tempo (invoice number in the transfer memo, so the seller’s books reconcile it), or the card the owner saved on ai3.co through Stripe (the seller must take card payments; the charge lands on their Stripe account with the invoice number). Give the invoice’s online link (an ai3.co/i/… URL) and amount, currency, payee and invoice number are read from it; or give a raw wallet address and amount. rail defaults to auto: the wallet when the invoice offers one and the balance covers it, else the card. Books the payment as an expense. An agent pays only inside a spending authority the owner granted on ai3.co: the tool asks first, and a refusal says which rule and where the owner can change it (the authorities page, or the feed while the inspection window is open). Never work around a refusal.invoiceUrl rail to amount memo description accountCode
stripereadThe company’s Stripe through ai3.co: whether card payments are on (invoices then carry a Pay by card button and other companies can pay from their saved card), the card this company has on file for paying others, and links to fix either. Pass connect true to start or continue Stripe onboarding (returns a link the owner opens); sync true to read new Stripe charges, fees and payouts into the books now.connect sync
dispute-invoicewriteFile a dispute at Recourse (recourse.so), the venue every invoice names, signed with the company wallet. As the buyer, give the invoice’s online link and what went wrong. As the seller, give your own invoice number (for example non-payment) and the buyer’s wallet address. The ruling comes back in about a minute with a fault split and a money instruction on the Tempo rail; use settle-dispute to carry it out.invoiceUrl invoice counterpartyAddress breach remedy evidence verdict amount
disputereadDisputes this company is party to, with the ruling and money instruction once decided. Pass a dispute or case id for one and it is refreshed from the venue.dispute
settle-disputewriteCarry out a ruling’s money instruction from the company wallet: every transfer the ruling says this company owes is sent in pathUSD with the case id in the memo, and booked.dispute*
chart-of-accountsreadEvery account in the books with its code, name, type and current balance. Use the codes when posting a journal or choosing where a bill line goes.
post-journalwritePost a balanced manual journal: at least two lines, each a debit or a credit to an account code, debits equal to credits. Use it for accruals, corrections, prepayments and anything no other tool covers. Pass draft: true to leave it unposted for a person to review.date narration lines* draft
journalsreadManual journals, newest first, with status (draft, posted, voided), date, narration and totals.status limit
void-journalwriteReverse a posted journal so it drops out of every report. The journal and its reversal both stay in the books. Cannot be undone.journal* reason
trial-balancereadEvery account with a balance at a date, debit balances in one column and credit balances in the other, and whether the two agree. Pass from to see only the movements in a window.asOf from
entriesreadThe posted entries behind a report figure: filter by account code or account type, a date window, an agent, and the kind of source (cost_sweep, invoice, payment, bill, journal, funding, reversal, conversion). Each row names the transaction it belongs to; pass that id to `transaction` for the full story.account type from to agent sourceKind limit
transactionreadOne transaction in full: every debit and credit, what caused it (an invoice, a bill and its attached documents, a bank line, a journal, or the cost event with its agent and run), and whether it was reversed.transactionId*
suppliersreadSuppliers the company has bills from, with ids, emails and the expense account their bills default to.
billsreadBills received from suppliers, newest first, with status (draft, approved, part_paid, paid, void), totals, what is still owed and days overdue.status overdueOnly limit
billreadOne bill in full: lines with their expense accounts, tax, payments made, and the supplier.bill*
create-billwriteRecord a bill the company owes a supplier. Names the supplier (created if new), lists the lines with the expense account each belongs to, and by default approves it, which books the expense and the payable. Amounts are in the bill currency.supplier* supplierEmail reference date dueInDays currency rateToBase lines* notes approve
pay-billwriteRecord that a bill was paid, in full by default, from Treasury or a named bank account code. Posts debit Payables / credit the cash account.bill* amount date reference fromAccount
void-billwriteCancel a bill recorded in error. A draft is voided; an approved bill with nothing paid is reversed. Cannot be undone.bill* reason

From Claude or ChatGPT

AI3 is an MCP server at https://ai3.co/mcp. With a personal token, the same tools appear as ledger_position, ledger_create_invoice and so on, plus open_books (open an agent for its books alone), report_costs and issue_ledger_key. Every write needs confirm: true; called without it, the tool says what it would do.

Rules

  • Every transaction sums to zero, and the database refuses one that does not.
  • The books are append-only. A correction is a reversal (void-invoice, void-journal, void-bill), never an edit.
  • A draft an agent raises changes no report until it is issued. create-invoice issues by default; draft: true leaves it for a person.
  • A closed period refuses new entries dated inside it.
  • Money is integer minor units. Floats are refused at the door.
  • Nothing is estimated. A figure is actual, incomplete or unavailable, and says which.