One dollar, one signature, one key.
$1.00 USDC on Base mainnet buys 400 credits; an MCP tool call costs 3 credits (about 133 calls). The key you get back works in any MCP client. No account, no card, no ETH: just USDC on Base. Not sure yet? 20 free tool calls per UTC day, no key or wallet needed.
What you are buying
Credits are prepaid call units on the hosted naxytra runtime and MCP server. A top-up is $1.00 USDC on Base mainnet (one x402 payment) and grants 400 credits; 1 credit = $0.0025. An MCP tool call costs 3 credits ($0.0075, versus $0.01 paying per call); other runtime tasks cost 1-8 credits by tier. A failed call never consumes credits.
- The spend key (xytara_spend_<hex>) is what your MCP client sends with each call: Authorization: Bearer <key>, or X-Naxytra-Key, or ?key= on the MCP URL for clients that cannot set headers.
- The key is shown once, at purchase. It is not stored by this page and cannot be re-displayed; anyone holding it can spend the credits, so keep it secret and ask support to revoke it if it leaks.
- Before you buy: 20 free tool calls per UTC day, no key or wallet needed. The MCP server reports the remaining free calls in each result's _meta["naxytra.com/allowance"].
- Credits are tied to the paying wallet address and are not transferable. An unused balance can be refunded within 14 days to the address that paid.
- Card checkout is coming.
Testnet and trying it out
Credit top-ups are Base mainnet only: Base Sepolia (testnet) top-ups are not enabled, because free test USDC must not buy credits spendable on real provider work. To try the tools without paying, use the free daily allowance: connect any MCP client with no key and make up to 20 calls per UTC day. Pay-per-call x402 on Base Sepolia ($0.001 per call) remains available for agents that want to exercise the payment path with test USDC.
Connect a client (no key needed) · curl quickstart · Base Sepolia USDC faucet
Pay $1.00 USDC on Base and get a key
Connect an injected wallet (MetaMask, Coinbase Wallet, Rabby), sign one gasless USDC authorization, and the runtime returns your spend key with 400 credits. You need $1.00 of USDC on Base mainnet and nothing else: no ETH for gas, no account. The signature is a transfer authorization for exactly 1000000 USDC base units ($1.00) to 0x7cd2E0Ed2721319B20FAac4109774d030833F84D; the runtime's own 402 challenge is authoritative and is what this page signs.
- Connect your wallet and switch it to Base (chain 8453) if asked.
- Sign the $1.00 USDC authorization when your wallet shows it (EIP-712 "TransferWithAuthorization" on the USD Coin contract).
- Copy your key. It is shown once; this page does not store it and never puts it in a URL.
Keep the key secret: anyone holding it can spend these credits. On /setup, paste it into the box and every client snippet fills itself in. Settlement transaction:
No wallet extension was found in this browser. Install MetaMask, Coinbase Wallet or Rabby, or use the Node snippet below with a wallet key.
How many credits are left on a key?
Paste a spend key. It is sent only to the runtime's balance endpoint (GET https://xytara.onrender.com/v1/credits/balance) as the Authorization header; it does not leave your browser otherwise and is not stored.
curl -s https://xytara.onrender.com/v1/credits/balance \
-H "Authorization: Bearer YOUR_KEY"
# -> {"ok":true,"account_id":"0x...","available_units":400,"credits_per_call":3,...}
Buy from a script instead
If your agent already holds a funded wallet, do the same three requests from Node: fetch the 402, sign the EIP-712 authorization, POST it with the PAYMENT-SIGNATURE header. The response's spend_credential.bearer_token is the key; store it with the same care as the wallet key. The public integration guide at github.com/naxytra/naxytra-mcp shows the same flow inside an MCP client.
// Buy 400 credits ($1.00 USDC on Base mainnet) from a wallet key and print the spend key.
// Node 20+. npm i viem@2.21.55 (BUYER_PRIVATE_KEY holds USDC on Base; no ETH is needed, the facilitator pays gas)
import { privateKeyToAccount } from "viem/accounts";
import { randomBytes } from "node:crypto";
const TOPUP = "https://xytara.onrender.com/x402/credits/topup";
const account = privateKeyToAccount(process.env.BUYER_PRIVATE_KEY);
// 1. Unpaid POST -> 402 with the exact terms (network, asset, amount, payTo).
const quote = await fetch(TOPUP, { method: "POST", headers: { "content-type": "application/json" }, body: "{}" });
if (quote.status !== 402) throw new Error("expected 402, got " + quote.status + " " + (await quote.text()));
const { payment_required } = await quote.json();
const accept = payment_required.accepts.find((a) => a.network === "eip155:8453" && a.scheme === "exact");
// 2. Sign one gasless USDC authorization (EIP-3009 TransferWithAuthorization, EIP-712).
const now = Math.floor(Date.now() / 1000);
const authorization = {
from: account.address,
to: accept.payTo,
value: accept.amount,
validAfter: "0",
validBefore: String(now + (accept.maxTimeoutSeconds || 300) - 30),
nonce: "0x" + randomBytes(32).toString("hex")
};
const signature = await account.signTypedData({
domain: { name: accept.extra.name, version: accept.extra.version, chainId: 8453, verifyingContract: accept.asset },
types: {
TransferWithAuthorization: [
{ name: "from", type: "address" }, { name: "to", type: "address" }, { name: "value", type: "uint256" },
{ name: "validAfter", type: "uint256" }, { name: "validBefore", type: "uint256" }, { name: "nonce", type: "bytes32" }
]
},
primaryType: "TransferWithAuthorization",
message: { ...authorization, value: BigInt(authorization.value), validAfter: 0n, validBefore: BigInt(authorization.validBefore) }
});
const paymentSignature = Buffer.from(JSON.stringify({ x402Version: 2, accepted: accept, payload: { signature, authorization } })).toString("base64");
// 3. Paid POST -> 200 with the spend key (shown once) and the credit grant.
const paid = await fetch(TOPUP, { method: "POST", headers: { "content-type": "application/json", "PAYMENT-SIGNATURE": paymentSignature }, body: "{}" });
const result = await paid.json();
if (!paid.ok) throw new Error(paid.status + " " + result.reason + (result.detail ? ": " + result.detail : ""));
console.log("spend key (shown once, keep it secret):", result.spend_credential.bearer_token);
console.log("credits available:", result.balance.available_units);
On PowerShell set the key as its own statement: $env:BUYER_PRIVATE_KEY = "0x..."; node buy-credits.mjs. The xytara npm client's guided path (xytara first-run --execute-with-credits) spends credits on the runtime once you have a key.
Next: set up your client
Paste the key into the box on the setup page and copy the snippet for your client: Claude Desktop, Claude Code, Cursor, VS Code, Windsurf, LangChain, the OpenAI Agents SDK, or an x402-native client that pays per call without a key.