Concepts
Authentication
API keys, sign-in tokens, permissions, roles and choosing a company.
Every request carries a credential in the Authorization header:
Authorization: Bearer oat_live_…Oatmilk accepts two kinds of credentials. Both work with the REST API and with MCP.
| Credential | Best for | How you get it |
|---|---|---|
| API key | Your own server, scripts and back-office jobs | Developers › API keys |
| OAuth token | Apps other people connect, and AI assistants | The person signs in to Oatmilk and approves access |
API keys
An API key belongs to the person who made it and to one company. It starts with oat_live_ in production or oat_test_ in staging, and the two never work in each other's environment.
- It's shown once. Copy it when you create it. Oatmilk only stores a hash, so nobody can show it to you again. If you lose it, rotate the key to get a new secret.
- It expires. Keys last 90 days unless you choose otherwise, and at most a year.
- It follows its owner. Every request checks the owner's current role and membership. A key stops working when it's revoked, when it expires, or when its owner leaves the company.
- It's for servers. Never put a key in browser code, a mobile app or a public repository.
Permissions
A key or token only does what its permissions allow. Each action's page in the API reference lists the permissions it needs, and a request without them is refused with INSUFFICIENT_SCOPE.
| Permission | Allows |
|---|---|
accounting:read | Read accounting. Read records and receipt evidence allowed by your role. |
accounting:write | Write accounting. Submit receipts and, with finance access, edit records and reconcile. Select read access too. |
accounting:admin | Accounting administration. Manage access, bank settings and closed periods. Administrator role remains required. |
mail:read | Read company mail. Read cleared company email and its original files. Separate from accounting access. |
mail:write | Manage company mail. Review email and financial drafts. Select mail read too; booking also requires accounting read and write. |
mail:security | Read restricted account-access mail. Explicitly allow access codes, security messages and unscreened mail. Requires administrator role and mail read. |
api_keys:manage | Manage API keys. Create or replace your keys within this key’s permissions and expiration; administrators may revoke organization keys. |
mailboxes:search | Search your inbox for receipts. Start Find in my inbox for purchases that need a receipt, or check your inbox now, in your own connected inbox only. Read and write access don’t include it. |
contractor:read | Read your contractor records. Read your own hours, timesheets, pay, agreements and profile with one company. |
contractor:write | Change your contractor records. Log and submit your own hours and update your profile. Select read access too. |
Roles
Permissions say what a credential may try. The owner's role in the company decides what they may actually do, and the stricter of the two always wins.
| Role | Can work with |
|---|---|
admin | Everything, including people, settings, connectors, webhooks and closing periods. |
finance | The books: transactions, receipts, matching, invoices, contractors and reports. |
contributor | Their own receipts and card purchases, and the company's categories. |
accountant | An outside accountant: reads and exports what their access allows, through OAuth only. |
contractor | The contractor API: only their own hours, pay, agreements and profile. |
Choosing a company
An API key always works in the company it was made in. A person with an OAuth token may belong to several companies: send X-Accounting-Organization with the company's ID to choose one. If you send it with an API key, it must name the key's own company.
X-Accounting-Organization: org_2abc…Each person can also have a personal workspace for their own money, chosen the same way. identity.get returns workspaceKind (company or personal). A personal workspace has every action except the contractor portal, recruiting and team invitations, which fail there with PERSONAL_WORKSPACE.
OAuth for apps and AI assistants
Apps that other people connect should use OAuth instead of asking for an API key. The person signs in to Oatmilk, sees what your app asks for, and approves it. Your app never sees their password, and they can disconnect it at any time.
Oatmilk publishes its OAuth details at https://app.getoatmilk.com/.well-known/oauth-authorization-server, and MCP clients discover them automatically from https://app.getoatmilk.com/.well-known/oauth-protected-resource/api/mcp. See MCP server.
Steps only a person can take
Some things always need a person in Oatmilk itself: signing an agreement, approving a suggestion, sending money, or entering bank and tax numbers. The API refuses them with an INTERACTIVE_… error that includes the link to the right page, so your app can hand it to the person. See Errors.