# Transactions

> Entries, bank and card lines, categories, tags, accounts, reconciliation and statements.

MCP toolset: `transactions` (https://app.getoatmilk.com/api/mcp?toolset=transactions)

## accounts

- [`accounts.create`](https://app.getoatmilk.com/docs/api/accounts.create.md) — Create an RBC or other manually imported bank account.

- [`accounts.lifecycle`](https://app.getoatmilk.com/docs/api/accounts.lifecycle.md) — Mark an account inactive from an explicit date or since its last verified statement, or reactivate it. Preserves historical records and earlier statement obligations. Requires the current revision and an idempotency key.

- [`accounts.list`](https://app.getoatmilk.com/docs/api/accounts.list.md) — List available bank and payment accounts.

- [`accounts.update`](https://app.getoatmilk.com/docs/api/accounts.update.md) — Set an account display name using the current revision and an idempotency key. Provider identity and currency remain unchanged.

## accounts.lifecycle

- [`accounts.lifecycle.preview`](https://app.getoatmilk.com/docs/api/accounts.lifecycle.preview.md) — Read the account and its latest verified statement end date before marking it inactive. Returns the next-day cutoff, or null when no verified statement is available.

## cards

- [`cards.claim`](https://app.getoatmilk.com/docs/api/cards.claim.md) — Update the caller's card claims atomically: identifierIds claims unassigned cards, releaseIdentifierIds releases only cards the caller personally claimed, seenIdentifierIds records what they reviewed, and idempotencyKey prevents duplicate saves. Other people's cards and finance-managed assignments cannot be changed; administrators reassign those in Cards.

- [`cards.claimable`](https://app.getoatmilk.com/docs/api/cards.claimable.md) — Show unassigned company cards (last four digits, printed name and account only), the caller's original mine list of last-four strings, and ownedCards for editing. Own cards are marked removable only when the caller linked them. No transaction details are returned. The caller may edit an earlier answer, or is asked about unseen unassigned cards when holding none.

- [`cards.list`](https://app.getoatmilk.com/docs/api/cards.list.md) — List the card and account numbers (last four digits) Oatmilk uses to tell which account paid, with each one's account, cardholder and whether a person or Autopilot added it, whether each account is a bank account or a credit card, the members who can hold a card (with their names), and suggested cardholders for cards nobody holds yet, matched from the name printed on the card.

- [`cards.save`](https://app.getoatmilk.com/docs/api/cards.save.md) — Add a card or account number (kind card_last4 or account_last4 and four digits) to an account, or change its label, cardholder or whether it is on, with idempotencyKey (and id with expectedRevision for changes). Receipts paid with that card are placed on its account. A number active on another account is refused.

- [`cards.setAccountType`](https://app.getoatmilk.com/docs/api/cards.setAccountType.md) — Mark an account as a bank account or a credit card with accountId, accountType, expectedRevision and idempotencyKey. Payments between a bank account and a credit card are then treated as transfers.

## cards.prompt

- [`cards.prompt.dismiss`](https://app.getoatmilk.com/docs/api/cards.prompt.dismiss.md) — Answer "None of these" to "Which of these cards are yours?", with the seenIdentifierIds you were shown and idempotencyKey. You're asked again only about cards added later.

## categories

- [`categories.addRecommended`](https://app.getoatmilk.com/docs/api/categories.addRecommended.md) — Add the recommended categories the organization doesn't have yet, archived until someone turns them on. Supply idempotencyKey and optional keys to add only some. Existing categories are never renamed or moved. Finance access required.

- [`categories.create`](https://app.getoatmilk.com/docs/api/categories.create.md) — Create an accounting category using name and idempotencyKey, with an optional top-level parentId (subcategories are one level deep), description (up to 500 characters, read by the AI) and rules: merchant words that always use this category. Requires finance access.

- [`categories.list`](https://app.getoatmilk.com/docs/api/categories.list.md) — List organization categories with parent_id, description, display path ("Events › Hackathons"), taxonomy_key, the caller's last_used_at and rule_count. Contributors see active categories only.

- [`categories.update`](https://app.getoatmilk.com/docs/api/categories.update.md) — Rename, move (parentId, or null for top level), describe or deactivate a category with a revision check, or choose it for automatic filing with useFor (income, bank_fees, other, contractors, interest_income). A category with active subcategories can't be deactivated. Finance access required.

## entries

- [`entries.attachReceipt`](https://app.getoatmilk.com/docs/api/entries.attachReceipt.md) — Attach a receipt entry to an existing compatible bank entry without duplicating expenses. Requires both current revisions and an idempotency key.

- [`entries.bulkCategorize`](https://app.getoatmilk.com/docs/api/entries.bulkCategorize.md) — Categorize a set of entries with their current revisions. Finance access required.

- [`entries.context`](https://app.getoatmilk.com/docs/api/entries.context.md) — Read what Oatmilk knows about where and when a transaction happened, by entryId: the trip it belongs to, its place pin, whether it looks like a hotel hold (with the reason and the date a final charge is expected), and purchases within about a kilometre around the same dates. Contributors can read only transactions they own.

- [`entries.create`](https://app.getoatmilk.com/docs/api/entries.create.md) — Manually create a receipt entry from preserved evidence when extraction needs correction. Requires the submission revision, exact minor-unit amounts and an idempotency key.

- [`entries.delete`](https://app.getoatmilk.com/docs/api/entries.delete.md) — Delete a transaction from the books with id, expectedRevision, reason (3 to 1000 characters), idempotencyKey and optional choices: bankLines keep (default, the line goes back to Reconcile) or exclude (a manual CSV line leaves the books too), receipts dismiss (default, labelled not a transaction) or keep, and email not_transaction (default, the company email is archived as general mail) or keep. A submitted reimbursement claim is withdrawn, the transaction leaves its trip and open questions close. It is voided, never erased: files, history and audit stay, and entries.restore puts it back. Refused when entries.delete.preview lists a blocker. Finance access required.

- [`entries.get`](https://app.getoatmilk.com/docs/api/entries.get.md) — Get an entry by id with its evidence and allocations.

- [`entries.list`](https://app.getoatmilk.com/docs/api/entries.list.md) — Search accounting entries by query, status, account, category or date. Contributor results contain only their own entries.

- [`entries.restore`](https://app.getoatmilk.com/docs/api/entries.restore.md) — Restore a deleted transaction with id, expectedRevision (its revision after deleting), reason and idempotencyKey. Its bank matches, excluded bank lines, receipt labels, the email's folder, a withdrawn claim, its trip and its questions come back when nothing changed since; a bank line matched to something else since is a conflict. Finance access required.

- [`entries.retryStep`](https://app.getoatmilk.com/docs/api/entries.retryStep.md) — Restart a supported processing step for one transaction using its current revision and an idempotency key. Inspect the activity before choosing only_step or from_here; unsupported modes, protected human decisions, closed periods, and stale revisions are rejected. Review restarts require an administrator.

- [`entries.update`](https://app.getoatmilk.com/docs/api/entries.update.md) — Edit an entry using id, expectedRevision, idempotencyKey, merchant, date, amountMinor, currency, categoryId, paymentAccountId, type, status and notes. Closed periods cannot be changed. A matched entry keeps its amount, currency and account, and its type must follow the bank movement: money in is income, refund or transfer; money out is expense, fee, income_refund or transfer. Pass learn: false when putting an earlier value back, as Undo does, so the correction isn't retained as vendor learning.

## entries.delete

- [`entries.delete.preview`](https://app.getoatmilk.com/docs/api/entries.delete.preview.md) — Before deleting a transaction, read everything tied to it by id: its bank lines (and whether each can be excluded with it), the receipts and company email it came from, a reimbursement claim, its trip, splits, tags and open questions, the default for each choice, and anything that blocks deleting it (a closed period, a Stripe record, the book record of a synced Wise movement, an approved or paid reimbursement). A deleted transaction returns who deleted it, when and why. Finance access required.

## entries.deleted

- [`entries.deleted.list`](https://app.getoatmilk.com/docs/api/entries.deleted.list.md) — List deleted transactions, newest first, with limit and offset: merchant, date and amount, who deleted each, when and why, what else changed, and whether it was restored. Finance access required.

## entries.evidence

- [`entries.evidence.confirm`](https://app.getoatmilk.com/docs/api/entries.evidence.confirm.md) — Verify and append a prepared supporting original to its exact transaction with entryId, submissionId and idempotencyKey. Returns the preserved evidence and an extraction-only job; reading never creates purchases or changes financial fields. Duplicate originals on the same transaction are reused.

- [`entries.evidence.prepare`](https://app.getoatmilk.com/docs/api/entries.evidence.prepare.md) — Prepare an immutable supporting-original upload for an active editable transaction. Supply entryId, filename, mimeType, sizeBytes, sha256 and a stable idempotencyKey. Skip PUT when alreadyUploaded, then confirm. Adds documents alongside existing originals without creating purchases or changing financial fields.

## entries.hold

- [`entries.hold.release.undo`](https://app.getoatmilk.com/docs/api/entries.hold.release.undo.md) — Undo Oatmilk's pairing of money back on a card with the hotel hold it gave back, by the money back's releaseEntryId with an idempotencyKey. The pair is never made again, a card fee booked with the hold is a fee again, the money back is reviewed again, and a hold it resolved is open again. Finance access required; a closed month blocks it.

- [`entries.hold.set`](https://app.getoatmilk.com/docs/api/entries.hold.set.md) — Say whether a card charge is a hotel hold with entryId, state (confirmed_hold or not_a_hold) and an idempotencyKey. Confirming books the charge as a transfer, so it leaves expense totals and tax while staying visible and matched; pass resolvedByEntryId to say which later charge replaced it. Declining puts the purchase back. A person's decision is final: Oatmilk never overturns it. Closed periods can't change. Contributors can decide only transactions they own.

## entries.place

- [`entries.place.set`](https://app.getoatmilk.com/docs/api/entries.place.set.md) — Save where a purchase was made with entryId, lat, lon, a label, an optional address and an idempotencyKey. A place a person set is never replaced by an automatic lookup. Contributors can set only the place of transactions they own.

## entries.tags

- [`entries.tags.set`](https://app.getoatmilk.com/docs/api/entries.tags.set.md) — Add, remove or dismiss project tags on up to 100 entries at once with entryIds, add, remove and dismiss (tag ids) and idempotencyKey; pass the same operationId with every batch of one bulk change. Adding a tag Oatmilk suggested accepts it; dismissing a suggestion stops it being suggested for that entry. Tags added through the API or MCP are recorded as such and don't confirm rules; finance's dashboard choices do. A rule tags open transactions by itself only for a tag with start and end dates, after two confirmations from separate actions and no rejection, from the day it qualified. Contributors can tag only their own receipts until finance reviews them. Tags don't change amounts, categories or tax.

## exchangeRates

- [`exchangeRates.get`](https://app.getoatmilk.com/docs/api/exchangeRates.get.md) — Get the Bank of Canada daily exchange rate for a day, as units of quote for one base (for example base USD, quote CAD, date 2026-09-25). Pairs without CAD are crossed through CAD; a weekend or holiday uses the closest earlier business day. Returns the rate, the day it was published for, the series and a source description to keep with a match or tax review. Reads bankofcanada.ca and never changes anything.

## imports

- [`imports.commit`](https://app.getoatmilk.com/docs/api/imports.commit.md) — Import an RBC CSV with accountId, csv, filename, mapping and idempotencyKey. Preserves the original and deduplicates transactions. Autopilot classifies the new lines afterwards unless skipAi is true.

- [`imports.download`](https://app.getoatmilk.com/docs/api/imports.download.md) — Get an authorized short-lived download for the original statement or CSV import evidence.

- [`imports.preview`](https://app.getoatmilk.com/docs/api/imports.preview.md) — Validate a CSV import using accountId, csv text and mapping with date, description, amount or debit/credit, and dateFormat. Returns errors without booking transactions.

## imports.undo

- [`imports.undo.apply`](https://app.getoatmilk.com/docs/api/imports.undo.apply.md) — Undo explicitly selected import-owned groups atomically using the current preview fingerprint, reason, and idempotency key. Keep reviewed or edited transactions and detach their incorrect imported bank links when safe; remove only proved untouched derived entries. Preserves originals and audit. Closed periods and payment dependencies block changes.

- [`imports.undo.history`](https://app.getoatmilk.com/docs/api/imports.undo.history.md) — Read paged organization import, Undo, and Restore history with actual ownership counts and audited reasons. Optional batch and account filters keep the list scoped. Restore eligibility is checked by its lazy preview.

- [`imports.undo.preview`](https://app.getoatmilk.com/docs/api/imports.undo.preview.md) — Preview selective Undo for one manual CSV or uploaded statement import, or guarded Restore for one complete Undo operation. Resolve batch, statement, transaction, or bank-row context inside the organization. Returns paged groups, treatment choices, blockers, and an exact whole-graph fingerprint while preserving originals.

- [`imports.undo.restore`](https://app.getoatmilk.com/docs/api/imports.undo.restore.md) — Restore one entire Undo operation atomically using its current operation revision, inverse preview fingerprint, reason, and idempotency key. The server verifies exact after-state, current relationships, source ownership, and open periods. Later edits or conflicting allocations block restoration.

## investigations.questions

- [`investigations.questions.answer`](https://app.getoatmilk.com/docs/api/investigations.questions.answer.md) — Answer a question with its id, one of its optionId answers (or none_of_these when the person settled it by hand), an optional note of up to 1000 characters and an idempotencyKey. An offered answer does only what Oatmilk wrote down when it asked (confirm or decline a hold, put a receipt on a hotel's charge or take it off, link a transaction to a trip); none_of_these only closes the question. Every answer is audited, and a question closes once answered. Contributors can answer only questions about transactions they own.

- [`investigations.questions.list`](https://app.getoatmilk.com/docs/api/investigations.questions.list.md) — List the questions Oatmilk asked a person while investigating, newest first, optionally for one entryId or only the open ones. Each has a title, two to four answers, whether a note is allowed, and the answer when given. Contributors see only questions about transactions they own.

## investigations.review

- [`investigations.review.run`](https://app.getoatmilk.com/docs/api/investigations.review.run.md) — Run the second opinion now on one bank line (entryId) with an idempotencyKey: an agent with read-only lookups of the organization's transactions, hotel holds, trips, receipts and memory decides what the line is, pairs money back with the hold it gives back, or writes one specific question. Its answer is checked before Autopilot applies it, and its reasoning is kept in the transaction's activity. Administrators only.

## investigations

- [`investigations.run`](https://app.getoatmilk.com/docs/api/investigations.run.md) — Run the receipt investigator now for one transaction or receipt (entryId) with an idempotencyKey: it gathers what Oatmilk knows, asks the investigator for a judgement, links a receipt charged to a hotel room to the hotel's charge, and asks a person one plain question when it can't tell. Returns the run id to follow. Administrator access required.

## merchants

- [`merchants.confirm`](https://app.getoatmilk.com/docs/api/merchants.confirm.md) — Confirm what Oatmilk filled in for a merchant, optionally correcting displayName, websiteDomain, description, industry or kind in edits. Confirmed and corrected fields belong to the person and are never overwritten by a later lookup. Needs the merchant key and an idempotency key; pass expectedRevision from merchants.get to detect changes.

- [`merchants.enrich`](https://app.getoatmilk.com/docs/api/merchants.enrich.md) — Look a merchant up on the web and fill in its profile: what it is, its website and industry, each backed by a quote from a page. Pass key for one merchant, or leave it out to look up the next businesses that were never looked up, up to the organization's limit. Runs in the background and returns a run id. Only the merchant's name is sent to the search; never amounts or who paid. Category changes are suggestions for a person to approve.

- [`merchants.get`](https://app.getoatmilk.com/docs/api/merchants.get.md) — Read one merchant by its key: the profile, monthly spend per currency, the five latest transactions, the web pages the profile was read from, and any category suggestion waiting for review. Finance access required.

- [`merchants.list`](https://app.getoatmilk.com/docs/api/merchants.list.md) — List the merchants the organization paid, with what Oatmilk knows about each (description, industry, website, kind), spend per currency net of refunds over the last 12 months or from/to dates, last paid date, category with its source (rule, history or confirmed) and whether it needs a look. Names written differently, such as "Slack Technologies, LLC" and "SLACK.COM", are one merchant. Filter with search or filter=needs_look. Finance access required.

## merchants.settings

- [`merchants.settings.get`](https://app.getoatmilk.com/docs/api/merchants.settings.get.md) — Read whether new merchants are looked up automatically and how many web searches one run may use.

- [`merchants.settings.update`](https://app.getoatmilk.com/docs/api/merchants.settings.update.md) — Turn automatic merchant lookups on or off and set the most web searches one run may use (1 to 25). Needs the current revision after the first save. Administrator access required.

## places

- [`places.search`](https://app.getoatmilk.com/docs/api/places.search.md) — Search for a place or an address by name: pass query (up to 120 characters) and optionally near, the point the results should lean toward, as {lat, lon} or "lat,lon". Returns up to five results from OpenStreetMap, each with a label, an address, lat and lon; a person then saves one with entries.place.set. Run it only when a person submits a search, never while they type. Each person gets 30 new lookups an hour, and only the words searched leave Oatmilk.

## places.settings

- [`places.settings.get`](https://app.getoatmilk.com/docs/api/places.settings.get.md) — Read whether Oatmilk looks for the location of older card purchases in the background: backfill, on by default. It places up to 20 purchases from the last 120 days every five minutes and asks a person only when it cannot tell.

- [`places.settings.update`](https://app.getoatmilk.com/docs/api/places.settings.update.md) — Turn the background search for the location of older card purchases on or off with backfill (true or false) and an idempotencyKey. Turning it off never removes a place already saved. Administrator access required.

## receipt.tax

- [`receipt.tax.confirm`](https://app.getoatmilk.com/docs/api/receipt.tax.confirm.md) — Confirm GST/HST on a receipt or bank purchase, including an explicitly verified zero, with current revision, original source reason and idempotency key. Generic taxes remain separate; original printed components are preserved.

## reconciliation

- [`reconciliation.close`](https://app.getoatmilk.com/docs/api/reconciliation.close.md) — Explicitly close an account period after its opening, movement and closing balances reconcile. Finance access required; reopening needs an administrator and the accounting:admin scope (reconciliation.reopen).

- [`reconciliation.createEntry`](https://app.getoatmilk.com/docs/api/reconciliation.createEntry.md) — Create an entry from an imported bank transaction with an explicit type and optional category. Reuses existing entries on retry.

- [`reconciliation.list`](https://app.getoatmilk.com/docs/api/reconciliation.list.md) — List reconciliation records and unmatched items using account and date filters.

- [`reconciliation.match`](https://app.getoatmilk.com/docs/api/reconciliation.match.md) — Allocate a bank transaction to an entry with entryId, transactionId, amountMinor in the receipt currency, expectedRevision and idempotencyKey. Cross-currency matches also require bankAmountMinor, exchangeRate (bank major units per receipt major unit), exchangeRateDate and exchangeRateSource. Finance must review foreign-exchange matches explicitly.

- [`reconciliation.reopen`](https://app.getoatmilk.com/docs/api/reconciliation.reopen.md) — Reopen a closed accounting period with an audited administrator reason.

- [`reconciliation.split`](https://app.getoatmilk.com/docs/api/reconciliation.split.md) — Split an entry among categories using exact minor-unit amounts, revision and idempotency key.

- [`reconciliation.unmatch`](https://app.getoatmilk.com/docs/api/reconciliation.unmatch.md) — Remove an allocation using allocationId, expectedRevision and idempotencyKey. Finance only, with audit history.

## reimbursements

- [`reimbursements.approve`](https://app.getoatmilk.com/docs/api/reimbursements.approve.md) — Approve up to 100 submitted reimbursement claims in one atomic review, recording receipt validity and whether the claimant was an employee or officer at purchase for GST/HST treatment.

- [`reimbursements.bindRecipient`](https://app.getoatmilk.com/docs/api/reimbursements.bindRecipient.md) — Bind an existing Wise recipient to an active member after verifying its name, currency and business profile. No bank details are returned.

- [`reimbursements.candidates`](https://app.getoatmilk.com/docs/api/reimbursements.candidates.md) — For one outgoing bank transfer, list each active member with their approved unpaid claims in the transfer's currency and the exact set of claims that adds up to the transfer, when there is exactly one. Read only; linking still uses reimbursements.link.

- [`reimbursements.claimPurchase`](https://app.getoatmilk.com/docs/api/reimbursements.claimPurchase.md) — Create a personal expense claim for an active member from an existing unallocated receipt purchase, with its current revision, exact original evidence and explicit confirmation of who paid. Never creates or changes the expense.

- [`reimbursements.completePayment`](https://app.getoatmilk.com/docs/api/reimbursements.completePayment.md) — Complete an awaiting-receipts bank reimbursement only with approved original receipt purchases for the same member, currency and exact total, using current payment, bank and entry revisions.

- [`reimbursements.forEntry`](https://app.getoatmilk.com/docs/api/reimbursements.forEntry.md) — Read the reimbursement claim and status for one purchase, if present. Members can read only their own.

- [`reimbursements.get`](https://app.getoatmilk.com/docs/api/reimbursements.get.md) — Read one reimbursement claim and its purchase and payment status. Members can read only their own.

- [`reimbursements.identify`](https://app.getoatmilk.com/docs/api/reimbursements.identify.md) — Classify one historical Wise transfer against approved member claims. A dry run returns evidence; apply links only one exact named payee and claim match.

- [`reimbursements.link`](https://app.getoatmilk.com/docs/api/reimbursements.link.md) — Link an existing outgoing bank transfer to approved expense claims with the same member, currency and exact total. The bank entry becomes a transfer, not another expense.

- [`reimbursements.list`](https://app.getoatmilk.com/docs/api/reimbursements.list.md) — List reimbursement claims and their submitted, approved, rejected, prepared, funded, paid or returned status. Members see only their own claims; finance can review organization claims.

- [`reimbursements.matchPayment`](https://app.getoatmilk.com/docs/api/reimbursements.matchPayment.md) — Match a funded Wise reimbursement to its imported transfer using Wise's exact transfer reference and source amount. The bank entry becomes a transfer.

- [`reimbursements.prepare`](https://app.getoatmilk.com/docs/api/reimbursements.prepare.md) — Prepare one Wise reimbursement for approved claims belonging to the same member and currency. Preparation never sends funds.

- [`reimbursements.recipients`](https://app.getoatmilk.com/docs/api/reimbursements.recipients.md) — List verified Wise recipient bindings for members without exposing account details.

- [`reimbursements.recordPayment`](https://app.getoatmilk.com/docs/api/reimbursements.recordPayment.md) — Record an existing untouched outgoing bank payment to an explicitly confirmed active member as a reimbursement transfer awaiting receipt-backed claims. Never invents purchases or tax and never sends money.

- [`reimbursements.refreshRecipient`](https://app.getoatmilk.com/docs/api/reimbursements.refreshRecipient.md) — Refresh the verified Wise recipient on an unsent prepared reimbursement after the recipient binding changes. Requires the payment revision and never sends funds.

- [`reimbursements.reject`](https://app.getoatmilk.com/docs/api/reimbursements.reject.md) — Reject a submitted reimbursement with a reason and expected revision.

- [`reimbursements.send`](https://app.getoatmilk.com/docs/api/reimbursements.send.md) — Send one prepared Wise reimbursement for approved claims belonging to one member and currency. Requires a current administrator, the accounting:admin integration scope, the payment's current revision and an idempotency key. A real Wise payout may occur; a sidebar agent asks the person who started its chat to approve this action. Never auto-sends.

- [`reimbursements.submit`](https://app.getoatmilk.com/docs/api/reimbursements.submit.md) — Submit a reimbursement claim for a personally paid expense from your own original receipt. Oatmilk never duplicates the expense; check its status with reimbursements.list, reimbursements.get or reimbursements.forEntry.

- [`reimbursements.syncPayment`](https://app.getoatmilk.com/docs/api/reimbursements.syncPayment.md) — Read a previously funded Wise reimbursement status and update the claim only when Wise confirms payout or return. Never sends funds.

## statements

- [`statements.download`](https://app.getoatmilk.com/docs/api/statements.download.md) — Get a short-lived private link to a statement file by id. format original (the default): the unchanged original, an uploaded or Wise statement PDF or photo (pass inline: true to open it in the browser) or a CSV or Wise sync export. format pdf: a PDF of it, the original when it is one, otherwise a PDF Oatmilk renders from Wise's statement data, the CSV's lines or the photo, labelled as prepared by Oatmilk and kept for later downloads. Only statement files can be opened this way. Read-only.

- [`statements.lines`](https://app.getoatmilk.com/docs/api/statements.lines.md) — Read statement lines. With id: the lines Oatmilk read from that statement file, whether they were checked against its period and its opening and closing balances (verified), whether they are in the books (booked), and the reason when they were not. With accountId, from and to (up to 400 days): the account's lines in the books for those dates, each with the id of a checked statement that covers its date (verifiedBy, or null), and the statement files of that period. Amounts are signed integer strings in minor units of the account's currency; money out is negative. Read-only.

- [`statements.list`](https://app.getoatmilk.com/docs/api/statements.list.md) — List the original statement files Oatmilk keeps (uploaded PDF and photo statements, Wise's own monthly statement PDFs, and CSV exports), each with its account, bank, last four digits, period, balances and status: queued, reading, imported (with how many lines were new and how many were already in the books), review (with its plain reason and reasonCode; a statement waiting on its account also has suggestedAccountId, the likeliest existing account, and newAccount, an account drafted from the statement with name, provider, currency, lastFour and accountType, when its number isn't saved on any account; reasonCode ACCOUNT_NEW means no account Oatmilk has could be it), duplicate (of which statement), kept or failed. Also says, for every account and month, whether a statement covers the whole month (statement), part of it (partial), only lines synced from Wise (feed), nothing (missing) or a time before the account's first activity (before). Each file also says whether a PDF can be downloaded (pdf: original, or rendered by Oatmilk from Wise's statement data, a CSV or a photo), how its lines were read (readWith: vision, or text for a reading from the PDF's text layer made before vision), the reader's own warnings, a person's mark (flagged with a note, or checked) and checks: why it waits for a person (review, failed, flagged, old_reader, unsure). Wise sync data is listed once per account and window (the newest copy). Filter with from and to (up to 36 months; the last 12 when left out), or allPeriods: true to find files across the entire saved history, accountId or accountIds (up to 50), includeCoverage: false for only the file list without account-month coverage (coverageIncluded: false and empty month grids; omitted or true retains full coverage), bank, status (or attention for review and failed, or check for every file that waits for a person; toCheck counts them), search, limit and offset. Read-only.

- [`statements.review`](https://app.getoatmilk.com/docs/api/statements.review.md) — Decide what happens to uploaded statements, with idempotencyKey, decision and either id with expectedRevision or items (up to 100 of { id, expectedRevision }). assign (with accountId) checks the saved reading again for that account without reading the file, and with remember: true also saves the statement's account number and cardholders' cards on that account (never one already on another account) and checks the other statements waiting on it again; new_account (administrators only, with the accounting:admin scope for API keys) adds the account the statement is for once, from the first statement's newAccount with any of name, provider, currency, lastFour and accountType in newAccount overriding it, saves its last four digits so later statements match it, assigns every named statement to it, checks every other statement waiting on that account again, and answers with the account and how many statements it is checking (rechecking); read_again reads the file again (model: zai/glm-5.3-flash by default, or openai/gpt-6-luna, google/gemini-3.8-flash or openai/gpt-6.1-sol) and reads the account number, each cardholder's card and every line afresh; an imported statement keeps its account; keep keeps a statement that needs review as the original without importing its lines; flag (with an optional note) puts it in front of a person; unflag removes the flag; confirm records that a person checked it was read correctly. Nothing is booked unless the lines add up to the statement's balances, and an imported statement's account can't change here. With items, the answer lists each statement changed and each one skipped with why.

## summaries

- [`summaries.get`](https://app.getoatmilk.com/docs/api/summaries.get.md) — Read the separately generated purchase summary and supporting source references. Never treats a summary as financial evidence.

- [`summaries.update`](https://app.getoatmilk.com/docs/api/summaries.update.md) — Edit, dismiss or retry a purchase summary independently of receipt processing and human notes, with its current revision and idempotency key.

## tags.ai

- [`tags.ai.list`](https://app.getoatmilk.com/docs/api/tags.ai.list.md) — List what the project classifier suggested for a project (tagId, optional verdict likely or ask) that nobody has accepted or dismissed yet: each transaction's id, date, merchant, amount, currency and the classifier's probability. Accept with accounting_entries_tags_set add, or say no with dismiss.

- [`tags.ai.run`](https://app.getoatmilk.com/docs/api/tags.ai.run.md) — Ask the project classifier which transactions belong to a project, with tagId, idempotencyKey, optional limit (1 to 100, default 40) and recheck (look again at transactions it already answered). It reads transactions in the project's dates (and the 30 days before), or for a project without dates those that mention its name, other names or keywords, and uses the project's description, keywords and Notion page text. Likely matches become suggestions; unsure ones become questions (accounting_tags_ai_list verdict ask). A sure match tags a transaction by itself only while Autopilot is on and may finish work, for a project with a start and end date around an open transaction with no tag, dated on or after the project was set up; earlier transactions only get suggestions. An answer without probabilities counts as unsure. Returns counts.

## tags

- [`tags.create`](https://app.getoatmilk.com/docs/api/tags.create.md) — Create a project tag with name and idempotencyKey, and optionally parentId (a group; groups are one level deep), color (gray, red, orange, amber, green, teal, blue, purple or pink), description, aliases (other names people write), startsOn/endsOn (the event window) and budgetMinor with budgetCurrency. Active tag names are unique.

- [`tags.delete`](https://app.getoatmilk.com/docs/api/tags.delete.md) — Delete a project tag that was never used, with id, expectedRevision and idempotencyKey. A tag on any transaction, or holding other tags, can't be deleted: archive it or merge it instead.

- [`tags.get`](https://app.getoatmilk.com/docs/api/tags.get.md) — Get one project tag with the tags inside it, its totals, profit and loss by category, a monthly timeline and the merchant rules Oatmilk learned for it. A group includes the tags inside it, counting each transaction once.

- [`tags.list`](https://app.getoatmilk.com/docs/api/tags.list.md) — List project tags (which event or program a transaction is for): name, group (parent_id, one level deep), color, description, other names, event window (starts_on, ends_on), budget, archived state, the caller's last_used_at, and for finance spend, income, net and transaction counts by currency. A group's rollup counts each transaction once. Pass includeArchived to include archived tags. Contributors see active tags without totals or budgets.

- [`tags.merge`](https://app.getoatmilk.com/docs/api/tags.merge.md) — Merge one project tag into another with sourceId, targetId, the source's expectedRevision and idempotencyKey: every transaction tagged with the source gets the target instead (once), learned rules and the tags inside a merged group move too, and the source is archived. The audit records every transaction moved.

- [`tags.report`](https://app.getoatmilk.com/docs/api/tags.report.md) — Profit and loss by project tag for optional from/to dates and currency: spend, income and transaction counts per tag and per group, the deduplicated tagged total, untagged transactions, and overlap (transactions tagged to more than one project, which count in each). Currencies stay separate.

- [`tags.suggest`](https://app.getoatmilk.com/docs/api/tags.suggest.md) — Suggest project tags for up to 100 entries (entryIds) from each tag's event window, learned merchant rules and notes or descriptions that mention the tag or its other names. Each suggestion has a score from 0 to 100 and its reasons. Suggestions don't count in totals until accepted with accounting_entries_tags_set.

- [`tags.update`](https://app.getoatmilk.com/docs/api/tags.update.md) — Change a project tag with id, expectedRevision and idempotencyKey: rename, recolor, describe, set other names, move to a group or out of one (parentId null), set or clear the event window and budget, or archive and restore it (archived true or false). Archiving a group archives the tags inside it; restoring the group restores them.

## tags.notion

- [`tags.notion.link`](https://app.getoatmilk.com/docs/api/tags.notion.link.md) — Link a project to a Notion page or database row with page, sourceOfTruth (notion: name, dates, status, budget and description come from Notion; oatmilk: Oatmilk writes them to Notion) and idempotencyKey. Pass tagId (and optionally the project's expectedRevision) to link an existing project, or leave it out to create a project from the page (optionally parentId and color). For a database row, properties is required: the Notion property for each of dates, status, budget and description, or null to leave it out (accounting_tags_notion_preview suggests them; nothing is mapped silently). Linking syncs once straight away and never empties a filled field on either side: where one side is empty the filled value is kept, reads the page text as context for the classifier, and asks the classifier to suggest transactions for the project.

- [`tags.notion.preview`](https://app.getoatmilk.com/docs/api/tags.notion.preview.md) — Read a Notion page or database row before linking it to a project: supply page (a notion.so link or page ID) and, for an existing project, tagId. Returns its title, whether it is a row and in which database, suggested properties for dates, status, budget and description with every property that could hold each (choices) and the value each would read (propertyValues), the start of the page text the classifier would use, any problems, and with tagId the project's own values and what the first sync would change for each source of truth (firstSync). Review it, then pass the properties you chose to accounting_tags_notion_link.

- [`tags.notion.resolve`](https://app.getoatmilk.com/docs/api/tags.notion.resolve.md) — Resolve a sync conflict on one field (name, dates, status, budget or description) with tagId, field, keep (notion writes Notion's value to Oatmilk; oatmilk writes Oatmilk's value to Notion) and idempotencyKey. Then syncs the project.

- [`tags.notion.sync`](https://app.getoatmilk.com/docs/api/tags.notion.sync.md) — Sync a linked project with Notion now, with tagId and idempotencyKey (linked projects also sync about hourly). Fields change only on the side that isn't the source of truth. A field the other side changed since they last agreed is not overwritten: it is returned in project.conflicts for a person to resolve with accounting_tags_notion_resolve.

- [`tags.notion.unlink`](https://app.getoatmilk.com/docs/api/tags.notion.unlink.md) — Stop syncing a project with Notion, with tagId and idempotencyKey. The project keeps its current name, dates, budget and description; nothing changes in Notion.

## tags.project

- [`tags.project.update`](https://app.getoatmilk.com/docs/api/tags.project.update.md) — Set a project tag's status (planned, active or completed) or keywords (up to 20 words the classifier looks for) with tagId, idempotencyKey and optionally expectedRevision (the project's revision from tags.get). Changing keywords asks the project classifier to look at its transactions again. When the project syncs from Notion, a status set here that differs from Notion's is a conflict to resolve with accounting_tags_notion_resolve.

## transactions

- [`transactions.correct`](https://app.getoatmilk.com/docs/api/transactions.correct.md) — Correct an unallocated CSV bank row with its revision, reason and idempotency key. Original statement evidence and previous import identities remain preserved. Closed periods and Wise rows cannot be edited.

- [`transactions.get`](https://app.getoatmilk.com/docs/api/transactions.get.md) — Get one imported bank or card transaction by id: amount, date, account, statement text, what it is matched to (allocations with their transactions and entries), and the facts the bank supplied such as merchant, card, cardholder and exchange details.

- [`transactions.list`](https://app.getoatmilk.com/docs/api/transactions.list.md) — Search imported bank and card transactions with search text, accountId, currency, from/to dates, allocation (matched, unmatched or partial), direction (in or out), minAmount/maxAmount in minor units, limit and offset. Each line includes allocatedMinor and the entry ids it is matched to.

- [`transactions.restore`](https://app.getoatmilk.com/docs/api/transactions.restore.md) — Restore a previously reversed CSV bank row with a revision check and audited reason.

- [`transactions.reverse`](https://app.getoatmilk.com/docs/api/transactions.reverse.md) — Exclude an erroneous unallocated CSV bank row with an audited reason. Preserves evidence and duplicate detection.

## transactions.documents

- [`transactions.documents.download`](https://app.getoatmilk.com/docs/api/transactions.documents.download.md) — Get a short-lived download for a document Oatmilk fetched from the bank provider for a transaction, such as Wise's transfer confirmation for a contractor payment. Ids are listed on entries.get as providerDocuments.

## trips

- [`trips.create`](https://app.getoatmilk.com/docs/api/trips.create.md) — Create a trip with title, startDate, optional endDate and placeLabel, and an idempotencyKey. Finance access required.

- [`trips.get`](https://app.getoatmilk.com/docs/api/trips.get.md) — Read one trip by id: its summary, every transaction in it with its role (lodging, hold, room_charge, meal, transport or other), confidence and note, and the place pins to draw on a map. Contributors see only their own transactions in it.

- [`trips.linkEntry`](https://app.getoatmilk.com/docs/api/trips.linkEntry.md) — Put a transaction in a trip with tripId, entryId, an optional role (lodging, hold, room_charge, meal, transport or other) and an idempotencyKey. A transaction is in one trip at a time; linking it here moves it. Contributors can link only transactions they own.

- [`trips.list`](https://app.getoatmilk.com/docs/api/trips.list.md) — List trips: purchases made while travelling, grouped by stay, with title, place, dates, status (upcoming, active or past), how many transactions belong to each, what it cost per currency (holds left out, hotel credits taken off) and its map centre. Contributors see only trips that include a transaction they own.

- [`trips.unlinkEntry`](https://app.getoatmilk.com/docs/api/trips.unlinkEntry.md) — Take a transaction out of a trip with tripId, entryId and an idempotencyKey. Oatmilk never puts it back. Contributors can unlink only transactions they own.

- [`trips.update`](https://app.getoatmilk.com/docs/api/trips.update.md) — Rename a trip or change its dates or place with id, the fields to change and an idempotencyKey. A trip a person edited is never rewritten by Oatmilk. Finance access required.
