contractorOps.import.contractors
Bring contractors in from a table: source notion with databaseId (the database's link or ID), or source csv with rows. mapping names the column for any fields whose column names don't match (null for none); the others are matched by name, and a column that isn't in the table is reported in problems. A required field no column matches is refused with the table's columns listed. Fields: name (required), legalName, workEmail, personalEmail, wiseEmail, wiseLink, phone, roles, jobRole, department, jurisdiction, address (split into street, city, province or state, postal code and country), city, postalCode, chargesSalesTax, salesTaxRate, discord, github, portfolio, startDate, notes, currency, and the bank columns accountHolderName, bankName, bankAddress, accountNumber, institutionNumber, transitNumber, routingNumber, iban and swiftBic. People already in Oatmilk are matched by email and then by name, and only have blanks filled in; new people are added without an invitation, and no one is emailed. jobRole is matched to a job role by title and level; a title with several levels takes the level whose pay band holds the person's current rate, and otherwise jobRoleLevels lists the levels to choose from. The address used to reach each person is work email, then personal, then Wise, unless emails (row reference to address) chooses another; a row with no email is left out until emails gives it one. Payment details are saved only when an administrator imports and only for someone with none yet, in the currency column's currency, else the bank's country's, else the person's country's, else CAD. They are validated, sealed and audited, and saving them doesn't email the contractor; a row whose details don't validate is still imported and listed in paymentProblems. Payment details are never returned, in a preview, a result or a message: each row's plan has paymentDetails with present, method (bank_transfer or wise_email), masked (at most the last four characters of the account number or IBAN, or the Wise email masked) and fields (the names of the details the row has), a Wise email is left out of emails and masked when it's the address used, and a column whose name says it holds payment or tax details is only read for the bank and Wise fields. With preview true nothing is saved and the plan for every row comes back.
/api/v1/accounting/contractorOps.import.contractorsPermissions
Who can call it
Retries
MCP
accounting_contractor_ops_import_contractorsFields
sourceenumRequirednotion reads a Notion database on the server; csv takes the rows of a parsed CSV file.
csvnotionrowsarray of mapsFor csv: each row as column name to value, at most 500.
1–500 items
databaseIdstringFor notion: the database's link or ID. The database must be shared with the Oatmilk connection.
1–2000 characters
mappingobjectThe column for any fields whose column names don't match (null for none). Fields left out, or every field when it's omitted, are matched by column name; the result returns the mapping it used, so a preview shows the suggested one.
previewbooleantrue checks every row and saves nothing.
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
emailsmapThe address to use for a row, by the row's reference (its Notion page link, or Row 2, Row 3 for a CSV file), instead of work, personal, then Wise email.
Example
curl https://app.getoatmilk.com/api/v1/accounting/contractorOps.import.contractors \
-H "Authorization: Bearer $OATMILK_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"source": "csv",
"rows": [
{}
]
}'{
"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/contractorOps.import.contractors \
-H "Authorization: Bearer $OATMILK_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"source": "csv",
"rows": [
{}
]
}'More in Contractors.