Intents

Create an intent

Create an intent for a governed action.

POST/v1/agent-api/intents

The SDK's submitIntent and the CLI's action commands create the intent for you. If the server asks the agent to co-sign a wallet payment, both clients will also sign and submit it in the same call.

Headers

Idempotency-KeystringOptional
Optional operation identifier. Reuse the same value only when retrying the same logical submission. Without it, each request is a new submission with no request-idempotency guarantee. Separate x402/MPP approval correlation and nonce-reuse rules still apply.

Body parameters

Below are the shapes that action can take. The idempotencyKey field is optional, and when you send it, the Idempotency-Key header takes the same value.

action.type method Required fields Optional fields
send ach counterpartyRailId, amount accountId, description, memo
send wire counterpartyRailId, amount accountId, description, memo
send on-chain counterpartyRailId, amount accountId, description
transfer accountId, toAccountId, amount memo, description
create_counterparty name, one of rail or email
request_counterparty_details counterpartyId, methods
x402 accountId, paymentRequirements resource, authorization, signedOffer
mpp accountId, challenge resource
policy_override schemaVersion, operations, durationSeconds, reason

Responses

200
Intent created and evaluated. A send or wallet-source transfer from a non-custodial wallet account returns an additional nextAction object (a submit_stamp envelope) with the unsigned body to stamp and submit to POST /intents/{intentId}/submit-stamp.
400
Input invalid, including an accountless send when multiple source accounts are allowed (policy_send_account_required)
403
Account not accessible under this policy, an accountless send has no allowed source (policy_send_account_unavailable)
404
Agent or referenced counterparty resource not found. Payment recipient failures may include details.requiredRail, which can be submitted in a create-counterparty intent
409
Intent conflicts, including idempotency-key reuse with changed request parameters, an inferred source that changed during submission (policy_send_account_changed), another payment from the same wallet still being approved (movement_wallet_approval_open; details.heldUntil is when the payment holding the wallet frees it, with the seconds until then in Retry-After, and is null when that cannot be told, as while that payment is being signed; wait until then, or a few seconds when it is null, then send the request again, on a new idempotency key when details.intentCancelled is true, because this request's intent was cancelled and its key answers with that cancelled intent, and on the same key when it is false, because the intent is still open (if it has been cancelled since, that resend returns it and nothing moved, so start again on a new key); details.blockingIntentId names the payment holding the wallet when it is one of your own intents, and cancelling it frees the wallet at once), a retried send that now crosses networks while its earlier request is still open (cross_chain_send_movement_required; have the earlier request denied or let it expire, or have Catena support close it if it was already approved, then start the payment again on a new idempotency key), a network Catena has made temporarily unavailable (onchain_network_closed, with no Retry-After; the request changed nothing and payments already in progress complete; do not retry on that network, and use one named in details.alternatives instead), or an existing payment details request with safe invitation state
429
Too many bank payments were requested for the organization (rate_limited). Each bank payment counts against a per-organization budget of 60 a minute by default, shared by its agents and members, with no daily cap; send the request again after the Retry-After seconds
503
Non-custodial wallet sending is not enabled, or a service the request needs is temporarily unavailable (movement_admission_paused, or temporarily_unavailable with the service in details). The request changed nothing, and payments already in progress complete; send it again after the Retry-After seconds

Response fields

idstringRequired
accountIdstringOptional
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"Required
status"pending" | "processing" | "completed" | "blocked" | "failed"Required
resolution"completed" | "blocked" | "denied" | "expired" | "failed" | "cancelled" or string or nullRequired
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.
reasonsarray of stringRequired
expiresAtstring or nullRequired
replayedbooleanRequired
dataobject or nullRequired
nextActionobjectOptional
nextAction.type"submit_stamp"Required
nextAction.signingRequestIdstringRequired
nextAction.signerobjectRequired
nextAction.preparedBodyobjectRequired
nextAction.movementobjectOptional
nextAction.stepsarray of objectOptional
nextAction.totalsobjectOptional
metadataobjectOptional
Present while the intent waits for a person's approval: dataUrl is the console page where they decide it
metadata.dataUrlstring or nullRequired
Updated October 29, 2026 Generated from the agent API's published OpenAPI document View as Markdown