Pay per call. Nothing else.
Every service on BotTrunk is an HTTP endpoint that answers 402 Payment Required until it's paid in USDC. No API keys, no accounts, no invoices — the payment is the authentication.
How a paid call works
The x402 protocol turns the HTTP status code that was reserved for this in 1997 into a real payment flow. Four steps, about four seconds on Algorand:
- Ask. Your agent calls the endpoint. It gets a 402 whose body says what to pay, to whom, on which network.
- Pay. The agent signs a USDC transfer for that amount and retries the same request with an X-PAYMENT header.
- Verify & fulfil. We check the payment with the facilitator, then run the service upstream. Nothing is charged if the upstream fails.
- Settle. The transfer is submitted on-chain. The response carries an X-PAYMENT-RESPONSE header with the transaction id.
Connect your agent
Any x402-capable client handles the 402 → pay → retry dance for you. Pick the one that matches your stack.
// Claude Desktop, Cursor, or any MCP host. One server, every service as a tool.
{
"mcpServers": {
"bottrunk": { "url": "https://mcp.bottrunk.com" }
}
}
# pip install x402 py-algorand-sdk
from x402.clients import requests as x402_requests
session = x402_requests.x402_http_adapter(account) # your agent's Algorand account
r = session.post("https://api.bottrunk.com/s/scrape-markdown",
json={"url": "https://example.com/pricing"})
print(r.json()["markdown"])
print(r.headers["X-PAYMENT-RESPONSE"]) # settlement receipt
// npm install @x402-avm/fetch
import { wrapFetchWithPayment } from "@x402-avm/fetch";
const fetchWithPay = wrapFetchWithPayment(fetch, account);
const r = await fetchWithPay("https://api.bottrunk.com/s/scrape-markdown", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ url: "https://example.com/pricing" }),
});
console.log(await r.json());
# 1. Ask — you get the 402 shown below.
curl -X POST https://api.bottrunk.com/s/scrape-markdown \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/pricing"}'
# 2. Pay and retry with the signed transfer, base64-encoded.
curl -X POST https://api.bottrunk.com/s/scrape-markdown \
-H "Content-Type: application/json" \
-H "X-PAYMENT: <base64 payment payload>" \
-d '{"url": "https://example.com/pricing"}'
Your agent's wallet needs a little ALGO for fees and must be opted in to the USDC asset (31566704 on MainNet, 10458941 on TestNet). That's a one-time transaction from any Algorand wallet.
The 402 response
This is what scrape-markdown answers today when called without payment. amount is in atomic units — 5000 µUSDC is $0.005.
{
"x402Version": 2,
"error": "Payment required",
"accepts": [
{
"scheme": "exact",
"network": "algorand:SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=",
"asset": "10458941",
"amount": "5000",
"payTo": "UTWS33TM7IT7NINJSFWS5KVGL73G4ERJMYDKHF7KE4WDXHYO4L7V2PNMRE",
"maxTimeoutSeconds": 60,
"resource": "https://api.bottrunk.com/s/scrape-markdown",
"description": "Any public page as clean, LLM-ready markdown.",
"mimeType": "application/json",
"extra": {
"decimals": 6,
"tag": "x402-global-challenge"
}
}
],
"extensions": {
"bazaar": {
"info": {
"input": {
"type": "http",
"method": "POST",
"params": {
"url": "string",
"render_js": "boolean",
"selector": "string"
}
},
"output": {
"schema": {
"type": "object",
"properties": {
"markdown": {
"type": "string",
"description": "Body content as GitHub-flavored markdown."
},
"title": {
"type": "string",
"description": "Document title."
},
"word_count": {
"type": "integer",
"description": "Words in markdown, for budgeting tokens."
}
}
}
}
}
}
}
}
| scheme | string | Always exact: pay exactly the amount, nothing is metered. |
| network | string | CAIP-2 id of the chain. Algorand MainNet or TestNet. |
| asset | string | USDC asset id on that network. |
| amount | string | Price in atomic units (6 decimals). |
| payTo | string | BotTrunk's receiving address. Never send anywhere else. |
| maxTimeoutSeconds | integer | How long the payment stays valid. |
| extensions.bazaar | object | Input/output schema so agents can discover and call the service without reading this page. |
The payment header
X-PAYMENT is base64 of a JSON object carrying the signed Algorand transaction group. Clients build it; you only need to know the shape if you're writing one.
{
"x402Version": 2,
"scheme": "exact",
"network": "algorand:SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=",
"payload": {
"paymentGroup": ["<base64 msgpack of the signed USDC transfer>"],
"paymentIndex": 0
}
}
On success the response carries X-PAYMENT-RESPONSE: base64 JSON with success, transaction (the Algorand txn id), network and payer. If verification fails you get the 402 again with an error; if the upstream service fails you get a 502 and are not charged.
Networks
| Network | CAIP-2 id | USDC asset |
|---|---|---|
| Algorand Mainnet | algorand:wGHE2Pwdvd7S12BL5FaOP20EGYesN73ktiC1qzkkit8= | 31566704 |
| Algorand Testnet (current) | algorand:SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI= | 10458941 |
Payments are verified and settled by the GoPlausible facilitator. BotTrunk never holds your keys and never holds your funds: the transfer goes from your wallet to the receiving address in one on-chain transaction.
Catalog API
The same list as the home page, for machines. Public, no payment needed.
curl https://bottrunk.com/api/v1/catalog # every service curl https://bottrunk.com/api/v1/catalog?category=Data # filtered curl https://bottrunk.com/api/v1/catalog/scrape-markdown # one, with input/output schema