General
1. Can I use Mandate with Solana?
Yes. Action-based validation (POST /validate) works with any chain. You pass action, reason, amount, and to as strings. Address comparison is case-sensitive for non-EVM chains, so Solana base58 addresses work as-is. The allowlist checks compare addresses exactly as stored.
Raw validation (POST /validate/raw) is EVM-only and requires EIP-1559 transaction parameters.
2. What happens if the Mandate API is down?
Block the transaction. Never fall back to calling the wallet directly. An unreachable policy server does not mean “no policies apply.” It means policies cannot be verified. Retry up to 3 times at 30-second intervals. If all retries fail, inform the user: “Cannot execute until policy server recovers. No funds were spent.” This is the core fail-safe principle. See Fail-Safe Behavior.3. Can I use Mandate without a private key?
Yes. Action-based validation does not require gas parameters, nonce, or signing. You validate the intent (action + reason + amount + recipient), then call your wallet provider (Bankr, Locus, Sponge, or any custodial API) to execute. Mandate validates the intent. Your wallet handles execution.4. How do I test without real funds?
Use amndt_test_* runtime key with Base Sepolia (chain ID 84532). Testnet validation runs the full 14-check pipeline identically to mainnet. Fund your test wallet from a Base Sepolia faucet. Testnet usage is free.
5. What is the difference between validate and raw validate?
POST /validate (recommended): Action-based. Send action, reason, amount, to. Works with any wallet type. No intent hash, gas, or nonce needed. Returns allowed: true or a block reason.
POST /validate/raw (deprecated): EVM-specific. Send full transaction parameters (nonce, gas, calldata) plus an intentHash. Used by self-custodial agents that sign locally. Supports envelope verification after broadcast.
Use action-based validation for all new integrations.
Keys and Authentication
6. Can multiple agents share a runtime key?
No. Each agent gets its own runtime key at registration. Policies, quotas, and audit logs are tracked per agent. Sharing a key means shared quotas and a shared audit trail, which defeats the purpose of per-agent governance.7. How do I rotate my runtime key?
Open the dashboard, navigate to the agent’s detail page, and click “Regenerate Key.” The old key is immediately invalidated. Update your~/.mandate/credentials.json and any environment variables with the new key.
8. Does Mandate support ERC-721 and ERC-1155?
Yes, through raw validation. Raw validation accepts any calldata, so you can validate NFT transfers, approvals, and marketplace interactions. The policy engine applies spend limits based on the decoded USD value. For NFTs without clear USD pricing, setamount in the action-based endpoint or rely on allowlist and selector-based controls.
Chains and Tokens
9. What chains are supported?
Four chains: Ethereum Mainnet (1), Ethereum Sepolia (11155111), Base Mainnet (8453), and Base Sepolia (84532). Test keys (mndt_test_*) work with testnets. Live keys (mndt_live_*) work with mainnets.
See Chain Reference for USDC addresses and SDK constants.
10. Can I set different policies per chain?
One policy per agent. To use different policies per chain, create separate agents for each chain. Each agent has its own runtime key, policy, quotas, and audit log.Approvals
11. How long do approvals last?
Theapproval_pending state has a 1-hour TTL. If the owner does not respond within 1 hour, the intent expires and any reserved quota is released. After approval, the agent has a 10-minute broadcast window.
12. Can I approve via API?
Yes. UsePOST /api/approvals/{id}/decide with a Sanctum authentication token:
Policies and Limits
13. Is the reason field stored?
Yes. The reason field is stored in the audit log permanently. Every transaction record includes the agent’s stated reason, the validation result, and the policy evaluation trace. When the optional LLM judge runs, it uses zero-retention (the reason is not persisted by the LLM provider).14. What is the default policy?
After registration and claiming, agents get: 1,000 daily limit, no monthly cap, no address restrictions, no approval rules, risk scanning enabled. Adjust these in the Policy Builder.15. Can agents register themselves?
Yes.POST /api/agents/register requires no authentication. The agent receives a runtimeKey and a claimUrl. The human owner visits the claimUrl to link the agent to their dashboard account. Until claimed, the agent uses the default policy.
Monitoring and Audit
16. How do I monitor agent spend?
The dashboard provides three views:- Audit Log: Every validation request, approval decision, and on-chain confirmation.
- Insights: Quota usage visualization showing per-day and per-month spend against limits.
- Agent Detail: Current quota consumption and remaining budget at a glance.
GET /api/intents/{id}/status.
Advanced
17. Does Mandate support batch transactions?
Validate each transaction individually. Mandate tracks intents one at a time, with independent quota reservations and state machines. For batch operations, loop through your transactions and validate each before execution.18. What about gas sponsorship?
Mandate validates the intent. Gas is the agent’s responsibility. If you use a gas relay or paymaster, Mandate validates the intent before you submit to the relay. The gas payment mechanism is orthogonal to policy enforcement.19. Can I use Mandate with ethers.js?
Yes. Wrap your ethers.js signer in theExternalSigner interface:
20. Is there a free tier?
Yes. Testnet usage is completely free. Usemndt_test_* keys with Sepolia or Base Sepolia. The full 14-check pipeline, approval workflows, audit log, and dashboard are available on testnet at no cost. Mainnet pricing is based on validated intents per month.
21. What format does the amount field use?
It depends on the method. The policy engine always evaluates in USD internally, but different SDK methods accept different input formats.
| Method | Amount format | Example | Meaning |
|---|---|---|---|
client.validate() | USD string | '50' | $50 |
wallet.transfer() | Raw token units | '5000000' | 5 USDC (6 decimals) |
CLI --amount | USD string | 50 | $50 |
REST API POST /validate | USD string | "50" | $50 |
validate() endpoint and CLI accept human-readable USD amounts as strings. MandateWallet.transfer() accepts raw token units because it constructs the on-chain transaction directly. USDC has 6 decimals, so '5000000' equals 5 USDC. ETH has 18 decimals.
Next Steps
Quickstart
Register an agent and validate your first transaction in under 5 minutes.
Common Errors
Step-by-step solutions for the most frequent errors.
Integration Guide
Pick the right Mandate integration for your framework.