Concepts

Human attestation

Even policy-approved proposals don’t execute until a human attests. This is intentional — it’s the layer that turns guardrails into governance.

Lifecycle

  • Agent calls POST /api/agent/v1/trades/propose.
  • Backend runs validation. If blocked, returns the violations and creates nothing.
  • If allowed, backend creates a ServiceRequest with type = "agent_proposed_trade" and status = "pending". Returns serviceRequestId to the agent.
  • The user opens the AC app and sees the request in the same queue as manually-submitted trades. The agent flag and rationale are visible.
  • User accepts → backend executes against the custodian, the request status flips to completed.
  • User rejects → status flips to rejected with an optional reason.

Surfacing attestation in your agent

When propose_trade returns successfully, do not tell the user the trade happened. Tell them you proposed it and that the AC app is waiting on them.

Good messaging from the agent
const res = await proposeTrade({ … });
return `Proposed buy BTC $5,000. Open advisorscrypto.com → Requests to
attest. The policy approved (IPS v${res.decision.ipsVersion}) but the
trade hasn't executed yet — your approval is required.`;

The rationale field

When you propose, include a one-sentence rationale. It shows up next to the agent badge on the attestation card and is the user’s primary context for accepting.

json
{
  "action": "sell",
  "assetSymbol": "BTC",
  "assetType": "crypto",
  "amountUsd": 8500,
  "rationale":
    "Rebalance crypto sleeve toward 20% target (currently 26%)."
}

Idempotency on retries

Network blips happen. If you retry a propose_trade, pass the same Idempotency-Key header on both calls. We return the existing record on the second call instead of creating a duplicate.

http
POST /api/agent/v1/trades/propose
Idempotency-Key: agent-prop-2026-06-15-04f9c2

The key is good for 24 hours from the first successful call.

Last updated 2026-06-15