---
title: "Cancel an intent before execution starts, or while its bank payment waits to be signed"
method: POST
path: "/intents/{intentId}/cancel"
tags: ["intents"]
---

# Cancel an intent before execution starts, or while its bank payment waits to be signed

`POST /intents/{intentId}/cancel`

## Request

- Base URL: `https://api.catena.com/v1/agent-api`
- URL: `https://api.catena.com/v1/agent-api/intents/{intentId}/cancel`
- Auth: HTTP bearer

## Path parameters

- `intentId` string, required

## Response `200`

Full intent state after cancellation. Repeating the request for an already-cancelled intent returns the same successful projection. An intent can be cancelled while it waits for approval, after approval, or while it executes a bank payment that is prepared but not yet signed. Cancellation cannot stop or reverse a signed payment or other work already executing.

- object
  - `id` string, required
  - `accountId` string: Resolved source account, pinned when the intent was created. Omitted for actions without an account.
  - `type` 'send' | 'transfer' | 'create_counterparty' | 'request_counterparty_details' | 'x402' | 'mpp' | 'policy_override' | 'policy_proposal' | 'card_purchase', required
  - `status` 'pending' | 'processing' | 'completed' | 'blocked' | 'failed', required
  - `resolution` union, required: Exact terminal outcome, or null while the intent is nonterminal. Known values are completed, blocked, denied, expired, failed, and cancelled; clients must preserve future nonblank strings.
    - 'completed' | 'blocked' | 'denied' | 'expired' | 'failed' | 'cancelled'
    - string
  - `reasons` string[], required
  - `expiresAt` string, date-time, nullable, required
  - `movement` object
    - `planId` string, required
    - `nextStep` 'wait' | 'done' | 'blocked', required
  - `proposal` object
    - `reason` string, nullable, required: Whether this policy proposal can go ahead, without naming the resource or its state. While `status` is pending, null means the proposal passes every check made before a person reviews it; wait on awaiting_resources (something it needs, such as an active account, is not ready yet) and temporarily_unavailable (the check could not finish; read again later), and resubmit on referenced_resource_unavailable (an account or counterparty it names cannot be used) and proposal_invalid (it cannot be approved as written). While it is pending, it does not reflect whether a counterparty the proposal would create matches an existing one or shares an existing one's name, or what a wallet name (ENS) resolves to; only the person reviewing it sees those. When `resolution` is blocked, it is the reason the approval attempt recorded. In every other state it is null, and `status` and `resolution` give the outcome.
  - `evidence` object: The evidence submitted with the intent, keyed by field key: text exactly as sent, or a file's details. Absent when the intent carries none
  - `data` union, required
    - object
    - object: A completed policy proposal: the policy its approval created, and the counterparty each proposed reference became. A counterparty deleted since, or one the current policy does not list, is left out.
      - `policy` object, required
        - `id` string, required
        - `name` string, required
      - `counterparties` object[], required
        - `ref` string, required
        - `id` string, required
        - `name` string, required
        - `outcome` 'created' | 'reused', required
  - `metadata` object, required
    - `dataUrl` string, nullable, required

## Other responses

- `404`: Intent missing or not owned by the authenticated agent (`intent_not_found`)
- `409`: Intent is not eligible for cancellation (`intent_not_cancellable`): it has already ended, it is executing without a bank payment, or its bank payment is signed or past its approval window. While another request is working on the intent's bank payment, the same code comes with `Retry-After`; send the request again after that many seconds. Also refused when the agent's policy cannot be read (`policy_unreadable`) until an admin saves its full configuration or, for a temporary override, revokes it and grants a new one; nothing changed, and GET /policy shows it with `invalidReason`

---

[API](https://skmtc.dev/catena/apis/catena-agent-api.md) - [All operations](https://skmtc.dev/catena/apis/catena-agent-api/llms.txt) - [OpenAPI document](https://skmtc.dev/catena/apis/catena-agent-api/revisions/9b72e32d21f1?raw)
