# intake.process

File an uploaded item as a confirmed kind (receipt, vendor_bill, issued_invoice, bank_statement, contractor_agreement, tax_document, company_document or other) with an optional target: accountId or newAccount for a CSV statement; contractorId, or newContractor (displayName, email, optional legalName, and confirmedNew once a person checked they aren't someone with the same or a close name), for an agreement, a tax document or another record kept for a contractor; taxYear for a tax document; paymentAccountId for a receipt. An agreement for a contractor that matches the one already on file (same start and end dates, rate and role) is refused with SAME_AGREEMENT until sameAgreement says what to do: link (file this upload as that agreement, adding nothing), replace (keep this copy as the agreement and void the uploaded one on file; not for one signed in Oatmilk) or keep (keep both, without reading this one's terms). Receipts and bills enter receipt processing, CSV statements are imported, agreements are kept as signed agreements, and other records go to the documents store. An issued invoice waits for review in the invoice importer; send invoiceIds once it is imported. Idempotent. Contributors can file receipts only.

`POST /api/v1/accounting/intake.process`

Permissions: `accounting:read`, `accounting:write` · Roles: admin, finance, contributor · Idempotency key required · Send `expectedRevision`

MCP tool: `accounting_intake_process`

## Fields

| Field | Type | Required | Notes |
| --- | --- | --- | --- |
| `id` | string (ID) | Yes | The record's ID. |
| `kind` | enum | Yes | Which kind of record or job this is. One of: `receipt`, `vendor_bill`, `issued_invoice`, `bank_statement`, `contractor_agreement`, `tax_document`, `company_document`, `other`. |
| `subtype` | string |  | Matches ^[a-z][a-z0-9_]{1,40}$. |
| `target` | object |  | No other fields. |
| `target.accountId` | string (ID) |  | The ID of a bank, card or payment account, from accounts.list. |
| `target.newAccount` | object |  | No other fields. |
| `target.newAccount.name` | string | Yes | A display name. 1–100 characters. |
| `target.newAccount.provider` | enum | Yes | One of: `rbc`, `other`. |
| `target.newAccount.currency` | string | Yes | Three-letter currency code, such as CAD or USD. |
| `target.newAccount.lastFour` | string or null |  | Default `null`. |
| `target.newAccount.accountType` | enum |  | One of: `bank`, `credit_card`. Default `"bank"`. |
| `target.contractorId` | string (ID) |  | The ID of a contractor, from contractors.list. |
| `target.newContractor` | object |  | No other fields. |
| `target.newContractor.displayName` | string | Yes | 1–200 characters. |
| `target.newContractor.legalName` | string |  | 1–300 characters. |
| `target.newContractor.email` | string (email) | Yes | An email address. at most 320 characters. |
| `target.newContractor.confirmedNew` | boolean |  |  |
| `target.sameAgreement` | enum |  | One of: `link`, `replace`, `keep`. |
| `target.taxYear` | integer |  | 1990 to 2100. |
| `target.paymentAccountId` | string (ID) |  | The card or account the purchase was paid with, from accounts.list. |
| `via` | enum |  | One of: `suggestion`, `manual`, `preset`. Default `"manual"`. |
| `expectedRevision` | integer |  | The record's current revision, from the last time you read it. If someone changed the record since, the request is refused with a conflict so you can reload and check before trying again. at most 9007199254740991; greater than 0. |
| `invoiceIds` | array of strings (ID) |  | A list of record IDs. 1–50 items. |
| `idempotencyKey` | string | Yes | Any unique text you generate once per intended change, so a retried request only happens once. Send it as the Idempotency-Key header instead if you prefer; if you send both they must match. 8–200 characters. |

## Example request

```bash
curl https://app.getoatmilk.com/api/v1/accounting/intake.process \
  -H "Authorization: Bearer $OATMILK_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "id": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
  "kind": "receipt"
}'
```

Reference page: https://app.getoatmilk.com/docs/api/intake.process
