Contractors

contractorOps.history.allocations.save

Share one payment across several imported timesheets (weeks, two-week periods or parts of a month), or pay one timesheet from several payments. Send contractorId and either transactionId (an outgoing bank payment) or payoutId (a payment recorded in Oatmilk with no pay period) with the allocations of that payment, or historyId with the allocations of that timesheet. Each allocation is historyId, transactionId or payoutId, amountMinor, and closes (true counts a small shortfall, such as a fee, as paid in full). The list replaces what that payment (or timesheet) had; an empty list removes it, which is how a match is undone. A payment never gives more than it paid, a timesheet never takes more than it pays, and one payment pays one contractor. A timesheet its allocations cover (any allocation, when it has no amount) is marked paid on the latest payment's date; one no longer covered goes back to unpaid. Timesheets paid in their table or marked paid by hand keep that. Automatic matching leaves the payment alone afterwards. Optional note and idempotencyKey. Audited.

POST/api/v1/accounting/contractorOps.history.allocations.save

Permissions

accounting:readaccounting:write

Who can call it

admin, finance

Retries

Idempotency key required

MCP

accounting_contractor_ops_history_allocations_save

Fields

  • contractorIdstring (ID)Required

    The ID of a contractor, from contractors.list.

  • transactionIdstring (ID)

    The ID of a bank or card transaction, from transactions.list.

  • payoutIdstring (ID)

    The ID of the related record.

  • historyIdstring (ID)

    The ID of the related record.

  • allocationsarray of objectsRequired

    at most 200 items

  • notestring

    A short note, kept with the record.

    at most 500 characters

  • idempotencyKeystringRequired

    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

curl https://app.getoatmilk.com/api/v1/accounting/contractorOps.history.allocations.save \
  -H "Authorization: Bearer $OATMILK_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "contractorId": "4d5e6f7a-8b9c-4d0e-8f1a-2b3c4d5e6f7a",
  "allocations": [
    {
      "historyId": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
      "amountMinor": "1250",
      "transactionId": "7f0f6c1e-1c1f-4b5e-9c8d-2f5e8e3c1a10"
    }
  ],
  "transactionId": "7f0f6c1e-1c1f-4b5e-9c8d-2f5e8e3c1a10"
}'
Response
{
  "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.

POST/api/v1/accounting/contractorOps.history.allocations.save
curl https://app.getoatmilk.com/api/v1/accounting/contractorOps.history.allocations.save \
  -H "Authorization: Bearer $OATMILK_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "contractorId": "4d5e6f7a-8b9c-4d0e-8f1a-2b3c4d5e6f7a",
  "allocations": [
    {
      "historyId": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
      "amountMinor": "1250",
      "transactionId": "7f0f6c1e-1c1f-4b5e-9c8d-2f5e8e3c1a10"
    }
  ],
  "transactionId": "7f0f6c1e-1c1f-4b5e-9c8d-2f5e8e3c1a10"
}'

More in Contractors.