How to Build a Research Agent That Pays for Data (2026)
What you will build
A Python research agent that takes a question like "What were the Q1 2026 revenue figures for the top five Indian private banks and what did analysts say about them?", calls a mix of free and paid data APIs, and returns a structured answer with citations. When free sources suffice, it pays nothing. When premium sources are needed, the agent pays in USDC through a MoltPe wallet with strict daily and per-transaction caps.
The agent is a standard LangChain ReAct agent. The only unusual piece is that a few of its tools happen to cost money — and the payment handling is completely invisible to the agent's reasoning loop. It just gets JSON back.
Prerequisites
- Python 3.11+ and pip.
- A MoltPe account and API key (
mp_test_for dev). - An OpenAI API key (the agent uses GPT-4o-mini for reasoning).
- Redis or SQLite for the cache layer — in-memory works for quick tests.
- Access to at least one x402-enabled paid data source, or a free API to simulate one.
Step 1 — Create the research agent wallet
Mint a dedicated wallet for this agent. Give it a name that ties back to its purpose — your transaction history is a lot more readable when wallets are named after jobs.
curl -X POST https://api.moltpe.com/v1/agents/create \
-H "Authorization: Bearer $MOLTPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "name": "market-research-agent", "network": "polygon" }'
{
"agent_id": "ag_01JMTRE2K8X4PV7N9B3CQZDYEH",
"wallet_address": "0xD7B0A1E8c5F6d9A3b2C7e0D4f8A1B5c9E2F4A6B8",
"network": "polygon"
}
Fund it with a small starting amount, say 50 USDC, from your treasury. This is the total exposure for this agent — you cannot lose more than this even in a worst case.
Step 2 — Set budget guardrails
The spending policy is the safety net. MoltPe enforces it at signature time, so even a prompt injection or a broken loop cannot blow through it. Set conservative initial values; you can always raise them once you know the workload.
curl -X POST https://api.moltpe.com/v1/agents/ag_01JMTRE2K8X4PV7N9B3CQZDYEH/policy \
-H "Authorization: Bearer $MOLTPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"daily_cap": "10.00",
"per_tx_cap": "1.00",
"allowlist": [
"0x9F1d3B5a7C9e1F3b5A7c9E1f3B5a7C9e1F3b5A7c",
"0x2B5a7C9e1F3b5A7c9E1f3B5a7C9e1F3b5A7c9E1f"
]
}'
The allowlist restricts payments to two approved data providers. Anything else gets rejected before it reaches the chain. This is the difference between a wallet and a trust boundary.
Step 3 — Wrap paid APIs as LangChain tools
Install the packages and build a tool per data source. The MoltPe Python SDK exposes an x402-aware HTTP client; you call it like requests but it transparently handles payment.
pip install langchain langchain-openai moltpe redis
# research_agent.py — LangChain agent with paid data tools behind a MoltPe wallet.
import os, hashlib, json
from langchain.agents import AgentExecutor, create_react_agent
from langchain_openai import ChatOpenAI
from langchain.tools import Tool
from langchain import hub
from moltpe import X402Client
import redis
AGENT_ID = "ag_01JMTRE2K8X4PV7N9B3CQZDYEH"
cache = redis.Redis(host="localhost", port=6379, decode_responses=True)
moltpe = X402Client(
api_key=os.environ["MOLTPE_API_KEY"],
agent_id=AGENT_ID,
max_payment_usd="1.00",
)
def cached_paid_call(url: str, query: dict, ttl: int) -> dict:
"""Run a paid x402 call, but only if the cache misses."""
key = f"paid:{hashlib.sha256(f'{url}:{json.dumps(query, sort_keys=True)}'.encode()).hexdigest()}"
hit = cache.get(key)
if hit:
return json.loads(hit)
resp = moltpe.post(url, json=query).json()
cache.setex(key, ttl, json.dumps(resp))
return resp
def market_data_tool(query: str) -> str:
"""Premium market data. 0.05 USDC per call, cached 60s."""
data = cached_paid_call(
"https://premiumdata.example.com/quotes",
{"q": query},
ttl=60,
)
return json.dumps(data)
def legal_db_tool(query: str) -> str:
"""Paid legal filings. 0.50 USDC per call, cached 24h."""
data = cached_paid_call(
"https://legaldb.example.com/search",
{"q": query},
ttl=86400,
)
return json.dumps(data)
Step 4 — Add caching and free fallbacks
The tool list should put free tools first. The agent picks them by default — LangChain tools are ordered — and only escalates to paid tools when free returns are empty or thin. In practice this drops cost by 60% or more on typical research runs.
import requests
def free_web_search(query: str) -> str:
"""Free web search — try this before paid sources."""
resp = requests.get("https://api.duckduckgo.com/", params={"q": query, "format": "json"})
return resp.text[:4000]
def budget_remaining() -> float:
"""Return daily cap minus today's spend, in USDC."""
info = moltpe.get(f"https://api.moltpe.com/v1/agents/{AGENT_ID}/spend-today").json()
return float(info["remaining"])
tools = [
Tool(name="free_web_search", func=free_web_search, description="Free web search. Use FIRST."),
Tool(name="market_data", func=market_data_tool, description="Premium market quotes. Costs 0.05 USDC."),
Tool(name="legal_db", func=legal_db_tool, description="Legal filings DB. Costs 0.50 USDC. Use sparingly."),
]
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
prompt = hub.pull("hwchase17/react")
agent = create_react_agent(llm, tools, prompt)
executor = AgentExecutor(agent=agent, tools=tools, verbose=True, max_iterations=8)
Step 5 — Run a research task
Before invoking, check budget. If the remaining cap is too low, short-circuit with a friendly message instead of letting the agent try and fail.
question = "Summarize Q1 2026 revenue for the top 5 Indian private banks with analyst commentary."
remaining = budget_remaining()
if remaining < 1.0:
print(f"Budget too low (${remaining:.2f} left today). Try tomorrow.")
else:
result = executor.invoke({"input": question})
print(result["output"])
# Expected console output (trimmed):
# > free_web_search: Q1 2026 Indian bank results ...
# > market_data: { "HDFCBANK": {...}, "ICICIBANK": {...} }
# Final: HDFC Bank reported revenue of ... ICICI Bank ...
Testing the agent
Run the agent twice with the same question. The first run pays for premium lookups; the second run should cost zero because the cache is warm. Confirm this by checking the MoltPe dashboard transactions panel or calling the API:
curl "https://api.moltpe.com/v1/transactions?agent_id=ag_01JMTRE2K8X4PV7N9B3CQZDYEH&since=today" \
-H "Authorization: Bearer $MOLTPE_API_KEY"
You should see a handful of 0.05 and 0.50 USDC outgoing payments on run 1, and an empty or near-empty list on run 2. That is the caching doing its job. For deeper testing, deliberately trip the per-tx cap by setting it to 0.01 and running the agent — you should see the middleware reject the market-data call with POLICY_VIOLATION and the agent gracefully fall back to the free source.
Production checklist
- Switch to live keys (
mp_live_) and a mainnet wallet only after caps are tested. - Centralize cache in Redis with persistence — in-memory caches don't survive restarts and you will over-pay.
- Alert on spend anomalies: if daily spend exceeds a baseline, send a webhook to Slack. MoltPe emits
spend.threshold_crossedevents. - Rotate the API key monthly and store it in a secret manager, never in the repo.
- Archive transaction logs for financial record-keeping. MoltPe keeps full history, but a local mirror keeps you independent of provider outages.
Frequently Asked Questions
Which paid data APIs support x402 today?
A growing list of market data, legal databases, and scientific corpora expose x402 endpoints. Check the MoltPe partner directory for current providers. You can also wrap any non-x402 API with your own paid proxy and bill per call, which many teams do to rate-limit and monetize a free tier.
How does caching reduce cost without making data stale?
Cache by query hash with a TTL tuned to the data type. Market prices get 60 seconds, legal filings get 24 hours, scientific papers get 30 days. The MoltPe SDK exposes a pluggable cache layer so you can back it with Redis, SQLite, or just an in-process LRU for short runs.
Can the agent burn through the budget in a loop?
Not if you set a daily cap. MoltPe enforces caps at signature time, so even a broken loop hitting a paid tool 1000 times will stop at the cap. This is why spending policies exist: they are the guardrail a prompt cannot talk its way around. Add your own in-code budget check for faster failure.
What happens when a paid source is down?
The MoltPe x402 client raises a typed exception when the upstream returns 5xx or times out. Catch it in your tool wrapper and fall through to the next source (free or alternate paid). Never retry the same failing source more than twice per run — that is how you burn budget on nothing.
Should the research agent share a wallet with other agents?
No. Give each agent its own wallet and its own policy. Shared wallets make debugging painful and blast radius huge. MoltPe agents are cheap to create — a research agent, a summarizer agent, and a notifier agent are three separate wallets with three separate daily caps.
Give your research agent a wallet
An afternoon of work, an hour of testing, and you have an agent that pays for the data it needs — no more, no less.
Start with a test wallet →About MoltPe
MoltPe is AI-native payment infrastructure that gives AI agents isolated wallets with programmable spending policies for autonomous USDC transactions. Live on Polygon PoS, Base, and Tempo. Supports REST, MCP, and x402.