Agent wallets
An agent wallet lets an AI agent or an automated service send payouts without your merchant key. You fund it
with part of your balance, and give the agent a wallet key (ak_test_… or ak_live_…) that can only:
- read its own wallet and balance, and
- create payouts within a fixed policy: one provider, a maximum per payout, an optional daily maximum
(
max_daily_amount, counted per Dakar calendar day), and an allowlist of recipient phones (1–20).
The wallet’s funded balance is the agent’s total spending limit. It can never touch the rest of your balance.
| You (merchant key) | The agent (wallet key) |
|---|---|
POST /v1/agent-wallets — create with a policy (Idempotency-Key required) |
GET /v1/agent/wallet — its policy |
POST /v1/agent-wallets/{id}/fund · …/reclaim — move money in / take unreserved money back |
GET /v1/agent/balance |
POST /v1/agent-wallets/{id}/keys — issue a key (shown once) |
POST /v1/agent/payouts — pay out within the policy |
POST /v1/agent-wallets/{id}/disable — stop new agent writes |
GET /v1/agent/payouts · …/{id} |
GET /v1/agent-wallets/{id}/payouts · …/transfers · …/keys |
Safe retries: action_id
Section titled “Safe retries: action_id”Every agent payout carries an action_id from your application (e.g. the approved task’s id), not invented by the
model. Xaalis binds one payout to each action_id in the wallet, so a retried tool call returns the original payout
instead of paying twice. Reusing an action_id with a different amount or recipient returns 409.
Owner approval above the limits (test mode)
Section titled “Owner approval above the limits (test mode)”Tight limits are safer, but an agent then stops dead on the first unusual payout. With owner approval, a payout over the wallet’s soft caps waits for a person instead of failing:
- Policy (merchant key or dashboard):
approval_above_limit: trueandapproval_max_amount— a hard ceiling, at leastmax_payout_amount. Off by default; test wallets only for now. - An otherwise valid agent payout above the per-payout cap or the day’s total answers
202with anagent_payout_approval(apr_…,status: "pending", 30 minutes). Nothing is reserved while it waits. A recipient outside the allowlist, another provider, or an amount aboveapproval_max_amountstill fails; a wallet holds at most 20 pending approvals (422 limit_exceeded). - The agent polls
GET /v1/agent/approvals/{id}:pending→approved(withpayout_id),declinedorexpired. It never sees a PIN link or the full phone number. - The owner decides in the dashboard or on WhatsApp, and confirms an approval with their PIN on a Xaalis page — never in
a chat or a tool. The page shows the full number, amount and fee. Approval admits the payout; it’s not a success: read
the payout’s own
status.
Retries: keep the same action_id and Idempotency-Key. A retry returns the same approval while it’s pending,
declined or expired — widening the caps doesn’t change that — then the one payout once approved. That retry answers
201 with the payout even if its reservation failed afterwards (status: "failed", failure_reason): check it, and
don’t start a new action automatically. A new action_id is a new request for the owner.
SDK: agent.payouts.request(…) / requestForAction(…) return a Payout or an AgentPayoutApproval; poll
agent.approvals.retrieve(id). The older create / createForAction still return a Payout and throw
XaalisApprovalRequiredError (with .approval) when approval is needed. An unreadable answer to a write throws
XaalisProtocolError with outcomeUnknown: true: retry with the same action, or poll the approval you know.
Live wallets: set up by a person
Section titled “Live wallets: set up by a person”In live mode, only a signed-in owner of the merchant account can create a wallet, change its policy, fund or
reclaim it, and issue its ak_live_ key — in the merchant dashboard, never with an API key. So an agent holding your
sk_live_ key (or any API key) can’t create or top up a wallet for itself. Your live API keys can still read
wallets and disable a wallet or revoke its key — stopping an agent is always one call away.
The owner can raise or lower the per-payout and daily caps or replace the recipient list at any time; the next payout is checked against the new policy.
Limits of this version
Section titled “Limits of this version”- Live agent payouts support Wave wallets only for now (Orange Money payouts aren’t available yet).
- A live agent key is only accepted over HTTPS.
- Disabling a wallet blocks new agent writes; payouts already accepted still finish.
The TypeScript SDK includes agent-wallet helpers (xaalis.agentWallets for you, an agent client with
payouts.createForAction for the agent), with an example tool handler.