# HXP Actions and Status Changes
> Source: /hxp/actions
> Read Action context and understand claim, handoff, finish, cancellation, evidence, and version checks

<Warning>
  The commands below are implemented for HXP's authenticated operator client. These operator URLs do not accept an organization API key or MCP token. MCP can read authorized Action context through `read_thread`, but exposes no claim, handoff, finish, or cancel-Action tool.
</Warning>

For third-party server access, use the separate [organization API-key contract](/hxp/machine-integrations). Its read projections and allowed commands are narrower than the operator API documented below. Do not substitute its bearer key into these operator URLs.


## Read the work before changing it [#read-the-work-before-changing-it]

The operator endpoint `GET /api/v1/orgs/{orgId}/messaging?scope={scopeId}&view=actions` returns `{ "data": { "items": [...], "nextCursor": null } }`. A guest's `view=thread&guest={guestId}` response also includes Actions.

| Fields | Meaning |
| --- | --- |
| `id`, `organizationId`, `scopeId` | HXP Action identity and tenant/workspace boundary |
| `guestId`, nullable `stayId`, `sourceMessageId`, `audience` | Guest, stay, originating comment, and visibility |
| `title`, `teamId`, `ownerId`, `ownerName`, `createdBy` | Work to do, queue, current owner, and creator |
| `dueAt`, optional `timeZone` | ISO due instant and read-time guest/property timezone context |
| `state`, `version` | Workflow state and optimistic concurrency version |
| `evidence`, `receiptId` | Completion evidence and completion receipt, initially null |
| `createdAt`, `updatedAt` | Record timestamps |

Use returned IDs and versions. Guest names and owner labels are display context, not stable identity or authority. Where a task concerns a benefit, booking, payment, or delivery, consult the authoritative domain record as well; the Action is the coordination record.

## Commands, not arbitrary status patches [#commands-not-arbitrary-status-patches]

Current Action states are `suggestion`, `waiting_for_teammate`, `working`, `complete`, and `canceled`. The public-facing work labels used for AI tasks and deliveries include additional states; do not use that larger vocabulary as valid Action transitions.

| Command | Endpoint suffix | Result | Requirements beyond read/write scope |
| --- | --- | --- | --- |
| `action` | `/messaging?scope=...` | New unowned `waiting_for_teammate`, version 1 | Valid guest/stay/audience; source context must match if supplied |
| `claim` | `/messaging?scope=...` | `working`, owned by current operator | Matching version, nonterminal, no existing owner; assigned-team membership if applicable |
| `handoff` | `/collaboration?scope=...` | `working`, owned by selected operator; due time updated | Matching version, nonterminal, eligible recipient; if already owned, caller must be current owner or creator |
| `finish` | `/messaging?scope=...` | `complete` with evidence and receipt | Matching version; current owner only; assigned-team membership if applicable |
| `cancel_action` | `/messaging?scope=...` | `canceled` | Matching version; creator or owner; assigned-team membership if applicable |

Every suffix is under `/api/v1/orgs/{orgId}`. These commands require `POST`, JSON, the HXP session, and `Idempotency-Key`. There is no generic `PATCH { "status": "done" }` operation, and no reopen command for a completed or canceled Action.

### Create [#create]

```json
{
  "type": "action",
  "guestId": "guest-example",
  "stayId": null,
  "audience": { "type": "team", "teamId": "team-example" },
  "sourceMessageId": null,
  "title": "Prepare the quiet room before arrival",
  "teamId": "team-example",
  "dueAt": "2026-09-20T18:00:00.000Z"
}
```

### Claim [#claim]

```json
{
  "type": "claim",
  "id": "hxp-action:example",
  "expectedVersion": 1
}
```

### Complete with evidence [#complete-with-evidence]

Fetch the latest Action after claiming. The following version is illustrative:

```json
{
  "type": "finish",
  "id": "hxp-action:example",
  "expectedVersion": 2,
  "evidence": "Room preparation checked and completed by the assigned operator."
}
```

`evidence` must contain 8–2,000 characters after trimming. The server records the authenticated owner; there is no client-supplied `completedBy` override.

### Hand off [#hand-off]

Send to `/collaboration`, not `/messaging`. `dueAt` is required but may be null; use the existing due time to retain it.

```json
{
  "type": "handoff",
  "actionId": "hxp-action:example",
  "expectedVersion": 2,
  "ownerId": "user-next-owner",
  "dueAt": "2026-09-20T18:00:00.000Z"
}
```

### Cancel [#cancel]

```json
{
  "type": "cancel_action",
  "id": "hxp-action:example",
  "expectedVersion": 2
}
```

These are alternative examples, not a sequence to run against the same version.

## Receipts, retries, and errors [#receipts-retries-and-errors]

Messaging commands return HTTP `200` with:

```json
{
  "result": {
    "id": "hxp-action:example",
    "kind": "action",
    "receiptId": "receipt-example"
  }
}
```

The collaboration runtime's handoff response uses the same shape with `kind: "runtime"` and the Action ID. Neither response contains the updated Action; reread its authorized snapshot for the new state and version.

- Use one stable operation key per intended command: 8–180 letters, digits, underscores, colons, or hyphens (a UUID is suitable).
- After an ambiguous network result, repeat the **same key and identical input** as the same actor in the same organization/scope. Do not generate a new key merely because a response was lost.
- Reusing a key for changed content produces `409`. A stale `expectedVersion` or invalid current state also produces `409`; reread and review before issuing a new command with a new key.
- Reads need `hxp:guests:read`; these writes also need `hxp:organizations:manage`. Current access is checked even for retries.
- Invalid requests normally return `400`; unauthenticated requests `401`; cross-origin checks may return `403`; unavailable or unauthorized collaboration records may return `404`. Do not interpret a `404` as proof a record never existed.

Operator errors have an `error` object with `code`, `message`, `requestId`, and `retryable`; responses also include `X-Request-ID`. Use the request ID for support and avoid logging guest message bodies or credentials.

## Completion is not provider fulfillment [#completion-is-not-provider-fulfillment]

An HXP completion receipt proves the HXP command was recorded. It does not redeem a benefit, move funds, change a reservation, or establish guest delivery. Those operations use their own authorized services and evidence. `submitted_to_provider`, `delivery_confirmed`, and `reconciling` belong to delivery/execution workflows, not this Action state machine.

For a third-party system that must perform these transitions, see the explicit [external integration gap](/hxp/overview#planning-a-third-party-integration). Enabling MCP alone will not add Action status-write tools.
