Agent-native accounts
An AI agent can open its own Bruce account, with no website, phone or human login, and use it the way a signed-in person does: set a profile, share pay details, request and collect money, and send payments. The wallet is owned by a key that only the agent holds.
If you want an agent to spend from your balance under caps instead, use delegated agent keys. Agent-native accounts are separate accounts that belong to the agent.
1. Sign up
GET /api/agent-auth/powreturns{ token, bits }. Find anoncewheresha256("<token>:<nonce>")starts with at leastbitszero bits. At the default of 20 bits this takes about a second.POST /api/agent-auth/registerwith{ publicKey, pow: { token, nonce }, displayName?, username? }.publicKeyis the base64 SPKI of the P-256 key.
The response includes userId and walletAddress. Signups are rate-limited per IP, and each puzzle can be used only once.
2. Log in
POST /api/agent-auth/challengewith{ publicKey }returns{ challengeId, message }. The challenge is valid for 5 minutes.- Sign the UTF-8
messageusing ECDSA P-256 with SHA-256. Send the signature as base64 DER or raw r||s. POST /api/agent-auth/sessionwith{ challengeId, signature }returns{ accessToken: "bas_…", expiresAt }.
Send Authorization: Bearer bas_… on every /api/* call. Sessions last one hour by default. To get a new one, log in again. POST /api/agent-auth/session/revoke ends a session.
3. Sign money movements
Every on-chain action uses the same three steps:
- Call the
…/prepareendpoint. It returnspayloadBase64andrequestExpiry. - Base64-decode the payload and sign the bytes with the agent key (ECDSA P-256 / SHA-256, DER, low-S).
- Call the submit endpoint with the same body plus
authorizationSignatureandrequestExpiry. Gas is sponsored.
| Action | Prepare | Submit |
|---|---|---|
| Send USDC (handle or address) | POST /api/transactions/send/prepare | POST /api/transactions/send |
| Escrow actions | POST /api/escrows/:id/relay/prepare | POST /api/escrows/:id/relay (add autoConfirm: true) |
| Scheduled payments | POST /api/scheduled-payments/:id/relay/prepare | POST /api/scheduled-payments/:id/relay (add autoConfirm: true) |
| Batch payouts (per chunk) | POST /api/batch-payments/:id/prepare | POST /api/batch-payments/:id/confirm with itemIds |
| Approved org send | POST /api/organizations/:id/approvals/:approvalId/prepare | POST …/execute |
If an agent submits without a signature, it gets 400 with code: "signature_required" and a hint that names the prepare endpoint.
With autoConfirm, Bruce records the state change (for example a confirmed deposit or a release) in the same call. The response includes it under confirm.
What agents can do
Everything on the logged-in API works the same way for agents, including:
- Profile, username and onboarding (
/api/setup/completeneeds no phone for agents) - Balance, transactions and contacts
- Payment requests, payment links and invoices
- Escrow, scheduled payments, batch payouts, organizations and notifications
Paying a request or a link is a signed send with paymentRequestId or paymentLinkId, followed by PATCH …/pay with the txHash.
Verified payments and withdrawals still need KYC or KYB, the same as for people.
These endpoints need a person and return 403 with not_available_for_agent_accounts:
- Admin
- Device and push registration
- Phone OTP
- PIN
- Creating delegated agent keys
- OAuth
- Accepting org invites
Limits
- Sponsored gas: 10 signed submits per day by default. The cap lifts once the account holds at least 5 USDC or is verified. Over the cap you get
429 sponsor_quota_exceeded. - Rate limit: every agent account has its own request limit.
- Audit: every state-changing request an agent makes is written to an audit log.
- Org approvals: an agent can approve sends requested by other agent accounts. A person must approve sends requested by people. When the requester is an agent, approval returns
approved_pending_signature, and the requester then signs with…/prepareand…/execute.
Tools
You don't have to implement signing yourself. The TypeScript SDK and the local MCP server handle it for you.