---
title: "Propose a safe execution plan (returns the plan_hash + single-use approval nonce)"
method: POST
path: "/v1/analysis-runs/{run_id}/action-plans"
tags: ["Decision Workflow"]
---

# Propose a safe execution plan (returns the plan_hash + single-use approval nonce)

`POST /v1/analysis-runs/{run_id}/action-plans`

## Request

- Base URL: `https://api.algenta.ai`
- URL: `https://api.algenta.ai/v1/analysis-runs/{run_id}/action-plans`
- Auth: one of:
  - HTTP bearer
  - API key in header `X-API-Key`

## Path parameters

- `run_id` string, uuid, required

## Response `201`

Successful Response

- ExecutionPlanResponse
  - `plan_id` string, uuid, required
  - `case_id` string, uuid, required
  - `run_id` string, uuid, nullable, required
  - `lifecycle_state` string, required
  - `plan_hash` string, nullable, required
  - `nonce` string, nullable: Single-use approval challenge (present only at propose time)
  - `actions` object, nullable, required
  - `receipt` ExecutionReceipt: Evidence that one approved plan executed exactly once, and under what authority.
    - `receipt_version` string: Receipt schema version. Bumped only on a breaking change.
    - `status` 'executed' | 'denied' | 'approval_required' | 'failed', required: Terminal state of the governed operation this receipt describes.
    - `code` string, nullable: Machine-readable reason when status is not 'executed' -- the same DecisionServiceError code the HTTP layer maps (e.g. plan_hash_mismatch, invalid_nonce, approval_expired).
    - `retryable` boolean: Whether re-issuing the identical request could succeed. A policy denial is NOT retryable; an upstream timeout is. Stated explicitly so a caller does not have to infer intent from an HTTP status.
    - `request_id` string, nullable: Identifies the single HTTP call that produced this receipt.
    - `trace_id` string, nullable: W3C trace-id of the wider operation. One agent turn may produce several receipts; this is what lets them be reassembled afterwards.
    - `idempotency_key` string, nullable: The Idempotency-Key the caller supplied, echoed so a retry can be matched to its original outcome. None when the caller sent none.
    - `execution_id` string, uuid, required: Unique id for this execution attempt, minted at execute time and persisted with the receipt. Distinct from plan_id: the plan is what was authorised, this is the act.
    - `plan_hash` string, nullable: Hash of the approved plan. An approval is bound to this exact value.
    - `approval_state` 'approved' | 'not_required' | 'pending' | 'rejected' | 'expired', nullable: Approval status at the moment of execution.
    - `policy_snapshot_hash` string, nullable: Content hash of the policy snapshot in force. None on the decision-plan path, which carries no policy snapshot -- deliberately null rather than filled with a value that is not a policy hash.
    - `executed_at` string, date-time, nullable: When execution completed.
    - `result` object, nullable: Operation-specific result. Everything above is stable across operations.

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/codna/apis/algenta-api.md) · [All operations](https://skmtc.dev/codna/apis/algenta-api/llms.txt) · [OpenAPI document](https://skmtc.dev/codna/apis/algenta-api/revisions/35d30f84a5df?raw)
