BUSK
ProofOpen app

Agent API

Agents buy finished work from shops people own

Your agent asks a shop for a capped quote, signs one Solana transaction that holds the USDC in escrow, and collects the files when the shop delivers. Settlement runs on chain, under the same rules as an order from a person.

Proven on Solana mainnetRecordSolscan

Order BSK-FTM3WG8Q at Ledger Cards: quoted, paid into escrow and delivered through this API, 1.00 USDC.

The shop's hatch: handed over
  1. BSK-FTM3WG8Qagent order
  2. Ledger Cards / Wallet recap card
  3. POST /agent/orders/quote201
  4. total 1.00 USDC, cap 1.00 USDC
  5. POST /agent/orders202
  6. solana-escrow, 1000000 base units
  7. escrow 7SkbsH...yfJk
  8. sign, POST .../submit200
  9. paid 5hwgwQ2n...mjzTxe
  10. mark_deliveredon chain
  11. delivered 22XYDtqh...7pDXB4
  12. hash bfd8d6e9...92dfb6
  13. confirm window72 h
  14. settles by 2026-10-22 14:39 UTC
  15. Solana mainnetOpen the record

How an agent order runs

Your code talks to BUSK over HTTPS. Money moves only through the BUSK orders program: from the agent wallet into the order's own escrow, and out of it to the shop at settlement or back to the agent wallet on a refund.

Quote valid
15 min
Confirm window
72 h
Fee ceiling per escrow
10 %
Requests per key
60 / min
  1. Your agent to BUSK: POST /agent/orders/quoteshop, product, options
  2. BUSK to Your agent: 201 quotetotal = cap, valid 15 min
  3. Your agent to BUSK: POST /agent/ordersquoteId, material
  4. BUSK to Your agent: 202 place_order txaccepts: mint, amount, escrow
  5. Your agent to Your agent: sign at index 0the agent wallet pays the fee
  6. Your agent to BUSK: POST .../submitsignedTx
  7. BUSK to Solana: co-sign and sendUSDC into the order's vault
  8. BUSK to BUSK: the shop makes itinside the quoted cost
  9. BUSK to Solana: mark_delivereddelivery hash, 72 h window opens
  10. Your agent to BUSK: GET order, filessame Bearer key
  11. BUSK to Solana: settle_orderon your confirm, or after 72 h

Quickstart

Every call below is shown in TypeScript (@solana/web3.js, tweetnacl, bs58) and curl. The TypeScript steps run in order as one script; steps 1 to 4 send no transaction. You need Node 20 or later and an agent wallet that holds the quoted USDC plus a little SOL for the network fee and the escrow rent, which comes back to it.

success  { "ok": true,  "data": ... }
failure  { "ok": false,
           "error": { "code": "QUOTE_EXPIRED", "message": "This quote expired. Ask for a new one." } }

Step 1: Sign in with the wallet that will own the key

POST/api/auth/nonceNo authPOST/api/auth/verifyNo auth

Keys are made by a wallet session. Ask for a one-time Sign-In With Solana message, sign its exact bytes with the wallet's ed25519 key and send the signature back (base58 or base64). The answer sets an rt_session cookie, valid 7 days. Signing in sends no transaction and costs nothing.

The message names the site it was made for, so send both calls to the same host. A nonce is good for 5 minutes and one use.

// Sign-In With Solana: sign the exact message bytes, keep the rt_session cookie.
async function signIn(kp: Keypair): Promise<string> {
  const wallet = kp.publicKey.toBase58();
  const { data: n } = await api<{ nonce: string; message: string }>("POST", "/api/auth/nonce", { body: { wallet } });
  const signature = bs58.encode(nacl.sign.detached(new TextEncoder().encode(n.message), kp.secretKey));
  const v = await api("POST", "/api/auth/verify", { body: { wallet, nonce: n.nonce, signature } });
  return v.headers.getSetCookie().map((c) => c.split(";")[0]).join("; ");
}
const ownerSession = await signIn(owner);
200POST /api/auth/nonce, recorded on busk.live
{
  "ok": true,
  "data": {
    "nonce": "3e2f77e3c2bb6e669cb65ee961d88999",
    "message": "busk.live wants you to sign in with your Solana account:\n3XhfkLat9rwbY9UxgsbFqLvGsXZwgEzPfwDokTo8FKkm\n\nSign in with your wallet. This request does not trigger a transaction or cost any fees.\n\nURI: https://busk.live\nVersion: 1\nNonce: 3e2f77e3c2bb6e669cb65ee961d88999\nIssued At: 2026-10-19T19:05:15.800Z\nExpiration Time: 2026-10-19T19:10:15.800Z",
    "expiresAt": "2026-10-19T19:10:15.800Z"
  }
}

Step 2: Create an agent key with its spending caps

POST/api/v1/studio/agent-keysWallet session

Every key carries two caps in USD: perOrderUsd (0.1 to 1,000) and dailyUsd (at least the per-order cap, up to 10,000 per UTC day). A key without caps is refused. Name an agentWallet to bind the key to the wallet that pays; leave it out and every quote and order request names its own agentWallet instead.

The key (busk_ak_...) is returned once and only its sha256 is stored. A wallet holds up to 10 active keys. Revoke one with DELETE /api/v1/studio/agent-keys/{id}; it stops working at once.

const { data: created } = await api<{ id: string; key: string }>("POST", "/api/v1/studio/agent-keys", {
  cookie: ownerSession,
  body: { label: "recap agent", perOrderUsd: 5, dailyUsd: 20, agentWallet: agent.publicKey.toBase58() },
});
const KEY = created.key; // shown once: keep it as a secret (only its sha256 is stored)
201recorded on busk.live, key value withheld (that key is revoked)
{
  "ok": true,
  "data": {
    "id": "a6836173-7b2c-4ef5-8cd2-ae159ca7c5b6",
    "key": "busk_ak_<shown once>",
    "label": "docs check",
    "agentWallet": "8F2Vpn15oi1t2SBZxN6HLyjHBwzRGsD9C3R8YvLnkzgY",
    "perOrderUsd": 2,
    "dailyUsd": 5,
    "createdAt": "2026-10-19T19:05:16.379Z"
  }
}

Step 3: Find a shop and a product

GET/api/v1/shopsNo authGET/api/v1/shops/{slug}No auth

The street lists shops that are open on chain with at least one live product. Filter with kind=reaction-pack or kind=wallet-recap, search with q, sort by orders, newest, price or speed.

A shop's products carry their option list: each option has an id, a type (choice, toggle or count), its price (addUsd on a choice or toggle, unitUsd per unit on a count) and its default. Send option ids and values in the quote; anything left out takes the default.

type Product = { id: string; kind: "reaction-pack" | "wallet-recap"; name: string; options: unknown[] };
const { data: shops } = await api<{ slug: string }[]>("GET", "/api/v1/shops?kind=wallet-recap");
const { data: shop } = await api<{ slug: string; products: Product[] }>("GET", `/api/v1/shops/${shops[0].slug}`);
const product = shop.products.find((p) => p.kind === "wallet-recap")!;
200GET /api/v1/shops/ledger-cards on busk.live, abridged to the fields an agent needs
{
  "ok": true,
  "data": {
    "slug": "ledger-cards",
    "name": "Ledger Cards",
    "tier": "standard",
    "status": "open",
    "turnaroundMin": 5,
    "products": [
      {
        "id": "f02430d5-1732-40fd-ab7b-e73e45a1c8c9",
        "kind": "wallet-recap",
        "name": "Wallet recap card",
        "deliverables": ["Card, PNG", "Source sheet, PDF", "Sources, JSON with Solscan links"],
        "baseUsd": 1,
        "options": [
          { "id": "period", "type": "choice", "default": "30d",
            "choices": [{ "id": "7d", "addUsd": 0 }, { "id": "30d", "addUsd": 0.2 }, { "id": "90d", "addUsd": 0.5 }] },
          { "id": "format", "type": "choice", "default": "post",
            "choices": [{ "id": "post", "addUsd": 0 }, { "id": "story", "addUsd": 0.2 }] },
          { "id": "holdings", "type": "toggle", "default": true, "addUsd": 0 },
          { "id": "backdrop", "type": "toggle", "default": false, "addUsd": 0.2 }
        ]
      }
    ]
  }
}

Step 4: Ask for a quote

POST/api/v1/agent/orders/quoteAgent key

The server prices the product from the shop's current price and the options you send, and returns the total, the cap and the split between generation cost, platform fee and the shop. The cap equals the total: the escrow is funded with exactly that amount and nothing more is ever charged.

A quote is valid for 15 minutes, can be used once, and only by the key that asked for it. Pro and Max shops take an optional presetId for one of their brand presets.

const { data: quote } = await api<{ quoteId: string; totalUsd: number; capUsd: number; validUntil: string }>(
  "POST", "/api/v1/agent/orders/quote",
  { key: KEY, body: { shopSlug: shop.slug, productId: product.id, options: { period: "7d", format: "post", holdings: true, backdrop: false } } },
);
console.log(`quote ${quote.totalUsd} USDC, cap ${quote.capUsd}, valid until ${quote.validUntil}`);
201recorded on busk.live with an agent key
{
  "ok": true,
  "data": {
    "productId": "f02430d5-1732-40fd-ab7b-e73e45a1c8c9",
    "shopSlug": "ledger-cards",
    "options": { "format": "post", "period": "7d", "backdrop": false, "holdings": true },
    "lines": [{ "id": "base", "label": "Wallet recap card", "amountUsd": 1 }],
    "totalUsd": 1,
    "capUsd": 1,
    "split": { "generationUsd": 0, "platformFeeUsd": 0.1, "platformFeePct": 10, "shopUsd": 0.9 },
    "currency": "USDC",
    "turnaroundMin": 5,
    "validForMin": 15,
    "validUntil": "2026-10-19T19:20:17.197Z",
    "preset": null,
    "quoteId": "811057aa-fa1a-4e6f-abee-4615a72a4653"
  }
}

Step 5: Reaction packs: upload the reference images

POST/api/v1/uploadsSession or key

A reaction pack is drawn from 1 to 3 reference images of a mascot you own or license. Upload each one as multipart form data (field file, PNG, JPEG or WebP, up to 5 MB) with the same agent key; the order may only use uploads made by that key.

The material for a reaction pack is { refs, rightsConfirmed: true, reactions? } with up to one reaction label per sticker (letters, digits, space and ! ? ' -, 1 to 24 characters). A wallet recap card takes { wallet } instead: any public Solana wallet.

// Reaction packs only: upload 1-3 reference images with the same key first.
const form = new FormData();
form.append("file", new Blob([readFileSync("mascot.png")], { type: "image/png" }), "mascot.png");
const up = await fetch(BASE + "/api/v1/uploads", { method: "POST", headers: { authorization: `Bearer ${KEY}` }, body: form });
const { data: upload } = (await up.json()) as { data: { ref: string; sha256: string; bytes: number } };
// material for a reaction pack: { refs: [upload.ref], rightsConfirmed: true, reactions: ["gm", "wagmi"] }
201shape from app/api/v1/uploads/route.ts
{
  "ok": true,
  "data": { "ref": "up-<uuid>/<sha256>.png", "sha256": "<sha256 of the file>", "bytes": 48213 }
}

Step 6: Place the order and get the payment transaction

POST/api/v1/agent/ordersAgent key

The answer is 202 with the order id, an unsigned place_order transaction for the agent wallet, and an accepts entry that states the payment: scheme solana-escrow, the USDC mint, the amount in base units (6 decimals) and the escrow account that will hold it.

The key's caps are checked here: a total above perOrderUsd, or above what is left of dailyUsd for the UTC day, is refused with 403 AGENT_CAP. The order counts toward the daily cap when it is created. Calling again with the same quoteId while the order is unpaid returns the same order with a fresh transaction.

type Accept = { scheme: "solana-escrow"; mint: string; amount: string; recipient: string; quoteId: string };
const { data: order } = await api<{ orderId: string; tx: string; validUntil: string; accepts: Accept[] }>(
  "POST", "/api/v1/agent/orders",
  { key: KEY, body: { quoteId: quote.quoteId, material: { wallet: agent.publicKey.toBase58() } } },
);
console.log(`${order.orderId}: ${order.accepts[0].amount} base units into escrow ${order.accepts[0].recipient}`);
202values of the mainnet agent order BSK-FTM3WG8Q (its escrow and mint as read on chain)
{
  "ok": true,
  "data": {
    "orderId": "BSK-FTM3WG8Q",
    "tx": "<base64 place_order transaction, unsigned>",
    "validUntil": "<the quote's validUntil>",
    "accepts": [
      {
        "scheme": "solana-escrow",
        "mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
        "amount": "1000000",
        "recipient": "7SkbsHpr6ghf8Y2oQmevdfwMdAbRXfxhntwtbcp3yfJk",
        "quoteId": "<the quote's id>"
      }
    ]
  }
}

Step 7: Sign with the agent wallet and submit

POST/api/v1/agent/orders/{id}/submitAgent key

The agent wallet is account 0: it pays the network fee and the rent of the escrow and its vault (both come back to it when the order settles or is refunded), and it signs first. The server checks that the instructions, accounts and blockhash are the ones it issued, adds its own signature last and sends the transaction.

Your wallet may add ComputeBudget instructions before or after the block, or a Lighthouse assertion after it. Anything else (a new signer, a new writable account, another blockhash, address lookup tables) is refused with 400 TX_REJECTED.

200 means the escrow is funded. 202 means sent and not confirmed yet: call again with the same body, which re-checks the same signature and never sends a second payment. On TX_FAILED or TX_EXPIRED, POST /api/v1/agent/orders again with the same quoteId for a new transaction.

const tx = VersionedTransaction.deserialize(Buffer.from(order.tx, "base64"));
tx.sign([agent]); // the agent wallet signs first; the server checks the bytes and signs last
const signedTx = Buffer.from(tx.serialize()).toString("base64");
let paid = await api<{ signature: string }>("POST", `/api/v1/agent/orders/${order.orderId}/submit`, { key: KEY, body: { signedTx } });
while (paid.status === 202) {
  await sleep(2000); // sent, not confirmed yet: the same body re-checks it and never sends twice
  paid = await api<{ signature: string }>("POST", `/api/v1/agent/orders/${order.orderId}/submit`, { key: KEY, body: { signedTx } });
}
console.log("paid into escrow", `https://solscan.io/tx/${paid.data.signature}`);
200the payment signature of BSK-FTM3WG8Q on mainnet
{
  "ok": true,
  "data": {
    "signature": "5hwgwQ2nRPMmTrBxknK58cXB8uuptZrucApBfd4miA3kSouBspB3MV1UkCuyjJX2HPFuDDc2i1fEM3RbkWmjzTxe",
    "order": { "id": "BSK-FTM3WG8Q", "state": "order", "buyerKind": "agent", "...": "the full order, as in step 8" }
  }
}

Step 8: Track the order and collect the files

GET/api/v1/agent/orders/{id}Agent keyGET/api/v1/files/{orderId}/{file}Session or key

Poll the order. Its state moves order (paid into escrow) -> making -> handoff (delivered) -> settled; it can end failed, refunded or cancelled. Each delivered file is a deliverable whose art.url is a same-origin path; fetch it with the same Bearer key.

When the shop delivers, the server writes a delivery hash on chain with mark_delivered: sha256 over the lines name:sha256 of every file, sorted by name and joined with a newline. Hash the files you received the same way to check them against the chain.

type Art = { kind: string; url?: string };
type OrderView = { state: string; deliverables: { id: string; name: string; art: Art }[]; proofTx: string | null };
let view: OrderView;
do {
  await sleep(5000);
  view = (await api<OrderView>("GET", `/api/v1/agent/orders/${order.orderId}`, { key: KEY })).data;
} while (!["handoff", "settled", "failed", "refunded", "cancelled"].includes(view.state));
for (const d of view.deliverables) {
  if (d.art.kind !== "asset" || !d.art.url) continue;
  const file = await fetch(BASE + d.art.url, { headers: { authorization: `Bearer ${KEY}` } });
  writeFileSync(d.id, Buffer.from(await file.arrayBuffer()));
}
console.log(view.state, view.proofTx ? `${BASE}/proof/tx/${view.proofTx}` : "");
200BSK-FTM3WG8Q after delivery, abridged
{
  "ok": true,
  "data": {
    "id": "BSK-FTM3WG8Q",
    "shopSlug": "ledger-cards",
    "productName": "Wallet recap card",
    "buyer": "5pg95PA4XTGg8NHoQAoW72Mjq4b7wpfUKTov8vxugzW4",
    "buyerKind": "agent",
    "state": "handoff",
    "quote": { "totalUsd": 1, "capUsd": 1, "currency": "USDC" },
    "deliverables": [
      { "id": "recap-card.png", "name": "Wallet recap (recap-card.png)", "format": "PNG", "sizeLabel": "199 KB",
        "art": { "kind": "asset", "url": "/api/v1/files/BSK-FTM3WG8Q/recap-card.png", "mime": "image/png" } },
      { "id": "sources.pdf", "name": "Source sheet (sources.pdf)", "format": "PDF", "sizeLabel": "128 KB",
        "art": { "kind": "asset", "url": "/api/v1/files/BSK-FTM3WG8Q/sources.pdf", "mime": "application/pdf" } },
      { "id": "sources.json", "name": "Sources (sources.json)", "format": "JSON", "sizeLabel": "220 KB",
        "art": { "kind": "asset", "url": "/api/v1/files/BSK-FTM3WG8Q/sources.json", "mime": "application/json" } }
    ],
    "settlement": null,
    "events": [
      { "state": "order", "at": "2026-10-19T14:39:06.596Z", "note": "Payment held in escrow" },
      { "state": "handoff", "at": "2026-10-19T14:39:25.006Z", "note": "Delivered" }
    ],
    "proofTx": "22XYDtqhUzLxwr11JQVjoUnZ2itiSfXD4xPDaE6WjH1Dh3hL7WsFgDJ7PUwWDfvLqXjJUJobE61C81KrQo7pDXB4"
  }
}

Step 9: Settle early, or let the confirm window close

POST/api/v1/orders/{id}/confirmWallet sessionPOST/api/v1/orders/{id}/cancelWallet session

Delivery opens a 72-hour confirm window. When it closes the server settles the order on chain by itself. To settle sooner, sign in as the agent wallet (step 1 with that wallet) and confirm: {} returns the settle_order transaction, signing it and sending {signedTx} settles at once.

Before making starts, the same session can cancel: an unpaid order is dropped, a paid one is refunded in full to the agent wallet.

// Optional: accept the delivery now instead of waiting for the 72-hour window. Sign in as the agent wallet.
if (view.state === "handoff") {
  const agentSession = await signIn(agent);
  const { data: s } = await api<{ tx: string }>("POST", `/api/v1/orders/${order.orderId}/confirm`, { cookie: agentSession, body: {} });
  const settle = VersionedTransaction.deserialize(Buffer.from(s.tx, "base64"));
  settle.sign([agent]);
  const done = await api<{ signature: string }>("POST", `/api/v1/orders/${order.orderId}/confirm`, {
    cookie: agentSession,
    body: { signedTx: Buffer.from(settle.serialize()).toString("base64") },
  });
  console.log("settled", `https://solscan.io/tx/${done.data.signature}`);
}

Rules the counter keeps

Read from the API code and the orders program. They are the same for an agent and for a person.

  1. Quotevalid 15 min
  2. Paid, makingdeadline: turnaround + 24 h
  3. Deliveredconfirm window 72 h
  4. Settledshop paid, vault closed

Escrow

  • Every order is its own escrow account in the BUSK orders program, with a USDC vault the program controls. place_order moves exactly the quoted total from the agent wallet into the vault.
  • The escrow stores the quote hash, the generation cost, the fee ceiling (10 %), the delivery deadline and, after delivery, the delivery hash.
  • On settlement the vault pays the generation cost and the platform fee to the platform account and the rest to the shop's payout account, then closes; its rent returns to the agent wallet.

Caps

  • Key caps: perOrderUsd and dailyUsd are required on every key and checked on every order (403 AGENT_CAP).
  • Quote cap: the escrow holds the quoted total, which is also the cap. Generation runs inside the quoted generation cost and the shop's own spend cap.
  • Fee ceiling: the platform fee is judged at settlement from the shop's tier (10 % Standard, 8 % Pro, 6 % Max) and can never exceed the 10 % written into the escrow.

Clock

  • A quote is valid for 15 minutes; an order needs at least 1 minute left on it.
  • The delivery deadline is the product's turnaround plus 24 hours from the moment the order is created.
  • Delivery opens a 72-hour confirm window (the program's confirm_window_secs, 259200 on mainnet). The buyer may settle earlier; after it closes the server settles.

Refunds

  • Cancelled before making starts: refunded in full (POST /api/v1/orders/{id}/cancel as the agent wallet).
  • Generation failed: the server refunds the full amount.
  • Deadline passed with nothing delivered: the server refunds the full amount, and the program also lets the buyer wallet sign refund_order itself once the deadline has passed.
  • A refund returns the whole vault balance to the agent wallet's USDC account and the rent to the agent wallet.

Rate limits

Fixed 60-second windows. Over a limit the answer is 429 RATE_LIMITED with a retry-after header and details.retryAfterSec.

RequestsLimit
Every request with an agent key (quote, order, submit, order view, uploads, files)60 per minute per key
Uploads20 per minute per IP
Shops, shop pages, proof240 per minute per IP
Confirm, cancel, showcase30 per minute per IP
Creating agent keys10 per minute per IP
Sign-in nonce / verify20 / 30 per minute per IP

Error codes

Every failure is { ok: false, error: { code, message, details? } } with one of these codes.

StatusCodeWhen
400BAD_REQUESTA field is missing or malformed; the message names the field
400BAD_MATERIALmaterial.refs holds uploads made by another key
400BAD_TXsignedTx is not a base64 transaction
400TX_REJECTEDThe signed transaction differs from the one issued beyond the allowed additions
401UNAUTHORIZEDNo key, an unknown key or a revoked key (or no session where one is needed)
403FORBIDDENThe key is bound to another agent wallet
403AGENT_CAPThe total is above the key's per-order cap or the rest of its daily cap
403TIER_REQUIREDpresetId was sent to a Standard shop
404NOT_FOUNDUnknown shop, product, quote or order, or one this key did not create
409SHOP_PAUSEDThe shop is not taking orders right now
409PRODUCT_UNAVAILABLEThe product is not on sale right now
409QUOTE_EXPIREDLess than a minute left on the quote; ask for a new one
409QUOTE_USEDThe quote already belongs to another order
409ORDER_PLACEDThe order is already paid
409NO_PENDING_TXSubmit came before the order transaction was issued
409TX_FAILEDThe payment failed on chain (for example another order took the same order id); ask for a new transaction
409TX_EXPIREDThe blockhash expired before the payment landed; ask for a new transaction
409NOT_DELIVEREDConfirm before delivery
409CANNOT_CANCELMaking has started or the order is past the paid state
413PAYLOAD_TOO_LARGEAn upload over 5 MB or a body over its limit
429RATE_LIMITEDOver a rate limit; wait retry-after seconds
503CHAIN_LAGGINGAn account is not readable at the needed slot yet; retry shortly

Proven on Solana mainnet

Agent order BSK-FTM3WG8Q went through every call on this page: an agent key, a quote, a place_order transaction signed by the agent wallet, delivery by the shop with the hash written on chain.

BSK-FTM3WG8QLedger Cards / Wallet recap card / 1.00 USDC / ordered by an agent
  1. Paid into escrow2026-10-19 14:39 UTCSolscanRecord5hwgwQ2nRPMmTrBxknK58cXB8uuptZrucApBfd4miA3kSouBspB3MV1UkCuyjJX2HPFuDDc2i1fEM3RbkWmjzTxe
  2. Delivered2026-10-19 14:39 UTCSolscanRecord22XYDtqhUzLxwr11JQVjoUnZ2itiSfXD4xPDaE6WjH1Dh3hL7WsFgDJ7PUwWDfvLqXjJUJobE61C81KrQo7pDXB4
Delivery hash
bfd8d6e9307c4c2462d41d53eeba4f3cf86788f96f4700a971dd966fcf92dfb6
Delivered files
recap-card.png, sources.pdf, sources.json
Check the delivery yourself: the three files on the record hash to the delivery hash in the escrow.
cd "$(mktemp -d)"
for f in recap-card.png sources.json sources.pdf; do curl -sO https://busk.live/api/v1/proof/files/BSK-FTM3WG8Q/$f; done
for f in recap-card.png sources.json sources.pdf; do echo "$f:$(sha256sum $f | cut -d' ' -f1)"; done | head -c -1 | sha256sum
# bfd8d6e9307c4c2462d41d53eeba4f3cf86788f96f4700a971dd966fcf92dfb6

The full record, with the delivered card the buyer chose to show: busk.live/proof/tx/22XYDtqhUz...KrQo7pDXB4

For machines

  • /llms.txt

    This page as plain text: the flow, every endpoint, the rules, limits, error codes and the quickstart script.

    curl -s https://busk.live/llms.txt
  • /agents/openapi.json

    OpenAPI 3.1 for the routes an agent calls, with the request bodies and the response envelope.

    curl -s https://busk.live/agents/openapi.json
  • /api/v1/proof

    Every transaction BUSK recorded, agent orders included, with its Solscan link.

    curl -s https://busk.live/api/v1/proof

The street is open: pick a shop, ask for a quote and let your agent pay into escrow.

Agent API | BUSK