Connectors and webhooks
Webhooks, Wise, Notion, Google Drive and other data sources.
59 actions
Give an AI assistant only these actions with the connectors MCP toolset.
https://app.getoatmilk.com/api/mcp?toolset=connectorsconnectors.credentials
- POST
connectors.credentials.removeDisconnect organization-scoped Stripe, Wise, Notion or Google Drive credentials from the administrator dashboard. Existing accounting records remain. Requires expectedRevision and idempotencyKey. - POST
connectors.credentials.saveStore organization-scoped Stripe, Wise, or Notion credentials from the administrator dashboard. Values are encrypted server-side, never returned, and replace the prior credentials after verification. Requires idempotencyKey and the current revision when replacing.
connectors
- GET
connectors.getRead one connector's status and non-secret configuration. For Notion this includes the mapped invoice, customer, vendor, and contact databases, property and status mappings, sync settings, and the last sync summary. - GET
connectors.listList available connectors grouped as financial (Stripe, Wise), data (Notion), and communication (email delivery), with connection status and capabilities. Organization admins manage provider credentials in Settings; secret values are never returned. - POST
connectors.testCheck a connector's connection now and record the result. For Notion this verifies the integration token and returns the workspace and integration name. - POST
connectors.updateSave Notion connector settings: database mappings (data source, property mapping, status option mapping) for invoices, customers, vendors, and contacts, and sync settings. Mappings are validated against the live Notion schema. Supply idempotencyKey and optionally expectedRevision.
connectors.googleDrive
- POST
connectors.googleDrive.connectStart connecting the company's Google Drive with read-only access: returns url, the Google consent page for the admin to open while signed in to Oatmilk (only the admin who asked can finish it, within ten minutes). Optional returnTo is an Oatmilk path to come back to. Once connected, import files and folders with dataSources.import (source google_drive; target company_documents to file incorporation papers and fill the company profile). Disconnect with connectors.credentials.remove (id google_drive). - GET
connectors.googleDrive.statusRead whether Google Drive can be connected here (configured), whether it is connected, and the Google account that connected it. Never returns a token.
connectors.wise
- POST
connectors.wise.signingKey.createCreate a signing key for Wise's strong customer authentication from the administrator dashboard. The private half is saved encrypted with the Wise credential; only the public half is returned, to add in Wise (Settings › API tokens › Manage public keys). A saved key is replaced only with replace true, because payouts sign with the same key. Requires the credential's expectedRevision and idempotencyKey. - GET
connectors.wise.statementAccessRead whether Wise's monthly statement PDFs reach Oatmilk: the state (working, waiting, needs a signing key, key not in Wise, refused, not found), how many are kept, when Oatmilk last approved Wise's strong customer authentication and when Wise will ask again (about every 90 days; Oatmilk approves it automatically with the saved signing key), the last refusal, and the saved key's public half to add in Wise. The private key is never returned. - POST
connectors.wise.statements.checkAsk Wise for statement PDFs now without waiting out a refusal: one month per synced balance, oldest missing first, signing Wise's approval request with the saved key when Wise asks. Returns what was kept and the statement access status. Supply idempotencyKey.
dataImports
- POST
dataImports.commitStart an import in the background with the mapping and decisions: create or choose customers and contractors, link or skip invoice numbers already in Oatmilk, and import or skip possible duplicate payments. Invoices keep their original numbers without using the invoice sequence, paid rows get their payment, the first PDF becomes the invoice's PDF, and Notion rows are linked for sync. Contractor payments are recorded as paid outside Wise; no money is sent and nobody is emailed. Rows already imported are skipped. Returns the import to follow with dataImports.get. Supply idempotencyKey. - GET
dataImports.definitionsList what can be imported from a connected database (invoices and contractor payment history): each field with its type, whether it's required, and the kinds of columns it accepts, plus the databases imported from recently. - GET
dataImports.filesGet short-lived download links for the files an imported invoice came with, and where it was imported from. - GET
dataImports.getRead one import with its progress, counts, the customers or contractors it added, and each row's outcome with a link to what it created. - GET
dataImports.historyList imports, newest first, with their source database, status and counts. Filter by target or database. - GET
dataImports.previewRead every row of the database with a column mapping and group the rows: ready, needs a decision (a new or ambiguous customer or contractor, an invoice number already in Oatmilk, or a possible duplicate payment), already imported, can't import (with the reason), or left out. Nothing is saved. Payment and tax columns are never read, and what they hold is hidden anywhere else in the preview. - POST
dataImports.resumeContinue an import that paused before it finished, for example after a time limit. It continues as the person who started it. Supply idempotencyKey. - GET
dataImports.suggestSuggest a column of a connected database (Notion) for each field of an import target, with a sample value per column, the status options found, and the mapping remembered for that database. Supply target, source and databaseId. A column whose name says it holds payment or tax details is marked sensitive, has no sample or options, and is never suggested or imported. - POST
dataImports.undoUndo a contractor payment import: the payouts it recorded are cancelled when they haven't changed since, and the rows can be imported again. Imported invoices are voided from each invoice instead. Supply reason and idempotencyKey.
dataSources
- GET
dataSources.filesList the files attached to a row or page: files in file columns and files embedded in the page. For google_drive, itemId is a folder (its files, partial when there are more than 200) or a file (itself); Google Docs, Sheets and Slides are listed as PDFs. With target, files already imported there are marked. File download addresses are never returned. - POST
dataSources.importFilesImport up to 25 files from a data source into Oatmilk: receipts (processed like uploaded receipts), tax_sources (supporting originals, no expense), signing_files (documents to send for signature), executed_agreements (agreements signed elsewhere; targetOptions parties, executedOn, title) contractor_agreements (draft documents; optional targetOptions contractorId, expectedContractorRevision and title create the draft agreement) or company_documents (incorporation papers and other company records: each is filed through intake as a company record, read, and fills the company profile's empty fields; the record is the document id). Sources are notion and google_drive. Each file is downloaded server-side, checked against its target's size limit and file types by its contents, and run through that target's usual upload path. Importing the same file into the same place again returns the existing record. Returns a result for each file. Supply idempotencyKey. - GET
dataSources.listList data sources files and records can be imported from (Notion, and Google Drive once an admin connects it with connectors.googleDrive.connect; OneDrive is listed as not available yet), with connection status, pinned databases and databases mapped in Settings › Connectors. - POST
dataSources.pinPin or unpin a database for everyone in the workspace so it appears first when importing. Supply source, databaseId, pinned and idempotencyKey. - GET
dataSources.readTextRead the text of a CSV or plain-text file attached to a row or page (up to 2 MB, UTF-8), for example a bank statement to import with imports.preview and imports.commit. Nothing is stored. - GET
dataSources.resolveOpen a pasted link or ID from a data source (for Notion: notion.so, app.notion.com, notion.site links, database and page IDs; for Google Drive: drive.google.com and docs.google.com links to files and folders, or a Drive ID). Returns whether it is a database or a page and the database ID to read rows from. - GET
dataSources.rowsRead rows of a database with readable, typed values for every column: text, numbers with their format, dates, options, people, related page titles, checkboxes, links and attached files. Supports search, sort by a column, only rows with files, and cursor paging. With target, files already imported there are marked. File download addresses are never returned. Columns whose names say they hold payment or tax details (bank, account, transit, institution and routing numbers, IBAN, SWIFT/BIC, Wise or Interac addresses, SIN, SSN, business or tax numbers) read as [hidden], what they hold is hidden anywhere else in the rows too, and they're never searched or sorted by. - GET
dataSources.schemaRead a database's columns with their types, options, number formats (and the currency they imply), related databases, and the columns suggested for a first view. Columns whose names say they hold payment or tax details list no options and can't be sorted or searched by. - GET
dataSources.searchSearch a data source for databases and pages shared with Oatmilk, most recently edited first. Supply source, optional query, kind (database, page, file or any), cursor and limit. For google_drive it searches file and folder names across My Drive and shared drives (kind file leaves folders out; Drive has no databases).
notion.dataSources
- GET
notion.dataSources.getRead a Notion data source's properties and suggested mappings for each role (invoices, customers, vendors, contacts), including suggested status option mappings. - GET
notion.dataSources.queryPreview rows of a Notion data source with simplified property values, optionally filtered by a title search. Paged with cursor. Properties whose names say they hold payment or tax details (bank, account, transit, institution and routing numbers, IBAN, SWIFT/BIC, Wise or Interac addresses, SIN, SSN, business or tax numbers) read as [hidden], and what they hold is hidden anywhere else in the rows too.
notion.invoices
- POST
notion.invoices.importLink existing Notion invoice rows to Oatmilk invoices. Status differences become suggestions for review; nothing is overwritten. Supply selections of pageId and invoiceId, plus idempotencyKey. - GET
notion.invoices.importPreviewPreview existing rows in the mapped Notion invoice database with the Oatmilk invoice each one most likely matches, whether it's already linked, and whether the statuses differ.
notion.links
- POST
notion.links.confirmConfirm a suggested Notion link. Any other confirmed link for the same record and database is replaced. Requires expectedRevision and idempotencyKey. - POST
notion.links.createLink an Oatmilk account, invoice, or contractor to a Notion page by page ID or pasted link. Links created by a person are confirmed unless status is proposed. Supply idempotencyKey. - GET
notion.links.listList links between Oatmilk records (accounts, invoices, contractors) and Notion pages, with their status (suggested, confirmed, declined), method, match reasons, and sync state. - POST
notion.links.rejectDecline a suggested Notion link so it isn't suggested again. Requires expectedRevision and idempotencyKey. - POST
notion.links.removeRemove a Notion link. The Notion page itself is not changed. Requires expectedRevision and idempotencyKey.
notion
- GET
notion.lookupFind likely Notion pages for an Oatmilk account, invoice, or contractor in the mapped databases. Candidates are ranked by name, email, website domain, invoice number, amount, and dates, with the reasons for each match. Nothing is linked until a person confirms. - GET
notion.resolveLinkResolve a pasted Notion link or ID (notion.so, app.notion.com, notion.site, collection://) to the page, database, or data source it refers to. - GET
notion.searchSearch Notion databases (data sources) or pages that are shared with the integration, most recently edited first.
notion.sync
webhooks.deliveries
- GET
webhooks.deliveries.listList webhook deliveries with status, attempts, response code, duration, a redacted response excerpt, and the signed payload. Filter by endpoint, status, or event type. - POST
webhooks.deliveries.retryQueue a failed or cancelled delivery to be sent again with the same event payload. Requires expectedRevision and idempotencyKey. - GET
webhooks.deliveries.statsSummarize webhook deliveries of real events (not tests) for the last 1, 7 or 30 days: how many were delivered, failed or are still waiting, median and 95th percentile response times, deliveries per day, each endpoint's counts, the busiest event types and the most common failure reasons.
webhooks.endpoints
- POST
webhooks.endpoints.archiveRemove an endpoint and cancel its queued deliveries. Delivery history is kept. Requires expectedRevision and idempotencyKey. - POST
webhooks.endpoints.createCreate an outgoing webhook endpoint with an https URL on the standard port (443) or 8443 and event subscriptions (exact names, group wildcards such as invoice.*, or *). Private and local network addresses are refused. The signing secret is returned once; replaying the same idempotencyKey returns the same response to the same person. Supply idempotencyKey. - GET
webhooks.endpoints.listList outgoing webhook endpoints with their subscribed events, status, recent delivery counts, and the last four characters of each signing secret. - POST
webhooks.endpoints.rotateSecretReplace an endpoint's signing secret. The new secret is returned once and signs every later delivery. Requires expectedRevision and idempotencyKey. - POST
webhooks.endpoints.updateChange an endpoint's URL, description, events, or turn it on or off. Turning a disabled endpoint back on resets its failure count. Requires expectedRevision and idempotencyKey.
webhooks.events
webhooks
wise
- GET
wise.profilesDiscover eligible Wise profiles using backend read-only credentials. - GET
wise.statusRead safe Wise synchronization readiness and last successful sync. - POST
wise.syncSynchronize configured Wise statements with durable history and duplicate handling, and keep Wise's own monthly statement PDF for each balance once the month is over (each month once). Optional from and to fetch that inclusive history period (up to 400 days), including quiet balances, without changing the normal sync cursor. Each run fetches up to three monthly windows; remainingWindows and nextFrom say what remains. Pass nextFrom as from with the same to to continue. Future end dates stop at the database cutoff accepted for that request. Retrying the same key resumes its frozen original inputs; completed retries return the saved response. Use a new key for the next history pass or a new sync. Receipt jobs may be queued with imported zero and continue in their own worker. Matching and Autopilot jobs are queued once per accepted sync; Autopilot classifies the new lines afterwards unless skipAi is true.
wise.receipts
- POST
wise.receipts.decideKeep saved fields or accept proved incoming merchant, canonical tax, and address values from an immutable Wise receipt review. Values come from the server. Requires exact review and entry revisions, fingerprint, reason, and idempotency key. Bank money and date use the existing correction workflow. - GET
wise.receipts.reviewCompare the previous Wise source, newly read evidence, and saved transaction using a private immutable review. Unknown tax stays distinct from confirmed zero. - GET
wise.receipts.statusRead scoped durable receipt-sync progress for one Wise purchase without starting provider work. - POST
wise.receipts.syncQueue a preserved, evidence-only read of receipts attached to this exact existing Wise purchase. Requires current entry revision and a stable idempotency key. Reviewed purchases are supported; closed purchases retain evidence without financial changes.