Guide
Pay for APIs in one call with the SDK
The Aut SDK gives your agent one function, call. Say what you need, and it finds the right API on Aut, pays for it on Robinhood Chain and returns the answer with a receipt. It works the same in TypeScript and Python.
| Finds the API | From your words and the kind of input: a token or wallet address, a transaction hash or a link |
| Pays | In USDG, or $AUTONOMO when the wallet has no USDG |
| Privately | Through Gloam, so the payment doesn't link to your wallet |
| On credit | Borrows from a Borro credit line when the wallet is short of USDG |
| Within limits | A most-per-call and a daily budget, checked before anything is signed |
| Receipt | Which API, how it was paid, the amount and the transaction link |
Install
npm install autonomo-sdkpip install autonomo-sdkTypeScript needs Node 20 or later, Python 3.10 or later. The Python SDK is also on PyPI as Aut; either way, you import it from Aut. Make a new wallet just for your agent and keep only what it may spend in it. Most APIs cost 0.01 USDG, so 1 USDG is about 100 calls. Paying in $AUTONOMO needs a little ETH once, for a Permit2 approval.
Pay from the agent's wallet
The usual way. The SDK pays in USDG if the wallet has enough, and otherwise in $AUTONOMO. Set payWith (pay_with in Python) to "usdg" or "Aut" to use only one.
// Pay from the agent's own wallet: USDG first, then $AUT.
import { Aut } from "autonomo-sdk";
const Aut = new Aut({
privateKey: process.env.AUTONOMO_WALLET_KEY,
limits: { perCall: { usdg: "0.02" }, daily: { usdg: "0.50" } },
});
const { data, receipt } = await autonomo.call("is this token safe", {
input: "0x86b57bcb9d249cf096cf8e21426c9dc9cafdec49",
});
console.log(data);
console.log(receipt.route, receipt.amount, receipt.token, receipt.explorer);"""Pay from the agent's own wallet: USDG first, then $AUT."""
import os
from Aut import Aut
Aut = Aut(
private_key=os.environ["AUTONOMO_WALLET_KEY"],
per_call={"usdg": "0.02"},
daily={"usdg": "0.50"},
)
result = autonomo.call("is this token safe", input="0x86b57bcb9d249cf096cf8e21426c9dc9cafdec49")
print(result.data)
print(result.receipt.route, result.receipt.amount, result.receipt.token, result.receipt.explorer)01It finds the API
"is this token safe" plus a token address picks Token Risk and fills in its path. When two APIs fit, it picks the one that's Verified, with the better track record.
02It checks the price against your limits
It asks the API for its price without paying. A price over your limits is refused here, before anything is signed.
03It pays and returns the answer
It signs one x402 payment for exactly that price, to that API only, and sends the request with it. Aut settles it on-chain and pays the gas. If the API fails, the payment doesn't settle and you aren't charged.
Pay privately with Gloam
With private: true (private=True), the call is paid from a private Gloam balance, so it doesn't link back to your wallet. The SDK hands the payment to Gloam's own MCP server, @gloamtrade/mcp, running on your machine: Gloam cashes out exactly the price through its relay and calls the API with it. The SDK never sees your Gloam key, and your agent's own wallet key isn't needed.
01Set up Gloam's server
Put its settings in ~/.gloam/agent.env, and keep the file private. GLOAM_AGENT_PRIVATE_KEY is the key Gloam spends with; it stays on this machine. Gloam won't spend without limits. Each Aut API is paid at its own address, so recipients is any, kept safe by small caps. Gloam's limits apply on top of the SDK's.
GLOAM_NETWORK=robinhood-mainnet
GLOAM_AGENT_PRIVATE_KEY=0x…
GLOAM_LIMIT_NETWORK=robinhood-mainnet
GLOAM_LIMIT_ASSETS=USDG
GLOAM_LIMIT_MAX_PER_PAYMENT=0.05
GLOAM_LIMIT_MAX_PER_DAY=1
GLOAM_LIMIT_RECIPIENTS=any02Fund its private balance
Deposit USDG into that agent's private balance with Gloam's gloam_execute_shield tool. A balance in the Gloam app belongs to the app, not to the agent's server. See Gloam's agent docs.
03Call with private on
// Pay privately from a Gloam balance, through Gloam's own MCP server running on this machine.
// It reads its key and limits from ~/.gloam/agent.env (GLOAM_NETWORK=robinhood-mainnet).
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
import { Aut } from "autonomo-sdk";
const gloam = new Client({ name: "my-agent", version: "1.0.0" });
// On Windows, npx is a script, so it's started through cmd.
const server = process.platform === "win32" ? { command: "cmd", args: ["/c", "npx", "-y", "@gloamtrade/mcp"] } : { command: "npx", args: ["-y", "@gloamtrade/mcp"] };
await gloam.connect(new StdioClientTransport(server));
const Aut = new Aut({
gloam: {
fetchPaid: async (args) => {
// A private payment builds its proofs on this machine and can take a few minutes: wait up to 5, not the
// MCP client's default of 60 seconds.
const out = await gloam.callTool({ name: "gloam_fetch_paid", arguments: args }, undefined, { timeout: 300_000 });
return JSON.parse((out.content as Array<{ text: string }>)[0].text);
},
},
});
const { data, receipt } = await autonomo.call("newest launches", { private: true });
console.log(data);
console.log(receipt.route, receipt.amount, receipt.explorer); // "gloam", the price plus Gloam's fee, the cash-out
await gloam.close();"""Pay privately from a Gloam balance, through Gloam's own MCP server running on this machine.
It reads its key and limits from ~/.gloam/agent.env (GLOAM_NETWORK=robinhood-mainnet). Needs `pip install mcp`."""
import asyncio
import json
from datetime import timedelta
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
from Aut import Aut
async def main():
server = StdioServerParameters(command="npx", args=["-y", "@gloamtrade/mcp"])
async with stdio_client(server) as (read, write), ClientSession(read, write) as gloam:
await gloam.initialize()
loop = asyncio.get_running_loop()
def fetch_paid(args):
# A private payment builds its proofs on this machine and can take a few minutes: wait up to 5.
call = gloam.call_tool("gloam_fetch_paid", args, read_timeout_seconds=timedelta(minutes=5))
out = asyncio.run_coroutine_threadsafe(call, loop).result()
return json.loads(out.content[0].text)
Aut = Aut(gloam_fetch_paid=fetch_paid)
result = await asyncio.to_thread(autonomo.call, "newest launches", private=True)
print(result.data)
print(result.receipt.route, result.receipt.amount, result.receipt.explorer)
asyncio.run(main())- A private call is only ever paid through Gloam. If the API doesn't offer it, the call is refused, never paid publicly.
- The price includes Gloam's cash-out fee, so 0.01 USDG becomes about 0.0105.
- What stays public: the amount, the API's payment address and the time. What stays private: which wallet paid.
- Gloam builds the payment's proofs on your machine, which can take a minute or two. MCP clients give up after 60 seconds by default, so the examples wait up to 5 minutes.
- On Windows,
npxis a script, so the TypeScript example starts the server throughcmd /c.
Borrow with a Borro credit line
Set a Borro credit line, and when the wallet can't afford a call, the SDK borrows just what it's short and pays in the same call. It asks Borro's MCP server for the borrow, sends it from the wallet, waits for the USDG to arrive, then pays as usual.
// Borrow what the wallet is short from a Borro credit line, then pay.
import { Aut } from "autonomo-sdk";
const Aut = new Aut({
privateKey: process.env.AUTONOMO_WALLET_KEY,
payWith: "usdg",
borro: { account: process.env.BORRO_CREDIT_LINE! },
});
const { data, receipt } = await autonomo.call("explain this transaction", {
input: "0x0f1635d41a8fbbde7d61ad39e045e067780b921329112c16955bc26ad3423041",
});
console.log(data);
console.log(receipt.route, receipt.borrowTxs, receipt.explorer); // "borro" when it borrowed, "usdg" when it didn't need to"""Borrow what the wallet is short from a Borro credit line, then pay."""
import os
from Aut import Aut
Aut = Aut(
private_key=os.environ["AUTONOMO_WALLET_KEY"],
pay_with="usdg",
borro_account=os.environ["BORRO_CREDIT_LINE"],
)
result = autonomo.call("explain this transaction", input="0x0f1635d41a8fbbde7d61ad39e045e067780b921329112c16955bc26ad3423041")
print(result.data)
print(result.receipt.route, result.receipt.borrow_txs, result.receipt.explorer)- Open the line at borro.markets/app with Let the agent pay its x402 bills ticked, for this agent's wallet. Borro's daily limit applies on top of the SDK's.
- The wallet needs a little BNB for the borrow transaction's gas.
- The receipt's route is
borrowhen it borrowed, with the borrow transaction, orusdgwhen the wallet already had enough. - Repaying the line is between you and Borro.
Try every route yourself
One script tries each way to pay with one small call to New Launches: 0.01 USDG, or 100 $AUTONOMO. Each command prints the receipt with its transaction link, so you can check what happened on-chain. It's capped at 0.02 USDG a call and 0.10 USDG a day. It runs on Node, which Gloam's server needs anyway; the Python examples above do the same things.
01Set up a folder
mkdir try-autonomo && cd try-autonomo
npm init -y
npm install autonomo-sdk @modelcontextprotocol/sdkSave the script below in it as try-every-route.mjs, then check it works. quote is free and needs no wallet: it shows the API the calls will use and every price it takes.
node try-every-route.mjs quote02Pay from a wallet: usdg and Aut
Use a new wallet with a few cents in it: 0.01 USDG for usdg, and 100 $AUTONOMO plus a little ETH (once, for the Permit2 approval) for Aut. Set its key in the terminal only, never in a file you share or commit.
# macOS and Linux
export AUTONOMO_WALLET_KEY=0x…
# Windows PowerShell
$env:AUTONOMO_WALLET_KEY = "0x…"node try-every-route.mjs usdg
node try-every-route.mjs AutOn Blockscout, the token moves from your wallet to the API's payment address. Aut's facilitator sends the transaction and pays the gas, so your wallet spends no BNB on it. Anyone can see this wallet paid.
03Pay privately: gloam
Before you start:
- Set up
~/.gloam/agent.envas in Pay privately with Gloam. Its key is the wallet Gloam deposits from. It holds the USDG to deposit and a little BNB for the deposit's gas. This step needs noAUTONOMO_WALLET_KEY. - Gloam's own limits must allow the payment:
USDGas the asset, at least 0.011 per payment, and recipientsany. The settings in that section do. - The deposit is public. Anyone can see that the key's wallet put USDG into Gloam's vault. What stays private is which payments it made from there. Use a wallet of its own for Gloam if that matters.
node try-every-route.mjs gloam-shield 0.05
node try-every-route.mjs gloam-balance
node try-every-route.mjs gloamDeposit, check the balance shows as unspent, then pay. The payment takes a minute or two while Gloam builds its proofs on your machine. On Blockscout, Gloam's vault pays the API, sent by Gloam's relayer: your wallet isn't in the transaction.
If it says paid_not_served, Gloam has paid but the API hadn't answered yet. Don't run gloam again, which would pay a second time. Pass the payment header it printed instead:
node try-every-route.mjs gloam-retry <paymentHeader>04Borrow and pay: borro
Before you start:
- A credit line, opened from an owner wallet as in Open a credit line: buy a little CREDIT on Uniswap with USDG, post it as collateral on Borro with nothing borrowed, set the agent wallet, and tick Let the agent pay its x402 bills. It needs room to borrow 0.01 USDG today, under the line's ceiling and daily limit.
AUTONOMO_WALLET_KEYis the agent wallet set on the line, not the line's owner, andBORRO_CREDIT_LINEis the line's address.- The agent wallet must be short of USDG. With 0.01 USDG or more it just pays, and the receipt says
usdg, notborro. A second wallet, with no USDG left over from step 2, is simplest. - It needs a little BNB for the borrow transaction's gas: about 0.00003 BNB.
# macOS and Linux
export AUTONOMO_WALLET_KEY=0x… # the agent wallet set on the credit line
export BORRO_CREDIT_LINE=0x… # the credit line
node try-every-route.mjs borro
# Windows PowerShell
$env:AUTONOMO_WALLET_KEY = "0x…"
$env:BORRO_CREDIT_LINE = "0x…"
node try-every-route.mjs borroIt prints two transactions. The borrow: the credit line lends what the wallet is short (all 0.01 when it holds none) to the agent wallet. Then the payment from that wallet to the API, a few seconds later. The line now owes what was borrowed, plus a little interest, until you repay it on Borro.
// Try every way the SDK pays, one small call at a time, on the New Launches API (0.01 USDG or 100 $AUT a call).
//
// node try-every-route.mjs quote free: the API it would use and every price it takes
// node try-every-route.mjs usdg pay in USDG from the wallet
// node try-every-route.mjs Aut pay in $AUT from the wallet (first time: one Permit2 approval)
// node try-every-route.mjs gloam-shield 0.05 move 0.05 USDG into the Gloam agent's private balance
// node try-every-route.mjs gloam-balance show that private balance
// node try-every-route.mjs gloam pay privately through Gloam
// node try-every-route.mjs gloam-retry <header> finish a Gloam call that was paid but not answered, without paying again
// node try-every-route.mjs borro borrow what the wallet is short from a Borro credit line, then pay
//
// Set in the terminal, never in a file you share or commit:
// AUTONOMO_WALLET_KEY usdg and Aut: the wallet that pays. borro: the agent wallet set on the credit line
// BORRO_CREDIT_LINE the Borro credit line's address (borro)
// Gloam needs no wallet key here: it reads its own key and limits from ~/.gloam/agent.env. Every paid command is capped
// at 0.02 USDG or 150 $AUT a call and 0.10 USDG or 500 $AUT a day, and prints the receipt with its transaction link.
import { Aut, AutonomoError } from "autonomo-sdk";
const QUERY = "newest launches";
const limits = { perCall: { usdg: "0.02", Aut: "150" }, daily: { usdg: "0.10", Aut: "500" } };
const [route, arg] = process.argv.slice(2);
function need(name) {
const v = (process.env[name] ?? "").trim();
if (!v) {
console.log(`Set ${name} first, in this terminal.`);
process.exit(1);
}
return v;
}
function show({ data, receipt: r }) {
console.log(`\nPaid ${r.amount} ${r.token} by route "${r.route}" for ${r.api.name}`);
console.log(`Payer: ${r.payer}`);
console.log(`Paid to: ${r.payTo}`);
if (r.explorer) console.log(`Payment: ${r.explorer}`);
for (const t of r.borrowTxs) console.log(`Borrow: ${t}`);
if (r.approveTx) console.log(`Approval: ${r.approveTx}`);
console.log(`Spent today: ${r.spentToday}`);
console.log(`\nAnswer starts: ${JSON.stringify(data).slice(0, 300)}`);
}
/** Starts Gloam's own MCP server on this machine and runs `work` with a function that calls its tools. */
async function withGloam(work) {
const { Client } = await import("@modelcontextprotocol/sdk/client/index.js");
const { StdioClientTransport } = await import("@modelcontextprotocol/sdk/client/stdio.js");
const npx = ["npx", "-y", "@gloamtrade/mcp"];
const [command, ...args] = process.platform === "win32" ? ["cmd", "/c", ...npx] : npx; // npx is a script on Windows
const gloam = new Client({ name: "autonomo-try-every-route", version: "1.0.0" });
await gloam.connect(new StdioClientTransport({ command, args }));
const call = async (name, args) => {
// A private payment builds its proofs on this machine and can take a few minutes: wait up to 5, not 60 seconds.
const out = await gloam.callTool({ name, arguments: args }, undefined, { timeout: 300_000 });
const text = out.content?.[0]?.text ?? "";
try {
return JSON.parse(text);
} catch {
return { status: "text", message: text };
}
};
try {
return await work(call);
} finally {
await gloam.close();
}
}
const wallet = () => new Aut({ privateKey: need("AUTONOMO_WALLET_KEY"), payWith: route, limits });
try {
if (route === "quote") {
const q = await new Aut().quote(QUERY);
console.log(`${q.api.name}: ${q.url}`);
for (const o of q.offers) console.log(` ${o.amount} ${o.token}${o.private ? " (private, through Gloam)" : ""}`);
} else if (route === "usdg" || route === "Aut") {
show(await wallet().call(QUERY));
} else if (route === "borro") {
const account = need("BORRO_CREDIT_LINE");
show(await new Aut({ privateKey: need("AUTONOMO_WALLET_KEY"), payWith: "usdg", borro: { account }, limits }).call(QUERY));
} else if (route === "gloam-shield") {
const amount = Number(arg ?? "0.05");
console.log(JSON.stringify(await withGloam((call) => call("gloam_execute_shield", { amount, network: "robinhood-mainnet" })), null, 2));
} else if (route === "gloam-balance") {
console.log(JSON.stringify(await withGloam((call) => call("gloam_list_notes", {})), null, 2));
} else if (route === "gloam-retry") {
// Presents the payment Gloam already made instead of paying again.
if (!arg) {
console.log("Pass the paymentHeader from the earlier result: node try-every-route.mjs gloam-retry <header>");
process.exit(1);
}
const { url } = await new Aut().quote(QUERY);
const r = await withGloam((call) => call("gloam_fetch_paid", { url, paymentHeader: arg, prefer: "gloam-cashout" }));
console.log(r.status === "ok" ? `Answered with the earlier payment: ${String(r.body ?? "").slice(0, 300)}` : `Not answered yet: ${JSON.stringify(r).slice(0, 500)}`);
} else if (route === "gloam") {
show(await withGloam((call) => new Aut({ gloam: { fetchPaid: (a) => call("gloam_fetch_paid", a) }, limits }).call(QUERY, { private: true })));
} else {
console.log("Use one of: quote, usdg, Aut, gloam-shield <amount>, gloam-balance, gloam, gloam-retry <header>, borro");
}
} catch (e) {
if (!(e instanceof AutonomoError)) throw e;
console.log(`\nNot paid (${e.code}): ${e.message}`);
}Limits
Every route checks both before anything is signed or sent. Set your own when you create the client:
| perCall / per_call | Most for one call. Default 0.05 USDG and 5,000 Aut |
| daily | Most per UTC day. Default 1 USDG and 10,000 AUTONOMO. Gloam and Borro payments count as USDG |
Today's spending is kept in ~/.autonomo/spend.json, shared by the TypeScript and Python SDKs. For a server with many agents, pass your own spendStore (spend_store).
The receipt
| api | The API's slug and name |
| route | usdg, Aut, gloam or borro |
| amount, token | What was paid |
| payer, payTo | The wallet, or "private (Gloam)", and the API's payment address |
| tx, explorer | The payment transaction and its Blockscout link |
| borrowTxs, approveTx | Borro borrows and the one-time Permit2 approval, when there were any |
| spentToday | Today's total against the daily budget |
Python uses snake_case for the same fields: pay_to, borrow_txs, approve_tx, spent_today.
Look before paying
find lists the APIs that match a request, and quote shows the API a call would use and every price, including the private one. Both are free and need no wallet. To skip the search, name the API with slug and path.
When a call isn't paid
Errors are an AutonomoError with a code and a plain reason, for example "the wallet holds 0 USDG, the call costs 0.01".
| cannot_pay | Over a limit, or the wallet can't afford any price the API takes. Nothing was signed |
| over_limit | A private call over a limit. Nothing was paid |
| no_private_option | The API doesn't offer Gloam. Nothing was paid |
| no_wallet / no_gloam | A key or the Gloam setup is missing |
| borro_refused | Borro refused the borrow, with its reason. Nothing was paid |
| payment_refused | The payment was refused, with the reason. You weren't charged |
| paid_not_served | Gloam paid but the API hadn't answered yet. Retry with the payment header it gives; don't pay again |
Prefer no code? The MCP server gives Claude, Cursor and Codex the same APIs as tools.