Who this is for
- SaaS subscriptions — monthly / annual billing where an agent manages the renewal
- AI service retainers — “Agent pays OpenAI up to $500/month for API access”
- Recurring procurement — monthly office supplies, recurring software renewals
- Usage-based billing — “Pay per API call, reconcile daily, cap at $1,000/month”
- Any flow where a user pre-authorizes a repeating spend envelope
What you’ll have when done
- A dedicated wallet for mandate-executed payments
- A registered agent with identity (Ed25519 keypair)
- An active mandate with defined scope and rules
- A confirmed test mandate execution
Steps
1. Create subscription wallet (required, ~2 min)
Wallet that funds mandate executions. Keep it separate from your main operating wallet so mandate spending is bounded by its balance. Wizard asks you:- Wallet name (e.g.
subscription-mandates) - Currency (USDC default)
2. Fund your wallet (optional, ~3 min)
Add USDC for mandate executions. In sandbox this is free; in live use on-ramp or transfer from another wallet. If you skip: mandates remainactive but executions will fail with INSUFFICIENT_BALANCE until you fund.
API equivalent (sandbox):
3. Register your agent (required, ~3 min)
The agent is the entity that executes the mandate. It has identity (an Ed25519 keypair) and a KYA tier that caps its spending independently of the mandate. Wizard asks you:- Agent name (e.g.
subscription-manager) - Description (what the agent does)
- KYA tier — default Tier 1 (Declared). Higher tiers unlock higher spending limits but require a Declared Spending Declaration or 30-day history.
Agent KYA tier and mandate scope both apply. Effective limit =
min(kya_tier_cap, mandate_scope). Set KYA tier based on risk; set mandate scope based on specific business authorization.4. Create payment mandate (required, ~4 min)
The mandate defines when, where, and how much the agent can spend. Wizard asks you:- Max per transaction (e.g. $100)
- Max per day (e.g. $500)
- Max per month (e.g. $5,000)
- Currency (USD default)
- Allowed merchants — specific merchant IDs the mandate permits
- Allowed categories — broader categories (
saas,compute,api, etc.) - Blocked merchants / categories — explicit denies
- Expires at — when the mandate automatically revokes
5. Test mandate execution (optional, ~3 min)
Sly triggers one mandate payment against a test merchant and verifies:- Mandate scope check passes
- Wallet has funds
- Agent KYA tier allows the amount
- Payment settles
- Webhook fires
After the wizard
Hand the mandate JWT to the agent. The agent presents it on every execution:- Verifies mandate scope (amount within caps, merchant allowed, not expired)
- Sums prior spend in the current day / month window
- Runs KYA tier + wallet policy checks
- Executes the transfer if all pass
- Spend-to-date vs. caps
- Recent executions + any rejections
- Remaining runway at current pace
- Revoke button
ap2.mandate_executed— per-execution confirmationap2.mandate_threshold_warning— approaching a capwallet.runway_alert— wallet running low
Patterns worth knowing
- Pause vs. revoke —
PATCH /mandates/:id { "status": "paused" }stops executions without losing the record. Resume later. - Scope expansion —
PATCH /mandates/:id { "scope": {...} }updates caps in-place. The audit log retains the prior state. - Mandate rotation — for annual renewals, create a new mandate before the old expires; the agent picks it up automatically if you update the ID in its config.
Troubleshooting
Mandate executions keep failing with `INSUFFICIENT_BALANCE`
Mandate executions keep failing with `INSUFFICIENT_BALANCE`
The wallet is underfunded relative to the execution amounts. Fund more, or lower the mandate’s per-tx cap so partial months don’t exhaust the wallet.
`POLICY_VIOLATION` on execution
`POLICY_VIOLATION` on execution
Check dashboard → Wallet Policies. The wallet policy layers on top of the mandate — if the wallet policy says “no gambling category” but your mandate says “yes saas”, and the merchant is in both, the wallet policy wins (narrower set).
Mandate JWT fails verification at merchant
Mandate JWT fails verification at merchant
Merchant is using the wrong public key. Our public keys rotate quarterly; merchants should pull from
https://api.getsly.ai/.well-known/jwks not hardcode.