$AUTCATBA
Aut
Launch
BSCBNB Smart Chain · Native currency BNB

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 APIFrom your words and the kind of input: a token or wallet address, a transaction hash or a link
PaysIn USDG, or $AUTONOMO when the wallet has no USDG
PrivatelyThrough Gloam, so the payment doesn't link to your wallet
On creditBorrows from a Borro credit line when the wallet is short of USDG
Within limitsA most-per-call and a daily budget, checked before anything is signed
ReceiptWhich API, how it was paid, the amount and the transaction link

Install

bash
npm install autonomo-sdk
bash
pip install autonomo-sdk

TypeScript 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.

TypeScript
// 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);
Python
"""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/agent.env
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=any

02Fund 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

TypeScript
// 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();
Python
"""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, npx is a script, so the TypeScript example starts the server through cmd /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.

TypeScript
// 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
Python
"""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 borro when it borrowed, with the borrow transaction, or usdg when 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

bash
mkdir try-autonomo && cd try-autonomo
npm init -y
npm install autonomo-sdk @modelcontextprotocol/sdk

Save 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.

bash
node try-every-route.mjs quote

02Pay 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.

bash
# macOS and Linux
export AUTONOMO_WALLET_KEY=0x…

# Windows PowerShell
$env:AUTONOMO_WALLET_KEY = "0x…"
bash
node try-every-route.mjs usdg
node try-every-route.mjs Aut

On 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.env as 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 no AUTONOMO_WALLET_KEY.
  • Gloam's own limits must allow the payment: USDG as the asset, at least 0.011 per payment, and recipients any. 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.
bash
node try-every-route.mjs gloam-shield 0.05
node try-every-route.mjs gloam-balance
node try-every-route.mjs gloam

Deposit, 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:

bash
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_KEY is the agent wallet set on the line, not the line's owner, and BORRO_CREDIT_LINE is 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, not borro. 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.
bash
# 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 borro

It 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-route.mjs
// 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_callMost for one call. Default 0.05 USDG and 5,000 Aut
dailyMost 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

apiThe API's slug and name
routeusdg, Aut, gloam or borro
amount, tokenWhat was paid
payer, payToThe wallet, or "private (Gloam)", and the API's payment address
tx, explorerThe payment transaction and its Blockscout link
borrowTxs, approveTxBorro borrows and the one-time Permit2 approval, when there were any
spentTodayToday'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_payOver a limit, or the wallet can't afford any price the API takes. Nothing was signed
over_limitA private call over a limit. Nothing was paid
no_private_optionThe API doesn't offer Gloam. Nothing was paid
no_wallet / no_gloamA key or the Gloam setup is missing
borro_refusedBorro refused the borrow, with its reason. Nothing was paid
payment_refusedThe payment was refused, with the reason. You weren't charged
paid_not_servedGloam 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.