# Contractor API

> Let contractors log hours, submit timesheets and read their pay from their own tools.

Source: https://app.getoatmilk.com/docs/contractors

Contractors who work for a company on Oatmilk have their own API at `/api/v1/contractor/`. It reaches only that contractor's own records: their hours, timesheets, pay, agreements and profile. Company API keys don't work here, and contractor sign-ins can't see the company's books.

```http
POST https://app.getoatmilk.com/api/v1/contractor/hours.create
Authorization: Bearer <contractor OAuth token>
```

## Signing in

The contractor API uses OAuth with the `contractor:read` and `contractor:write` permissions. A contractor connects an app or AI assistant by signing in with the account they use for the contractor portal. Use `https://app.getoatmilk.com/api/mcp?toolset=contractor` to give an assistant only the contractor tools.

## Choose the company

A contractor can work for several companies. Call `organizations.list` first: it needs no company. Then send `X-Accounting-Organization` with the chosen company's ID on every other request.

```bash
curl https://app.getoatmilk.com/api/v1/contractor/organizations.list \
  -H "Authorization: Bearer $OATMILK_OAUTH_TOKEN"
```

## Log and submit hours

```bash
curl https://app.getoatmilk.com/api/v1/contractor/hours.create \
  -H "Authorization: Bearer $OATMILK_OAUTH_TOKEN" \
  -H "X-Accounting-Organization: $OATMILK_ORGANIZATION_ID" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "date": "2026-09-15",
  "minutes": 90,
  "description": "Design review with the finance team"
}'
```

When the pay period is ready, submit every draft entry in it at once:

```bash
curl https://app.getoatmilk.com/api/v1/contractor/timesheet.submit \
  -H "Authorization: Bearer $OATMILK_OAUTH_TOKEN" \
  -H "X-Accounting-Organization: $OATMILK_ORGANIZATION_ID" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "date": "2026-09-15"
}'
```

## What stays in the portal

Bank details, tax numbers, agreeing to receive tax slips by email, and signing agreements only happen in the contractor's own portal session. The API refuses them with `INTERACTIVE_PORTAL_REQUIRED` or `INTERACTIVE_SIGNATURE_REQUIRED` and a `portalUrl` that opens the exact step.

## Every contractor action

The [contractor reference](https://app.getoatmilk.com/docs/api/contractor.md) lists all 43 actions with their fields.
