What integration means
Integrating payments into LlamaIndex means two related things: letting an agent pay for what it retrieves (a paid data source, an API, another agent), and, when you want it, charging other callers for a query engine you expose. The first is the common case, since LlamaIndex is built around retrieval and some of the best sources cost money; the second is the earn side, turning your index into a paid service.
This page is the integration reference: the pieces, how they fit, and where each path leads. For the step-by-step walkthrough of giving an agent a wallet, see how-to-add-payments-to-llamaindex-agent; for the same overview in a sibling framework, see crewai-payment-integration. The payment API product page is the broader reference. Here the focus is the shape of a LlamaIndex integration across both of its runtimes.
Two runtimes, two paths
The fact that shapes a LlamaIndex integration is that the framework ships in two runtimes: LlamaIndex in Python and LlamaIndex.TS in TypeScript. The payment packages, @blockchain0x/x402 and @blockchain0x/node, are Node, which means the two runtimes take two paths on the pay side.
In LlamaIndex.TS you are already in Node, so a tool calls the x402 client directly, in-process, with nothing extra to run. In Python LlamaIndex you call a small local Node proxy that holds the wallet, the same proxy used across the Python-framework integrations, because there is no Python payment package. Both end up exposing the identical pay-by-calling tool to the agent; only what sits under the tool differs. Knowing which runtime you are on tells you which path to take, and the earn side (a gateway) is the same for both.
The pay side in TypeScript
On LlamaIndex.TS, the wallet tool is a FunctionTool that calls createX402Client directly. No proxy, because you are in Node.
import { FunctionTool } from "llamaindex";
import { createClient } from "@blockchain0x/node";
import { createX402Client } from "@blockchain0x/x402/client";
const sdk = createClient({ apiKey: process.env.B0X_API_KEY! });
const fetchWithPay = createX402Client({ sdk });
export const payTool = FunctionTool.from(
async ({ url }: { url: string }) => {
const res = await fetchWithPay(url);
return res.ok ? await res.text() : `Failed: ${res.status}`;
},
{ name: "pay_and_fetch", description: "Fetch a URL, paying in USDC if required.", parameters: { type: "object", properties: { url: { type: "string" } }, required: ["url"] } },
);Add payTool to the agent's tools and it can pay for a retrieval in the same process. This is the cleanest path, with no extra service, and it is unique to the TypeScript runtime.
The pay side in Python
On Python LlamaIndex, the wallet tool is a FunctionTool whose body calls the local Node proxy, since the client is Node-only.
import requests
from llama_index.core.tools import FunctionTool
def pay_and_fetch(url: str) -> str:
"""Fetch a URL, paying in USDC if it requires payment. Returns the body."""
res = requests.post("http://127.0.0.1:8787", json={"url": url}, timeout=30)
return res.text if res.status_code == 200 else f"Failed: {res.status_code}"
pay_tool = FunctionTool.from_defaults(fn=pay_and_fetch)Start the proxy (the thirty-line service from the walkthrough), add pay_tool to a FunctionAgent, and the Python agent pays exactly as the TypeScript one does. To the agent the two are indistinguishable; the proxy is just the bridge the Python runtime needs.
The earn side
To charge for a query engine, expose it over HTTP and front it with a small Node gateway running createX402Plugin. This is the same for both runtimes, because the gateway sits in front of whatever serves the query engine.
import Fastify from "fastify";
import { createClient } from "@blockchain0x/node";
import { createX402Plugin } from "@blockchain0x/x402/server/fastify";
const sdk = createClient({ apiKey: process.env.B0X_API_KEY! });
const app = Fastify();
await app.register(createX402Plugin, {
sdk,
defaultNetwork: "testnet",
pricing: { "POST /query": { amountUsdc: "0.05", payToAddress: process.env.B0X_PAYTO_ADDRESS!, paymentRequestId: "pr_query" } },
});
app.post("/query", async (req) => {
const r = await fetch("http://127.0.0.1:8000/query", { method: "POST", body: JSON.stringify(req.body) });
return await r.json();
});
await app.listen({ port: 8080 });An unpaid POST /query gets a 402; a paid one runs your query engine and returns the answer. Price per query, since that is the unit a caller values, and keep a free route describing what the index covers so callers can decide before paying.
Pay once, reuse the result
LlamaIndex retrieval has a habit worth planning for: the same source gets queried repeatedly across a run, and a naive paying tool would pay for each call. Treat a paid retrieval like any expensive fetch and cache its result in your app layer, keyed by the URL or query, so the second request for the same data is served from cache rather than paying again.
The wallet's spend limit is still the backstop, but caching is what keeps a chatty retrieval loop from paying many times for one document. Decide a sensible freshness window per source (a price feed expires in seconds, a reference document in hours) and only pay again when the cache is stale. This is the LlamaIndex-specific operational point: the integration makes paying easy, and caching makes paying economical, so wire both rather than paying per identical retrieval.
Compatibility
The integration works across LlamaIndex's surfaces, with the pay-side path set by runtime.
| LlamaIndex surface | Works? | Notes |
|---|---|---|
LlamaIndex.TS FunctionTool |
Yes | Calls the x402 client directly, no proxy |
Python FunctionTool on FunctionAgent |
Yes | Calls the local Node proxy |
QueryEngineTool paying for sub-retrievals |
Yes | The paying tool feeds retrieved data in |
| Earning from a query engine | Yes | Front the HTTP endpoint with the Node gateway |
| Payment package language | Node | Python talks to it via a proxy; TS calls it directly |
When this fits
The integration fits when a LlamaIndex agent retrieves from sources that cost money, when you want to charge for a query engine, or both. That is a natural fit for LlamaIndex specifically, since retrieval is its core and paid data sources are common; an agent that pays per retrieval and an index that earns per query are both first-class uses.
It fits less well when every source is free and internal (no wallet needed) or when one large human-approved payment is the only money movement. For per-call machine payments around retrieval, the runtime-appropriate pay path plus an optional earn gateway is the integration that matches how LlamaIndex is actually used.
Pricing
Integration is free; you build it from open packages. What you pay is the wallet platform fee per agent on the pricing page: Free is $0 per agent per month at a 5% transaction fee, Pro is $9 at 2%, Business is $29 at 1%. Per-agent pricing means each agent that transacts, paying or earning, is billed on its own wallet, so you pay for the agents that actually move money.
What to ship today
If you are on LlamaIndex.TS, wrap createX402Client in a FunctionTool and make one paid retrieval on Base Sepolia. If you are on Python, start a proxy and wrap the call to it; the walkthrough is how-to-add-payments-to-llamaindex-agent. To earn, front a query engine with the Node gateway and confirm an unpaid call gets a 402. For the sibling-framework overview see crewai-payment-integration. Pricing is on the pricing page.