Administration
Company settings, people, API keys, email, runs and suggestions.
95 actions
Give an AI assistant only these actions with the admin MCP toolset.
https://app.getoatmilk.com/api/mcp?toolset=adminaccountant.access
accountant.changes
- GET
accountant.changes.listAccountants only: read the changes you asked the company to make and what was decided, newest first. Who decided is not shown. - POST
accountant.changes.requestAccountants with corrections access only: ask the company to attach an existing receipt to a bank record (attach_receipt with entryId and receiptEntryId), match a receipt to a same-currency bank payment (settle_match with entryId and transactionId), or check which contractor a payment belongs to (contractor_attribution with contractorId and transactionId), with a reason and idempotency key. Nothing changes until a company administrator approves it; payouts, agreements and settings are never offered.
accountant.comments
- POST
accountant.comments.createAccountants with comment access only: ask a question on one transaction (entry) or receipt with targetType, targetId, body and an idempotency key. The company is emailed a short grouped summary. - GET
accountant.comments.listAccountants with comment access only: read the questions and replies on one record (targetType and targetId), or the most recent ones on any record.
accountant.requests
accountant.slips
accountant.tax
accountant.welcome
accountants.access
accountants
- GET
accountants.activityRead an accountant's retained activity timeline (sign-ins, downloads, exports, requests, decisions, end-date changes and removal), newest first. Supply userId and optionally beforeId. - POST
accountants.inviteInvite an accountant by email with an access level (preset read, comment or prepare), an access end date (or null for no end date), optional name, firm and message, and an idempotency key. Returns the invitation and a private join link. Administrator access is required. MCP calls also require accounting:admin; the web agent asks for approval before changing outside access. Direct API requests cannot perform these access-granting actions. - POST
accountants.inviteManyInvite up to 10 people from one accounting firm in one go. Each person has their own email, name, access level (preset) and end date; the firm name and message are shared. Returns which invitations were sent and which failed, each with its private join link. Administrator access is required. MCP calls also require accounting:admin; the web agent asks for approval before changing outside access. Direct API requests cannot perform these access-granting actions. - GET
accountants.listList active and former accountants with their access, end dates and days left, plus pending invitations and access requests. Invitation links are never included. - POST
accountants.removeRemove an accountant now: ends access, revokes extra permissions and open requests, and removes the organization membership. Their history is kept. Requires userId, expectedRevision and idempotencyKey.
accountants.comments
- GET
accountants.comments.listList accountants' questions on transactions and receipts with the replies to each, newest first. Filter by status (active, open, answered, resolved, all) or by one record with targetType and targetId. Contributors never see these. - POST
accountants.comments.replyReply to an accountant's question with id, body and idempotencyKey. The accountant sees the reply and gets a short email. - POST
accountants.comments.resolveMark an accountant's question resolved with id, expectedRevision and idempotencyKey.
accountants.grants
accountants.invitations
- POST
accountants.invitations.linkReturn the private join link of a pending invitation again so it can be shared in your own message. Audited. Administrator access is required. MCP calls also require accounting:admin; the web agent asks for approval before changing outside access. Direct API requests cannot perform these access-granting actions. - GET
accountants.invitations.previewPreview the invitation email (subject, HTML and plain text) for an access level, end date, name and message before sending it. Sends nothing and contains no private link. - POST
accountants.invitations.resendEmail a pending accountant invitation again and restart its 14-day link window, with expectedRevision and idempotencyKey. Administrator access is required. MCP calls also require accounting:admin; the web agent asks for approval before changing outside access. Direct API requests cannot perform these access-granting actions. - POST
accountants.invitations.revokeRevoke a pending accountant invitation so its link stops working, with expectedRevision and idempotencyKey. - POST
accountants.invitations.updateChange a pending or expired accountant invitation: access level, end date, name, firm or message, with id, expectedRevision and idempotencyKey. Correcting the email address cancels the old link and sends a new invitation. Administrator access is required. MCP calls also require accounting:admin; the web agent asks for approval before changing outside access. Direct API requests cannot perform these access-granting actions.
accountants.requests
api_keys
- POST
api_keys.createCreate a scoped expiring API key within your current role and credential ceiling. The secret is returned once. - GET
api_keys.listList metadata for your API keys. Secret values are never returned. - POST
api_keys.revokeRevoke your API key; administrators may revoke organization keys. - POST
api_keys.rotateReplace your API key while preserving scope ceilings and revoking the original.
company
- POST
company.closePermanently close the company: delete its stored files, every record it has in Oatmilk, and the company itself with its memberships. It can't be undone; export the data first with company.export. confirmName must be the company's name (case doesn't matter). Only an administrator, with their own credential (the web app, or the terminal app or an API key), can close it; AI apps and Ask AI can't. The installation's own company can't be closed. Returns the counts of rows and files deleted and whether the company's sign-in organization was deleted. - POST
company.exportExport all of the company's data as one ZIP: manifest.json, data/<table>.json with every row the company has in every table, files/<bucket>/<path> with its stored files (receipts, emails, statements, agreements, invoices) and a README. Secret values (encrypted credentials and bank or tax details, sealed keys, one-time codes, private link tokens) are replaced with "[redacted]" and listed in redactedColumns. One download holds at most 50 MB: the records come first and files fill the rest; files that don't fit are listed with included false, and company.export.files gives a link for each. includeFiles false leaves files out (default true). Returns a link valid for 5 minutes, the counts of tables, rows and files, and how many files were skipped. Administrators only. - GET
company.getRead company identity, tax registrations, filing settings and source provenance. GST/HST dates require profile.gstHst.registered, frequency and yearEnd; null means not configured, not a permission failure. warnings identifies conflicting saved corporate fiscal year-ends that need administrator confirmation. - POST
company.updateUpdate company metadata and tax settings with the current revision and an idempotency key. Corporate annual returns remain distinct from tax periods.
company.export
developers.requests
developers
email.domain
- POST
email.domain.activateUse a custom domain only after its sending and receiving DNS records are verified. - POST
email.domain.configureStart verification of an organization-owned custom sending and receiving domain. - GET
email.domain.statusInspect the organization's custom email domain and the provider's public DNS records. - POST
email.domain.usePlatformReturn new outbound and receiving addresses to the default Oatmilk domains. - POST
email.domain.verifyAsk the email provider to verify the current custom domain's DNS records.
email.outbox
experiments
- GET
experiments.getRead the experimental features the signed-in person can try in this workspace (such as RTS mode, which shows the workspace as a 3D strategy game), whether they turned experimental mode on, which experiments they turned on, and the revision. Each person chooses for themselves; the platform decides which experiments are offered. - POST
experiments.updateTurn experimental mode on or off for the signed-in person (mode), or turn one experiment on or off (experiment with enabled). Only an experiment offered to this workspace can be turned on. Pass expectedRevision from experiments.get and an idempotencyKey. It never changes anyone else's choice.
identity
members
notifications.checklist
- POST
notifications.checklist.dismissMark a snooze reminder as seen for the signed-in member only. Requires an itemId and idempotencyKey. Repeated dismissal changes nothing. - GET
notifications.checklist.listList the signed-in member's unseen reminders that a snoozed checklist item returned. Only their own open items in this organization, at most ten from the past 30 days.
notifications.comments
- POST
notifications.comments.dismissMark one of the signed-in member's document comment notifications as read. Requires an idempotencyKey; other members' notifications cannot be changed. - GET
notifications.comments.listList the signed-in member's unread mentions and replies on organization documents, with a direct link to the comment thread.
notifications.joins
- POST
notifications.joins.dismissMark one join notice as seen for the signed-in member only. Requires an idempotencyKey. Dismissing twice, or a notice that isn't theirs, changes nothing. - GET
notifications.joins.listList the signed-in member's unseen notices that someone joined by an invitation (a contractor, an outside accountant or a team member): who joined, who invited them and a link to the person. Only the member's own notices, from the last 30 days, at most 10.
notifications.preferences
- GET
notifications.preferences.getRead the signed-in member's choice to get join notices by email and in Oatmilk. Both are on until they turn them off. - POST
notifications.preferences.updateTurn the signed-in member's join notices on or off, by email and in Oatmilk. Requires an idempotencyKey. It never changes another member's choice.
onboarding
- POST
onboarding.completeFinish or skip onboarding for the workspace with an idempotencyKey (skipped true when skipping). Finishing again keeps the first time. - GET
onboarding.inboxPromptWhether the signed-in member should see the optional read-only Gmail or Outlook connection suggestion, and which providers are configured. A connected inbox or this member's Not now answer hides it. - GET
onboarding.statusRead a new workspace's setup: whether onboarding is finished, the receipt address, its kind (company or personal), and which steps are done (company details, a bank account or connection, a first receipt or connected inbox, a teammate, and AI keys that cover decisions or Oatmilk's AI credits; a personal workspace has only the bank, receipt and AI steps).
onboarding.inboxPrompt
platform.admin
- GET
platform.admin.accessRequests.listPlatform administrators only: people who asked for access on the waitlist, newest first, with what they told us (email, name, company, role, size, website, kinds of financial data, banks, interests, notes) and the request's status and revision. status filters pending (default), approved, declined or all. - POST
platform.admin.accessRequests.reviewPlatform administrators only: approve or decline a waitlist request at its current revision. Approving emails the person a link to set up their workspace; platformAi lets their company use Oatmilk's AI credits instead of only its own keys. Declining sends nothing, and a declined request can be approved later. - GET
platform.admin.experiments.listPlatform administrators only: every experimental feature (such as RTS mode), who it is offered to (off, team for the platform's own workspace, or everyone), its Vercel flag key and that flag's value in Vercel Flags when the deployment is connected, plus the deployment-wide experimental-mode flag. People still turn each experiment on for themselves in Settings › Experimental. - POST
platform.admin.experiments.updatePlatform administrators only: offer one experiment to nobody (off), only the platform's own workspace (team) or every workspace (everyone). A Vercel flag set to off in Vercel Flags still keeps it off. Turning it off stops it at once for everyone who had it on. Pass expectedRevision from platform.admin.experiments.list. - GET
platform.admin.organizations.getPlatform administrators only: one workspace in God Mode with aggregate numbers only: its counts, its access (approved or paused, AI credits), which AI providers it brought keys for (never the keys), AI usage by feature and model, what kinds of actions it took in the period with how many of each, and the waitlist request it came from. - POST
platform.admin.organizations.updatePlatform administrators only: pause or resume a workspace (status approved or suspended) and turn Oatmilk's AI credits on or off for it (platformAi), at its current revision (0 for a workspace with no access record yet). The platform's own organization can't be changed. - GET
platform.admin.overviewPlatform administrators only (the platform's own organization): God Mode's overview. Signup mode, totals (workspaces, new ones, members, sign-ups, waiting requests, AI requests and cost) and every workspace with aggregate numbers only: members, transactions and receipts brought in, agreements, contractors, invoices, actions in the period, last activity, whose AI keys it uses and its AI usage and cost (AI Gateway's spend report when available, otherwise Oatmilk's own count). Never records, people or contents. days (1 to 90, default 30) sets the period.
platform.branding
- POST
platform.branding.confirmLogoVerify an uploaded logo's bytes and hash, then make it the organization letterhead logo. - GET
platform.branding.logoGet a short-lived link to the current organization logo. - POST
platform.branding.prepareLogoPrepare a private upload for the organization logo used on letterheads, agreements, and invoices. PNG or JPEG up to 2 MB.
platform.settings
- GET
platform.settings.getRead workspace preferences for invoicing numbers and defaults, document branding, compliance reminders, and the inbox AI models: which model reads each email and which gives the second opinion, and at what effort. - POST
platform.settings.updateUpdate invoicing numbering and defaults, letterhead text, compliance reminder preferences, and the inbox AI models, with a revision check. inboxAi.reading reads each email and its attachments into a draft; inboxAi.checking is the second opinion on anything left unclear. Each takes a model, one of openai/gpt-6.1-sol (GPT-6.1 Sol), openai/gpt-6-luna (GPT-6 Luna), google/gemini-3.8-flash (Gemini 3.8 Flash), zai/glm-5.3-flash (GLM-5.3 Flash), and a low, medium or high effort; null puts that step back on the recommended GPT-6 Luna at medium effort for reading and GPT-6 Luna at medium for the second opinion.
proposals
- POST
proposals.createSuggest a change to a record for someone to review. Nothing changes until the suggestion is approved. A newer suggestion for the same record and field replaces the older one. Supply subjectType, subjectId, field, proposedValue, reasoning, optional evidence, and idempotencyKey. - POST
proposals.decideDecline a suggested change, or approve it when a person is signed in to Oatmilk. API keys and agents can decline but can't approve; approving through them is refused with "Approve suggestions in Oatmilk." Approving applies the change through the normal audited action for that record, such as recording an invoice payment or recategorizing an entry. A partly paid suggestion without an amount needs paidAmountMinor. A failed or stale approval can be approved again or declined. Requires expectedRevision and idempotencyKey; an optional note is kept with the decision. - GET
proposals.getRead one suggested change with its reasoning, evidence links, and decision history. - GET
proposals.listList suggested changes to invoices, entries, mail, accounts, and Notion links, with the current and proposed values, plain-language reasoning, evidence, whether the evidence is newer or older, and status. Defaults to suggestions waiting for review.
runs
- GET
runs.getRead one run, or the latest run for a subject, with its ordered step events: steps started and finished, model calls, outputs, decisions, and errors. Use afterEventId to fetch only new events while a run is active. - GET
runs.listList AI and automation runs with their current step, status, and summary. Filter by kind (or a comma-separated kinds list), subject, or status. Contributors see only runs for their own submissions. - GET
runs.traceRead an authorized process trace with its stage timeline, logs, model metadata, and linked Workflow SDK run, steps, and events. Restricted mail remains visible only to a security administrator.
runs.workflows
- GET
runs.workflows.catalogList organization-owned Workflow SDK jobs and indicate which job sources are unavailable while a database update is pending. - GET
runs.workflows.getInspect an organization-owned Workflow SDK run with its steps, events, statuses, and redacted input and output. - GET
runs.workflows.listList organization-owned Workflow SDK jobs for receipts, mail, matching, Stripe, and accounting digest replies.
senders
settings
team.invitations
- POST
team.invitations.linkGet the private link of a pending team invitation, to share it another way. Only organization administrators can manage the team. MCP calls also require the accounting:admin scope; the direct API cannot send team invitations or remove members. - POST
team.invitations.resendEmail a pending team invitation again and give it another 14 days, with id, expectedRevision and idempotencyKey. Only organization administrators can manage the team. MCP calls also require the accounting:admin scope; the direct API cannot send team invitations or remove members. - POST
team.invitations.revokeCancel a pending team invitation so its link stops working, with source (oatmilk, or clerk for an invitation sent before Oatmilk sent its own), id, expectedRevision for an Oatmilk invitation, and idempotencyKey. Only organization administrators can manage the team. MCP calls also require the accounting:admin scope; the direct API cannot send team invitations or remove members.
team
- POST
team.inviteInvite a new team member by email with a role (admin, finance or contributor), an optional message and an idempotency key. Oatmilk emails them a private link when email is enabled; the result always includes a link to share and a delivery status. The link works for 14 days. Only organization administrators can manage the team. MCP calls also require the accounting:admin scope; the direct API cannot send team invitations or remove members. - GET
team.listList the team: everyone in the company's organization with their role and whether they can open Oatmilk, plus pending team invitations. Invitation links are never included.