the receipts
are available onchain
Every court-released Epstein email. OCR'd, structured, and queryable through a pay-per-request API. No accounts. No keys. Just USDC and a wallet.
wallet in, data out.
Your x402 client pays the micro-fee automatically. One HTTP call, one USDC transfer, structured JSON returned. That's it.
make the call
Hit /api/emails or /api/search. Your x402 client sees the 402, signs a USDC payment, and retries automatically.
payment settles
Coinbase's facilitator verifies and settles. No gas needed. No approval txns. Sub-second on Base.
get your data
Structured JSON with sender, recipient, date, subject, body, and source PDF provenance. Paginated. Filterable.
degens, journalists, agents.
If you're querying public records for alpha, building an investigation tool, or wiring up an AI agent to search court docs.
prediction traders
Query programmatically to inform your positions. Search names, dates, and connections faster than anyone reading PDFs by hand.
researchers
Full-text search across every field. Filter by sender, recipient, date. Export structured data. Cross-reference other datasets.
AI agents
Listed on the x402 Bazaar. Your agent can discover, pay, and query autonomously. No API keys to manage. No OAuth dance.
pip install, paste, query.
Fund a wallet with USDC on Base. Drop this into your project. That's the whole onboarding.
# pip install "x402[httpx,evm]" eth_account import asyncio, json from eth_account import Account from x402 import x402Client from x402.http.clients import x402HttpxClient from x402.mechanisms.evm import EthAccountSigner from x402.mechanisms.evm.exact.register import register_exact_evm_client # your wallet (needs USDC on Base) account = Account.from_key("0xYOUR_PRIVATE_KEY") client = x402Client() register_exact_evm_client(client, EthAccountSigner(account)) async def main(): async with x402HttpxClient(client) as http: # paginate through all results (max 1000/req) all_results = [] offset = 0 while True: resp = await http.get( f"https://epsteinemails.xyz/api/search?q=ghislaine&limit=1000&offset={offset}" ) data = resp.json() all_results.extend(data["results"]) if not data["has_more"]: break offset = data["next_offset"] print(f"fetched {len(all_results)} total results") asyncio.run(main())
endpoints
Structured queries. Filter by sender, recipient, date, subject. Filters combine with AND logic. Doesn't search body text -- use /api/search for that.
Query Parameters
| Param | Type | Description |
|---|---|---|
from | string | Filter by sender |
to | string | Filter by recipient |
subject | string | Filter by subject line |
date | string | Filter by date (e.g. "2017") |
source_file | string | Filter by source PDF |
limit | int | Max per page (default: 1000) |
offset | int | Pagination offset |
Response
| Field | Type | Description |
|---|---|---|
total | int | Total matching records |
returned | int | Records in this page |
has_more | bool | More pages? |
next_offset | int|null | Next page offset |
Examples
# filter by sender GET /api/emails?from=jeffrey&limit=10 # combine filters GET /api/emails?from=jeffrey&subject=schedule&limit=25 # paginate GET /api/emails?offset=0 # page 1 GET /api/emails?offset=1000 # page 2 GET /api/emails?offset=2000 # page 3
Searches across all fields at once: from, to, subject, body, date, cc, bcc. Use this when you don't know which field has what you're looking for.
Query Parameters
| Param | Type | Description |
|---|---|---|
q | string | Search query (required) |
limit | int | Max per page (default: 1000) |
offset | int | Pagination offset |
Response
| Field | Type | Description |
|---|---|---|
total_matches | int | Total matching records |
returned | int | Records in this page |
has_more | bool | More pages? |
next_offset | int|null | Next page offset |
Examples
# search all fields GET /api/search?q=ghislaine # smaller pages GET /api/search?q=palm+beach&limit=100 # paginate GET /api/search?q=2003&offset=0 # page 1 GET /api/search?q=2003&offset=1000 # page 2