LlamaIndex (Python): check several quotes on one page
Last updated: 2026-10-12
A LlamaIndex agent in Python that checks up to 20 quotes from one web page in one call to POST /v1/verify/quotes before it cites them. Price: US$0.02 per call, for 1 to 20 quotes. Each quote comes back exact, fuzzy or none, with offsets and context, plus the page's verdict and an Ed25519-signed receipt. Payments are in USDC with x402 v2 on Base mainnet (real USDC).
The tool is a LlamaIndex FunctionTool that calls the route over HTTP and pays with the x402 Python package.
To check one quote at a time, on the free trial with no payment code, see Example recipes. The same check for other frameworks: LangChain, OpenAI Agents SDK and Claude Agent SDK.
Install
Python 3.10 or later.
pip install "llama-index-core>=0.12" llama-index-llms-anthropic "x402[requests,evm]"
export ANTHROPIC_API_KEY=...
export ATTESTPAGE_X402_KEY=0x...
Any LLM LlamaIndex supports works; swap the Anthropic line for its class and install its package. ATTESTPAGE_X402_KEY is the private key (0x and 64 hex digits) of a wallet holding a little USDC. The key stays in your process.
agent_http.py
"""LlamaIndex agent that checks quotes with POST /v1/verify/quotes, paying per call with x402."""
import asyncio
import os
import sys
from eth_account import Account
from llama_index.core.agent.workflow import FunctionAgent
from llama_index.core.tools import FunctionTool
from llama_index.llms.anthropic import Anthropic
from x402 import x402ClientSync
from x402.http.clients import x402_requests
from x402.mechanisms.evm.exact import ExactEvmScheme
from x402.mechanisms.evm.signers import EthAccountSigner
ORIGIN = os.environ.get("ATTESTPAGE_URL", "https://vehcdj664efetfrsolne5umanq.srv.us").rstrip("/")
MAX_UNITS = 20000 # US$0.02 in USDC (6 decimals): the most one call may cost
client = x402ClientSync()
client.register("eip155:8453", ExactEvmScheme(signer=EthAccountSigner(Account.from_key(os.environ["ATTESTPAGE_X402_KEY"]))))
client.register_policy(lambda _version, reqs: [
r for r in reqs if r.network == "eip155:8453" and int(r.get_amount()) <= MAX_UNITS
])
session = x402_requests(client)
def verify_quotes(url: str, quotes: list[str]) -> dict:
"""Use before quoting one web page several times: checks 1 to 20 quotes against the page at url.
Returns results[i].match (exact, fuzzy or none), page.content_kind and a signed receipt. US$0.02 per call."""
try:
res = session.post(f"{ORIGIN}/v1/verify/quotes", json={"url": url, "quotes": quotes}, timeout=60)
return res.json()
except Exception as e: # payment refused by the policy above, network error: tell the agent why
return {"error": str(e)}
agent = FunctionAgent(
tools=[FunctionTool.from_defaults(fn=verify_quotes)],
llm=Anthropic(model=os.environ.get("MODEL", "claude-sonnet-5-5")),
system_prompt=(
"Before you quote a web page, call verify_quotes once with every quote you plan to use from it. "
"Cite a quote only when its match is exact or fuzzy and page.content_kind is real. "
"If the tool returns an error, say what it was and stop."
),
)
async def main(question):
print(await agent.run(user_msg=question))
if __name__ == "__main__":
asyncio.run(main(" ".join(sys.argv[1:]) or (
'Does https://www.iana.org/help/example-domains say "These domains may be used as '
'illustrative examples in documents" and "without prior coordination with us"?'
)))
python agent_http.py # pays US$0.02 per call in USDC
The first request gets a 402 with the price in the PAYMENT-REQUIRED header; the x402 session signs the payment and sends it again. The policy keeps only offers on Base (eip155:8453) of at most US$0.02, so a higher price or another network is refused before anything is signed, and the tool returns the reason as error. A request the service refuses (bad URL, empty quote) is refused before payment and not charged.
What comes back
results[i].match:exact,fuzzyornone, in the order ofquotes. Readpage.content_kindfirst:noneon abot_wallorjs_shellpage means the page could not be read.receipt: signed evidence of what the page said and when our fetcher saw it, as a JWS.POST /v1/receipt/verifychecks it for free, or check it offline with [verify-receipt.mjs](https://vehcdj664efetfrsolne5umanq.srv.us/docs/verify-offline). A receipt records what was on the page at that time, not whether a statement on it is correct.- Try the answer shape first with the free sample:
GET https://vehcdj664efetfrsolne5umanq.srv.us/v1/sample/quotes.
Terms
Pay per call, no account. See Payments, Limits and the Terms.