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.
/api/v1/accounting/intake.processPermissions
Who can call it
Retries
MCP
accounting_intake_processFields
idstring (ID)RequiredThe record's ID.
kindenumRequiredWhich kind of record or job this is.
receiptvendor_billissued_invoicebank_statementcontractor_agreementtax_documentcompany_documentothersubtypestringMatches ^[a-z][a-z0-9_]{1,40}$
targetobjectNo other fields
viaenumsuggestionmanualpresetDefault "manual"
expectedRevisionintegerThe 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
invoiceIdsarray of strings (ID)A list of record IDs.
1–50 items
idempotencyKeystringRequiredAny 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
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"
}'{
"data": { … }
}Try it
Try it
Checks your input with this action’s real schema and answers like the API, with synthetic data. No key needed, and nothing changes.
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"
}'More in Inbox and uploads.