Set up agent spend controls that survive prompt injection.
Set a spend permission in the dashboard - an allowance per period plus a per-transaction cap - and the backend enforces it on every payment. Because it lives on the backend and the API is read-only, prompt injection that hijacks the agent's planner still cannot raise the limit. Your code reads the permission over the API to display it or plan around it.
Before you start.
- An existing agent (see the add-payments-to-agent guide).
- Dashboard access for the workspace that owns the agent - permissions are set there, not via the API.
- A rough idea of expected daily spend - the allowance should be 2-3x normal usage, not 100x, so it is actually load-bearing.
- An API key to read the permission (a
sk_test_key is fine for this guide). - Familiarity with the agent spend policy concept - this guide is its operational counterpart.
Set the permission in the dashboard.
Open the agent in the Blockchain0x dashboard and set two numbers: an allowance over a period (a day, a week, or 30 days) and a per-transaction cap. The allowance bounds the worst case across the whole period; the per-transaction cap stops a single anomalous request from spending it all at once. This is a dashboard action on purpose - it is the human-set boundary the agent runs inside.
Amounts are USDC base units (6 decimals). An allowance_wei of "20000000" is 20 USDC; a per_tx_wei of "2000000" is 2 USDC. The period is a period_seconds value: 86400 for a day, 604800 for a week, 2592000 for 30 days.
Read the permission via the API.
Your code can fetch the live permission to show it in a UI or to let the agent check how much room is left before it tries a payment. The route is read-only - there is no mutate endpoint, which is exactly why the agent's key cannot widen its own limit.
curl https://api.blockchain0x.com/v1/agents/agt_123/spend-permissions \
-H "Authorization: Bearer $BLOCKCHAIN0X_API_KEY"{
"allowance_wei": "20000000",
"per_tx_wei": "2000000",
"period_seconds": 86400,
"start_at": "2026-05-15T00:00:00Z",
"end_at": null,
"revoked_at": null
}Bound it in time, or revoke it.
Two fields turn the permission into a time-bound control. start_at and end_at set the window in which it is live, so you can pre-stage a budget for a scheduled job or let one expire on its own; outside the window it authorizes nothing. revoked_at is the kill switch: revoke from the dashboard and the allowance drops to zero for any payment evaluated afterward.
For a harder stop, revoke or rotate the agent's API key with apiKeys.revoke or apiKeys.rotate - that cuts off the credential entirely, not just the spend. The permission revoke is the surgical move; the key revoke is the kill switch.
Handle a payment that hits the limit.
When a payment would exceed the active permission, the backend rejects it before anything touches the chain - no funds move. Your payments.create call returns an error; handle it like any other failed call, surface it to your operator, and do not retry blindly into the same wall.
To see what an agent attempted, watch the dashboard's activity log and reconcile real movements with transactions.get. A burst of rejected attempts is your early-warning signal: either a misconfigured allowance, a runaway loop, or an injection probe. Alert on it the same way you would on any spike of failed calls.
Five mistakes that defeat the control.
Putting the spend cap in agent code instead of the backend
Spend rules in the agent's planner or system prompt are not security boundaries. A prompt-injection attack that overrides the planner also overrides the cap. The whole point of a spend permission is that it lives outside the agent's manipulable scope - on the backend, set in the dashboard - so the agent cannot change it. Configure it there, not with 'tell the agent not to spend more than $X'.
Expecting the agent's API key to widen the limit
The API is read-only for spend permissions: there is no endpoint and no SDK method that raises an allowance. That is deliberate. If a compromised or injected agent could call a mutate endpoint with the key it already holds, the control would be worthless. To change a limit you use the dashboard, where the change is a human action with an audit trail.
Setting an allowance so high it never bites
A permission only protects you if it is load-bearing. An allowance set at 100x normal usage will not stop a runaway loop until it has already spent far more than you would have wanted. Size the allowance and the per-transaction cap at roughly 2-3x expected usage, then widen deliberately if real traffic proves you need to.
Forgetting the per-transaction cap
allowance_wei bounds the worst case over the whole period; per_tx_wei bounds any single payment. They do different jobs. A generous period allowance with no per-transaction cap still lets one anomalous request - a buggy retry, a maliciously-quoted price - move a large amount in a single shot. Set both.
No fast kill switch rehearsed
When something looks wrong at 2am, you want a move you have already practised. Two exist: revoke the permission in the dashboard (sets revoked_at, allowance to zero), or revoke/rotate the agent's API key with apiKeys.revoke / apiKeys.rotate (cuts the credential entirely). Know which one you reach for and that you can do it quickly.
After the permission is in place.
With the permission enforced, the follow-ups that pay off most are dependable webhook handling (so payment events actually reach your handler), identity verification (so counterparties trust the agent's profile), and a pre-launch security review (so you have not left another door open).
The webhook patterns developers ask about most
Earn the GitHub and domain verification badges
Secure your agent wallet before going live
Full reference at docs.blockchain0x.com. Product surface: Spending controls.