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

# Preflight a Project To-do Mutation

> Preview the exact recipients and effects of a create, update, assign, or archive without writing, and mint the receipt broad audiences require.

Validates one intended mutation without writing anything. Requires `project_todos:write` and employer access to the job. Preflight is the only manage action with no `idempotencyKey`.

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

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

<ParamField body="operation" type="string" required>
  `create_item`, `update_item`, `assign`, or `archive_item`.
</ParamField>

<ParamField body="audience" type="string">
  Required for `create_item`, `update_item`, and `assign`.
</ParamField>

<ParamField body="selectedContractIds" type="string[]">
  `SELECTED` only. Validated as strictly as the live mutation — offenders fail the preflight with per-ID reasons.
</ParamField>

<ParamField body="version" type="object">
  The exact version definition. Required for `create_item` and `update_item`.
</ParamField>

<ParamField body="itemId" type="string">
  Required for `update_item`, `assign`, and `archive_item`.
</ParamField>

## Response

`preflight` contains:

* `job` — the exact job ID and title.
* `audience` — the live blast radius: masked recipient names with contract IDs, the current count, and whether future hires will be auto-assigned.
* `due` and `blocking` — the projected due and block times, computed with the same schedule logic the live assignment uses.
* `evidence` and `instructionLinkage` — required review evidence and any linked instruction page.
* `duplicates` — `exact` lists active items whose complete request matches yours (the live create refuses these without `allowDuplicate: true`); `titleMatches` is a weaker advisory signal.
* `archive` — for `archive_item`: the exact number of open assignments that would close, plus the irreversibility and history-retention semantics.
* `receipt` — for broad audiences only: `{ token, expiresAt }`. Pass `token` back unchanged as `preflightReceipt` on the live mutation.
* `warnings` — human-readable advisories.

The receipt lives about 15 minutes and is bound to your account, the job, the operation, the audience, the live roster, and the exact payload. Any change invalidates it; run preflight again. The token is opaque — it never contains recipient identifiers.
