Contractors

contractorOps.roles.import

Create or update job roles from a table: source notion with databaseId (the database's link or ID), or source csv with rows (column name to value). 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: title (required), level, department, employmentType, summary, responsibilities, requirements, and either payBand text ("CAD 60–80/hour", "$90k–110k per year") or payMin, payMax, payCurrency, payUnit. Roles are matched by title and level, so importing again updates instead of duplicating, and a blank cell never erases what's written. A column whose name says it holds payment or tax details is never read, and problems says so when mapping names one. With preview true nothing is saved and the parsed roles and problems come back.

POST/api/v1/accounting/contractorOps.roles.import

Permissions

accounting:readaccounting:write

Who can call it

admin, finance

Retries

Idempotency key required

MCP

accounting_contractor_ops_roles_import

Fields

  • sourceenumRequired

    notion reads a Notion database on the server; csv takes the rows of a parsed CSV file.

    csvnotion
  • rowsarray of maps

    For csv: each row as column name to value, at most 500.

    1–500 items

  • databaseIdstring

    For notion: the database's link or ID. The database must be shared with the Oatmilk connection.

    1–2000 characters

  • mappingobject

    The 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.

  • previewboolean

    true checks every row and saves nothing.

  • 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.roles.import \
  -H "Authorization: Bearer $OATMILK_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "source": "csv",
  "rows": [
    {}
  ]
}'
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.roles.import
curl https://app.getoatmilk.com/api/v1/accounting/contractorOps.roles.import \
  -H "Authorization: Bearer $OATMILK_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "source": "csv",
  "rows": [
    {}
  ]
}'

More in Contractors.