---
title: "Record one immutable human Decision against an exact proposal action."
method: POST
path: "/api/v1/interactions/{interactionId}/decisions"
tags: ["Interactions"]
---

# Record one immutable human Decision against an exact proposal action.

`POST /api/v1/interactions/{interactionId}/decisions`

## Request

- Base URL: `https://commentary.dev`
- URL: `https://commentary.dev/api/v1/interactions/{interactionId}/decisions`
- Auth: API key in cookie `commentary_session`

Requires exact revisionId, actionId, proposal fingerprint, current strong If-Match, and Idempotency-Key. The first valid result is immutable; replay never retargets a later revision. A Decision is intent, not Fulfillment or execution evidence.

## Path parameters

- `interactionId` string, required

## Headers

- `If-Match` string, required
- `Idempotency-Key` string, required

## Request body

- object
  - `revisionId` string, required
  - `actionId` string, required
  - `proposalFingerprint` string, required
  - `outcome` 'approve' | 'reject' | 'abstain' | 'conflict' | 'acknowledge' | 'choose' | 'answer' | 'comment' | 'request_revision' | 'snooze', required
  - `consequence` object, nullable

## Response `200`

Successful response.

- object
  - `data` InteractionDecisionResult
    - `decision` InteractionDecision: Immutable human intent receipt. execution.proven is always false in this slice.
      - `id` string, required
      - `interactionId` string, required
      - `revisionId` string, required
      - `actionId` string, required
      - `proposalFingerprint` string, required
      - `semanticAction` string, required
      - `outcome` 'approve' | 'reject' | 'abstain' | 'conflict' | 'acknowledge' | 'choose' | 'answer' | 'comment' | 'request_revision' | 'snooze', required
      - `actor` object, required
      - `decidedAt` string, date-time, required
      - `expiresAt` string, date-time, nullable
      - `terminalState` 'recorded', required
      - `actionSnapshot` object, nullable
      - `consequence` object, nullable
      - `contentPurgeAfter` string, date-time
      - `contentPurgedAt` string, date-time, nullable
      - `execution` object, required
        - `proven` unknown, required
    - `aggregate` object, nullable
    - `responseProgress` InteractionResponseProgress, nullable: Browser-human recipient progress for the current exact revision. Does not change the Interaction lifecycle or prove external execution. Agent receipt transports do not expose this projection.
      - `revisionId` string
      - `responded` boolean
      - `revisionChanges` string, nullable
      - `previousResponses` object[]
        - `id` string
        - `outcome` string
        - `value` string, nullable
        - `contentPurged` boolean
      - `next` 'you' | 'agent' | 'approvers' | 'revision' | 'none'
      - `message` string
      - `availableActionIds` string[]
      - `approvedActionIds` string[]: Actions whose current approval policy is satisfied; not proof of execution.
      - `receipts` object[]
        - `id` string
        - `actionId` string
        - `outcome` string
        - `value` string, nullable
        - `contentPurged` boolean

## Other responses

- `201`: Successful response.
- `400`: The request was invalid.
- `401`: Authentication is required.
- `403`: The token or session does not have permission for this resource.
- `404`: The resource was not found.
- `409`: Revision, action, fingerprint, revocation, or idempotency conflict.
- `410`: Proposal expired or content was purged.
- `412`: If-Match is stale or malformed.
- `428`: If-Match is required.
- `429`: The request was rate limited.

---

[API](https://skmtc.dev/commentary/apis/commentary-public-api.md) · [All operations](https://skmtc.dev/commentary/apis/commentary-public-api/llms.txt) · [OpenAPI document](https://skmtc.dev/commentary/apis/commentary-public-api/revisions/7aaafc198c52?raw)
