[ agent api ]
Your agent can trade. It can never drain the account.
One credential, one policy the server enforces — operations, per-call cap, daily cap, coin allowlist. Five endpoints. Trading executes through a Hyperliquid agent wallet with trading-only rights; pay, swap and invoice return something the agent signs itself, because the platform holds no keys.
[ 60-second start ]
- 1. Create a key in Settings → API Keys and set the policy: grant read and trade, cap the call at $50.
- 2. Export the key and read the account. A new wallet gets a paper account with real market data and simulated fills.
export PB_KEY=pb_… curl -s https://protocolbanks.com/api/v1/agent/state \ -H "Authorization: Bearer $PB_KEY"
3. Place an order. The response tells you the fill, the fee and what the daily cap still allows.
curl -s https://protocolbanks.com/api/v1/agent/orders \
-H "Authorization: Bearer $PB_KEY" -H "Content-Type: application/json" \
-d '{"coin":"BTC","side":"long","sizeUsd":20}'
# run the whole walk in one command
PB_KEY=pb_… pnpm example:agent # state → order
PB_KEY=pb_… pnpm example:agent --invoice[ what the server enforces ]
The policy lives on the key, is edited at /settings/api-keys and cannot be widened by the caller. Values are clamped to the platform ranges.
| Field | Meaning | New key |
|---|---|---|
| allowedOps | read | trade | pay | swap — which calls the key may make | ["read"] |
| maxNotionalUsd | per-call cap; a larger order is refused before execution | $50 |
| dailyCapUsd | per UTC day, summed from metered calls | $200 |
| allowedCoins | allowlist; empty means every supported market | [] |
Trading also passes the platform risk envelope: position cap, leverage, stop-loss/take-profit, daily 5%/8% breakers. A size above the platform cap is clamped; a size above the key's cap is refused with 403.
[ endpoints ]
| Endpoint | Policy op | Executes? | Returns |
|---|---|---|---|
| GET /state | read | no | mode, equity, positions, activity, policy with spentTodayUsd |
| POST /orders | trade | yes (agent wallet) | fill + fee + remainingTodayUsd |
| POST /pay | pay | no | validated transfer intent to sign |
| POST /swap | swap | no | quote + transaction to sign |
| POST /invoice | pay | no | pending invoice + paymentLink |
Base URL https://protocolbanks.com/api/v1/agent. Every call is logged; orders are metered at 8 bps of notional.
[ sandbox → live ]
A key that belongs to a paper account trades at mark ± slippage with simulated money — same endpoints, same guards, mode: "paper" in the response, and the ledger survives a cold start. Approve the agent wallet on Hyperliquid and the same code goes live without a change. The agent wallet has trading-only rights: it can place and cancel orders, never withdraw.
[ errors ]
| Status | Meaning |
|---|---|
| 400 | malformed body, bad address, non-positive amount |
| 401 | missing or invalid key |
| 403 | policy refusal — op, per-call cap, daily cap, allowlist |
| 409 | platform guard — positions, breakers, funds, unknown market, no route |
| 429 | rate limit (100 requests/minute per IP) |
A 403 is the key policy refusing; a 409 is the platform guard refusing. Do not retry either unchanged. An order that reaches the venue without a confirmed response is reported as 409, recorded, and reconciled by client-order-id — it is never retried automatically.
[ frameworks ]
The API is a tool call. Wrap it in whatever your agent already uses — LangChain, the Vercel AI SDK, CrewAI, Mastra, or a raw function. @protocolbanks/agent-tools ships the five operations as JSON-Schema tool definitions with OpenAI and Anthropic converters, so one manifest covers every framework. The server enforces the cap, so the model can ask for anything:
const call = (path, body) =>
fetch(`https://protocolbanks.com/api/v1/agent${path}`, {
method: body ? "POST" : "GET",
headers: {
Authorization: `Bearer ${process.env.PB_KEY}`,
...(body ? { "Content-Type": "application/json" } : {}),
},
body: body ? JSON.stringify(body) : undefined,
}).then((r) => r.json())
// a runaway loop asking for $5,000 gets {"ok":false,"error":"… exceeds … cap"} with 403
const order = await call("/orders", { coin: "BTC", side: "long", sizeUsd: 20 })Prefer a protocol? The same surface is reachable from the MCP server for hosts that speak it.
[ references ]
- /api/agent.openapi.json — the machine-readable contract (OpenAPI 3.1)
- AGENT_API.md — auth, policy, every endpoint, errors, billing
- AGENT_CASES.md — four worked integrations, including a runaway model loop
- AGENT_TOOLS.md — the tool manifest and framework adapters
- PARTNERS.md — partner integration, sandbox, per-order billing

