AttestPage · Docs · Pricing · OpenAPI · llms.txt

LangChain (Python): check several quotes on one page

Last updated: 2026-10-12

A LangChain 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 calls the route over HTTP and pays with the x402 Python package.

To check one quote at a time or a batch of links, on the free trial with no payment code, see LangChain: check a quote before citing it.

The same check for other frameworks: LlamaIndex, OpenAI Agents SDK and Claude Agent SDK.

Install

Python 3.10 or later.

pip install "langchain>=1.0" langchain-anthropic "x402[requests,evm]"
export ANTHROPIC_API_KEY=...
export ATTESTPAGE_X402_KEY=0x...

Any chat model LangChain supports works; set MODEL (for example openai:gpt-5) 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

"""LangChain agent that checks quotes with POST /v1/verify/quotes, paying per call with x402."""
import os
import sys

from eth_account import Account
from langchain.agents import create_agent
from langchain.tools import tool
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)


@tool
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."""
    res = session.post(f"{ORIGIN}/v1/verify/quotes", json={"url": url, "quotes": quotes}, timeout=60)
    return res.json()


agent = create_agent(
    model=os.environ.get("MODEL", "anthropic:claude-sonnet-5-5"),
    tools=[verify_quotes],
    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 __name__ == "__main__":
    question = " ".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"?'
    )
    result = agent.invoke({"messages": [{"role": "user", "content": question}]})
    print(result["messages"][-1].content)
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. A request the service refuses (bad URL, empty quote) is refused before payment and not charged.

What comes back

Terms

Pay per call, no account. See Payments, Limits and the Terms.