proposals — a human-readable summary plus the concrete action series each example below walks through. Your application puts them in front of the customer, then submits the approved proposals verbatim to POST /instructions. Only that call creates real objects — and the drafted mandate still activates only with the customer’s signature.
Amounts are decimal strings in the destination asset; dates are unix seconds.
1. One-off payment
Prompt: Pay Acme 0.5 USDC on base-sepolia, one-time, from my base-sepolia wallet. 0xad878f82a6549ca1fe977f26bb768bf890420e92The agent recognizes a funding wallet on the destination’s own chain family, so this is a direct payment — no conversion account involved. The draft:
create_recipient— Acmecreate_crypto_destination— the address onbase-sepoliacreate_mandate— rule targeting the recipient:asset: USDC,network_id: base-sepolia,max_per_tx: "0.5",window: NONE,max_count_per_target_in_window: 1create_scheduled_payments— one date
window: NONE is what makes this a one-off. The per-target caps normally meter over a calendar window; NONE removes the reset, turning them into lifetime totals. Paired with max_count_per_target_in_window: 1, the mandate authorizes exactly one payment to Acme — ever. Once that payment fires, the exhausted mandate flips to done on its own: the authority is spent with the payment, leaving no standing grant behind. (Compare WEEKLY / MONTHLY in the next example, whose caps reset each calendar window and so keep authorizing.)
2. Recurring series under one mandate
Prompt: Pay Beta Corp 1 USDC on base-sepolia every week for 3 weeks.
- One recipient + destination as above
create_mandate—window: WEEKLY,max_per_tx: "1",max_count_per_target_in_window: 1,valid_untilcovering the seriescreate_scheduled_payments— 3 dates in one action
WEEKLY runs Monday 00:00 UTC to Monday, MONTHLY from the 1st, and NONE makes the caps lifetime totals.
3. Standing authorization, schedule under it later
A mandate does not need a schedule attached at birth. Have the agent draft one, or create it yourself withPOST /mandates — the snippet below is that request body:
payment_agent_id is one way the create call names the signer: the endpoint resolves the agent to its signer and drafts the mandate pending, bound to that signer (bound_signer_id on the returned mandate). The other way is naming the signer directly — signer_id + customer_id instead of payment_agent_id — which binds any of your signers, not only a hosted agent’s (Direct Control shows both forms). Binding — and enforcement at the mandate gate — is per signer, and approval stays the same dual-control step as everywhere else.
Once signed, schedule payments under it any time with POST /scheduled-payments — coverage is decided at fire time, so any scheduled payment that fits an active mandate’s rule fires without further signing. This is the “authorize once, pay as you go” shape: up to 100 USDC to Alice, once a month, until the end of 2026.
Choosing targets
The example above targets a recipient by name. Three target kinds are supported (a rule holds at most 32 targets):recipient — the customer’s payees, referenced by recipient id or name. Names are resolved at creation: the rule is stored — and signed — with verified recipient ids, and an unknown name fails the create instead of storing a dangling grant. At fire time a payment matches when its destination address belongs to the target recipient (a direct destination, or the deposit address of a conversion account paying them):
address — raw destination addresses, bound as given. Matching follows the chain family’s semantics: EVM addresses compare case-insensitively, Solana addresses byte-exactly. The same payee’s other addresses are outside the grant:
any — no target pinning: cap-limited authority over any destination. With no targets to key on, the window caps meter over one shared bucket across all payees, not per payee. It is the widest grant a mandate can express — use deliberately, with tight caps:
recipient and address rules the per-window caps apply per target, never pooled across them.
The asset is what leaves the wallet
asset names what the funding wallet sends, and must match the firing payment’s own asset (compared case-insensitively) — in practice, the stablecoin your wallet pays with, like USDC. When the payment converts downstream (a cross-chain swap or a bank offramp), the rule still names the deposit asset, never the converted output — see the offramp in example 5.
This is enforced at create: the asset must be sendable on the rule’s pinned network (or on at least one network when the rule leaves it open). Writing "asset": "USD" on an offramp mandate — or any symbol that can never match a send — fails the create with an actionable 400 instead of minting a dead grant that denies every fire.
4. Cross-chain payment (auto account)
Prompt: Pay John Doe 0.30 USDC on solana-devnet, once a month for 4 months, from base-sepolia. 7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsUThe funding wallet is EVM but the destination is Solana — no same-family wallet exists, so the agent drafts a cross-family swap via an auto account:
create_recipient+create_crypto_destination(the Solana address)create_auto_account— an EVM USDC deposit address onbase-sepoliathat converts and forwards to USDC onsolana-devnetcreate_scheduled_payments— 4 monthly payments that pay the deposit addresscreate_mandate— written in deposit terms:asset: USDC,network_id: base-sepolia
output_network: solana-devnet and destination_label tell your UI where the money ultimately landed; GET /auto-transactions lists the conversion legs.
If the agent does hold a wallet on the destination’s family, it always drafts the direct route instead — a swap is proposed only when no same-family wallet exists, and with several candidate wallets it asks which one to use rather than picking one silently.
5. Bank offramp (crypto → fiat)
Prompt: Pay Zephyr Logistics $250 into their Chase account 98765432, routing 021000021, ACH — one-time. Beneficiary: 500 Market St, San Francisco, CA 94105, US, from my base-sepolia USDC.
create_recipient— Zephyr Logisticscreate_bank_destination— account + routing number,rail: ach, beneficiary addresscreate_auto_account— offramp: USDC deposit → USD payout via ACHcreate_scheduled_payments+create_mandate— in deposit terms, as with the swap
asset is the asset of the wallet’s transaction intent — whichever supported stablecoin funds the payment (USDC in this example; USDT or RD work the same way) — not the final USD the bank receives. The gate authorizes and meters what leaves the wallet; the conversion to fiat is downstream routing.
Stablecoin conversion is 1:1: the executed payment shows output_asset: USD, destination_type: bank, destination_rail: ach, and a destination_label like Chase ••••5432. Supported payout rails are ach, fedwire, and swift. Bank-rail constraints (like beneficiary-name length) are validated when the instruction is accepted — a rejection rolls the whole instruction back, leaving no orphan recipient or destination.

