> ## Documentation Index
> Fetch the complete documentation index at: https://opentrain.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Create a Project To-do

> Create one item and its initial assignments atomically, with an explicit audience and a request-bound idempotency key.

Creates one to-do item, its first immutable version, and every initial assignment in a single transaction. Requires `project_todos:write`, a claimed account, and employer access to the job.

<ParamField body="action" type="string" required>`create_item`</ParamField>

<ParamField body="idempotencyKey" type="string" required>
  8–200 characters, bound to the complete request. Reuse the same key only to retry the identical request.
</ParamField>

<ParamField body="jobId" type="string" required />

<ParamField body="audience" type="string" required>
  `ACTIVE`, `FUTURE`, `ACTIVE_AND_FUTURE`, or `SELECTED`. There is no default — omission fails with `400`.
</ParamField>

<ParamField body="selectedContractIds" type="string[]">
  `SELECTED` only: a non-empty, duplicate-free list of active contracts on this exact job (up to 500). Invalid IDs reject the whole request with per-ID reasons.
</ParamField>

<ParamField body="preflightReceipt" type="string">
  Required for `ACTIVE`, `FUTURE`, and `ACTIVE_AND_FUTURE`. Mint it with [`preflight`](/docs/developers/api-reference/project-todos/preflight).
</ParamField>

<ParamField body="version" type="object" required>
  The worker-facing definition: `title`, `type`, optional `description`, `content`, `ownerRole`, `required`, `priority` (`NORMAL` | `HIGH` | `URGENT`), `blockingMode` (`NONE` | `IMMEDIATE` | `AFTER_DUE`), `blockingScope`, `dueOffsetMinutes`, `reminderPolicy`, and `completionConfig`.
</ParamField>

<ParamField body="categoryId" type="string">Optional category; omitting uses the job's General category.</ParamField>
<ParamField body="key" type="string">Optional stable item key.</ParamField>

<ParamField body="autoAssignNewHires" type="boolean">
  Adds future-hire auto-assignment to `ACTIVE`. Not allowed with `SELECTED`.
</ParamField>

<ParamField body="allowDuplicate" type="boolean">
  Overrides the `409 LIKELY_DUPLICATE` refusal when an active item already carries this exact request.
</ParamField>

## Response

```json theme={null}
{
  "ok": true,
  "action": "create_item",
  "itemId": "…",
  "versionId": "…",
  "audience": "SELECTED",
  "includesFutureHires": false,
  "fanOut": { "matchedContracts": 1, "createdAssignments": 1, "assignmentIds": ["…"] },
  "recipients": [{ "contractId": "…", "workerUserId": "…", "displayName": "Alex B." }],
  "replayed": false,
  "warnings": []
}
```

`recipients` are the masked people this exact request was verified against. On an identical-request retry, `replayed` is `true`, `createdAssignments` is `0`, and the roster is not re-resolved — a person hired after the original create is never silently added.

## Failure modes

Beyond the [common errors](/docs/developers/api-reference/project-todos/overview#common-errors): the reserved time-tracking setup to-do cannot be authored here, and integration-type items require the matching configured provider on the job.
