The lifecycle
1
Request authorization
Conto approves the payment, sends it for review, or denies it. If it is denied, stop and show
the reason.
2
Wait for review if needed
If a person must review it, keep the request ID. After they decide, read the request status
again before you continue.
3
Execute
Once the request is approved, execute it through the managed wallet or send it from your own
wallet.
4
Track the result
The payment moves to
processing, then to completed or failed.GET /api/sdk/payments/{requestId} or conto.payments.status(requestId) with the same agent
key. Status reads require transactions:read. The status endpoint returns lowercase values,
request returns uppercase values, and the external-wallet approve returns ready_to_send when
approved. Do not compare them interchangeably. This table maps each response status to the status
read right after it.
What each status read means:
What proves settlement?
Execution returnsreceipt.transactionId and receipt.settlementMode. live means an onchain
transfer, including testnet. test means simulated settlement, with no transaction hash, explorer
URL, block number, or confirmation time. Status and transaction reads repeat settlementMode.
unknown means Conto has no execution evidence for the request. completed alone does not prove
funds moved onchain. Preserve the receipt and request ID.
For an onchain flow, wait for transaction.status: "completed" and check the intended chain.
A hash alone, an approval, or HTTP 200 is not confirmation.
Bounded polling
Call this helper after submission or an uncertain result. It only reads state. Any state other thanprocessing, including review, expiry, and denial, returns control to your application. Also
configure the SDK request timeout: an in-flight HTTP call can finish after the polling deadline.
Retry-After and resume later with the same request ID. A polling
deadline or read failure does not cancel the payment. See rate limits.
Recovery recipes
Execution timed out
- Read the original request ID. A timeout is not proof that execution failed.
- If there is a transaction, follow that transaction to completion or failure.
- If the state is unresolved, retain it and investigate. Do not automatically repeat execution,
even if the authorization still reads
approved. - Create a new intent only after establishing the original outcome and confirming the business action still needs payment. Preserve the association between both intents.
alreadyExecuted: true. While another attempt is in flight, it returns 409 PAYMENT_PROCESSING.
Reconcile the original request before any other write.
Durably persist your business action ID, idempotency key, Conto request ID, execution attempt, and
receipt so a restarted worker can discover an earlier execution attempt.
A human must approve
KeepREQUIRES_APPROVAL requests pending in your application. An authorized reviewer decides in
the configured approval workflow. For a managed wallet, approving the
payment in Conto executes it. Check the same request ID after review: payments.status() shows the
transaction, and payments.execute() returns the existing receipt with alreadyExecuted: true
instead of sending again. Before approval, execute() returns 409 APPROVAL_PENDING. A declined
payment returns 403 PAYMENT_DENIED with reasons.
External confirmation returns a conflict
Send through your external signer only after approval. Confirm using the request ID, final hash, and the approval token when one was issued. After human workflow approval, the token can be omitted. Repeated confirmation does not duplicate recorded spend but can return409 ALREADY_CONFIRMED.
Compare the returned txHash with your saved transfer and follow statusUrl. If the hashes differ,
stop and investigate. Never send a second transfer to resolve a confirmation error.