# contractorOps.import.hoursSync

Sync past timesheets from the Notion Contractors Hours database in one step (databaseId once, its link or ID; later syncs leave it out and use the remembered one): checks the database, then adds new timesheets, corrects edited ones (dates, hours, rate, amount, GST/HST, notes) and marks unpaid ones paid when Notion says Paid (never the reverse), without duplicating any, then settles new unpaid timesheets against bank payments already linked to the contractor. Returns counts, the change for each row, the payments that settled timesheets or now need a person's OK, and a plain-words summary. Bank and tax columns are never read. Send a new idempotencyKey for each sync.

`POST /api/v1/accounting/contractorOps.import.hoursSync`

Permissions: `accounting:read`, `accounting:write` · Roles: admin, finance · Idempotency key required · Reaches outside Oatmilk (email or a provider)

MCP tool: `accounting_contractor_ops_import_hours_sync`

## Fields

| Field | Type | Required | Notes |
| --- | --- | --- | --- |
| `databaseId` | string |  | The Contractors Hours database's link or ID. Needed once; Oatmilk remembers it, and later syncs leave it out. 1–2000 characters. |
| `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/contractorOps.import.hoursSync \
  -H "Authorization: Bearer $OATMILK_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{}'
```

Reference page: https://app.getoatmilk.com/docs/api/contractorOps.import.hoursSync
