Skip to main content
Skip to content
Developer

API Documentation

Access 2.1M+ documents, 1,480+ persons, and investigative data via our public REST API. Free, read-only, no sign-up required. Issued API keys are available for higher per-key rate limits.

Base URL: https://epsteinexposed.com/api/v2

Quick Start

Make your first request in seconds. No authentication needed for basic access:

curl "https://epsteinexposed.com/api/v2/persons?q=epstein&per_page=5"

Every response is wrapped in a standard envelope with data, meta, and citation fields.

Authentication

Authentication is optional. Anonymous requests get 100 requests/hour. For higher limits, include an issued API key in the X-API-Key header:

curl -H "X-API-Key: ee_v2_issued_key_here" "https://epsteinexposed.com/api/v2/persons"

Issued keys use the ee_v2_ prefix, but the prefix alone is not sufficient. Keys are validated exactly and can be expired or rate-limited individually. Rate limit headers (X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset) are included in every response.

If you need sustained access above the anonymous tier, request an issued key instead of inventing your own prefix.

Rate Limits

TierLimitScope
Anonymous100 / hourPer IP address (sliding window)
Issued API Key1,000 / hour defaultPer issued key (sliding window, plan-specific)

Exceeding the limit returns 429 with a Retry-After header.

Response Format

All responses use a standard envelope:

{
  "api_version": "2.0",
  "status": "ok",
  "data": { ... },
  "meta": {
    "total": 1723,
    "page": 1,
    "per_page": 20,
    "has_more": true,
    "timestamp": "2026-02-24T12:00:00.000Z"
  },
  "citation": {
    "source": "Epstein Exposed",
    "url": "https://epsteinexposed.com",
    "license": "Public Interest - Attribution Requested",
    "accessed_at": "2026-02-24T12:00:00.000Z"
  }
}

Error responses:

{
  "api_version": "2.0",
  "status": "error",
  "error": { "code": 429, "message": "Rate limit exceeded" },
  "meta": { "timestamp": "..." }
}

HTTP Status Codes

CodeStatusDescription
200OKRequest succeeded.
400Bad RequestMissing or invalid parameters.
404Not FoundResource does not exist.
429Too Many RequestsRate limit exceeded. Check Retry-After header.
500Server ErrorSomething went wrong on our end.

Persons

GET/api/v2/persons

List and search persons with fuzzy matching, category filter, black book filter, and sort.

Params: q, category, black_book, sort, page, per_page

GET/api/v2/persons/{slug}

Full person detail: bio, aliases, positions, tags, structured data, aggregate stats.

GET/api/v2/persons/{slug}/connections

All known connections with strength, type, shared flight/document counts.

GET/api/v2/persons/{slug}/documents

Documents linked to this person, paginated.

Params: page, per_page

GET/api/v2/persons/{slug}/flights

Flight logs where this person appears as a passenger.

Documents

GET/api/v2/documents

Full-text search across 2.1M+ documents with source and category filters.

Params: q, source, category, page, per_page

GET/api/v2/documents/{id}

Full document detail with linked person IDs, OCR and integrity status.

GET/api/v2/documents/{id}/ocr

Extracted OCR text for a document, if available.

GET/api/v2/documents/{id}/integrity

SHA-256 hash verification and change history for a document.

Flights

GET/api/v2/flights

Search flight logs by passenger name, passenger ID, year, origin, or destination.

Params: passenger, passenger_id, year, origin, destination, page, per_page

GET/api/v2/flights/{id}

Single flight with full passenger manifest.

Emails

GET/api/v2/emails

Full-text search across email correspondence.

Params: q, page, per_page

GET/api/v2/emails/{id}

Single email with headers, body snippet, and linked persons.

Locations

GET/api/v2/locations

All known properties and locations associated with the case.

GET/api/v2/locations/{slug}

Single location with coordinates, address, description, and image.

Organizations

GET/api/v2/organizations

Companies, foundations, and entities connected to the case.

GET/api/v2/organizations/{slug}

Single organization with connected person and document counts.

Network

GET/api/v2/network/co-occurrence

Find documents where two persons appear together.

Params: person1 (required), person2 (required), limit

GET/api/v2/network/path

Shortest connection path between two persons via shared flights, documents, and relationships.

Params: from (required), to (required)

GET/api/v2/network/graph

Full connection graph (nodes + edges) filtered by minimum shared document threshold.

Params: min_shared_docs (default: 20)

GET/api/connection-lab

Multi-person co-occurrence matrix and timeline. Returns pairwise shared document/flight counts and dated co-occurrence events for 2-20 persons.

Params: persons (required, comma-separated IDs), detailA & detailB (optional, for pair evidence)

GET/api/connection-lab/connections

Top connections for a single person from the co-occurrence table. Used by the Explorer tab.

Params: personId (required), limit (default: 30, max: 50)

GET/api/v2/search

Full-text search across documents and emails. Returns separate result arrays for each type.

Params: q (required), type (documents|emails|all), limit, offset

Stats

GET/api/v2/stats

Database statistics: entity counts, integrity metrics, available sources and categories.

Bulk Export

Download full datasets as CSV or JSON for offline analysis:

GET/api/v2/export

List available datasets with record counts.

GET/api/v2/export/{dataset}

Download a dataset. Available: persons, flights, locations, organizations.

Params: format (csv|json, default: csv)

# Download all persons as CSV
curl -o persons.csv "https://epsteinexposed.com/api/v2/export/persons"

# Download flights as JSON
curl -o flights.json "https://epsteinexposed.com/api/v2/export/flights?format=json"

Forensic Analysis Tools

Cross-check names against external databases, generate investigation reports, and export evidence packets. Available at /money (12 forensic tabs) and /investigate (drag-and-drop board).

GET/api/cross-check

POST: Cross-reference a name against ICIJ Offshore Leaks, OpenSanctions, SEC EDGAR, and CourtListener. Returns matches from all 4 sources.

Params: body: { name: string }

GET/api/report/{slug}

GET: Generate investigation report data for a person. Returns connections, flights, documents, financial profile, cross-check results, and risk scores.

GET/api/evidence-packet

POST: Generate evidence packet data for a set of documents (auth required). Returns document details, review consensus, hash verification, and provenance chain.

Params: body: { documentIds: string[], subject: string }

GET/api/documents/{id}/reviews

GET: Fetch researcher reviews for a document. Returns reviewer notes, ratings, key findings, and structured observations.

# Cross-check a name against external databases
curl -X POST "https://epsteinexposed.com/api/cross-check" \
  -H "Content-Type: application/json" \
  -d '{"name": "Jeffrey Epstein"}'

# Get investigation report data
curl "https://epsteinexposed.com/api/report/jeffrey-epstein"

# Get document reviews
curl "https://epsteinexposed.com/api/documents/EFTA00123456/reviews"

Code Examples

cURL

# Search persons
curl "https://epsteinexposed.com/api/v2/persons?q=epstein&category=associate&per_page=5"

# Get a specific person
curl "https://epsteinexposed.com/api/v2/persons/ghislaine-maxwell"

# Search documents
curl "https://epsteinexposed.com/api/v2/documents?q=little+st+james&source=court-filing"

# With API key
curl -H "X-API-Key: ee_v2_issued_key" "https://epsteinexposed.com/api/v2/persons?q=clinton"

Python

import requests

API = "https://epsteinexposed.com/api/v2"

# Search persons
resp = requests.get(f"{API}/persons", params={"q": "epstein", "per_page": 5})
data = resp.json()

for person in data["data"]:
    print(f"{person['name']} ({person['category']}) - {person['stats']['documents']} docs")

# Get network path
resp = requests.get(f"{API}/network/path", params={
    "from": "jeffrey-epstein",
    "to": "bill-clinton"
})
path = resp.json()["data"]
print(f"Degrees of separation: {path['degrees']}")

JavaScript

const API = "https://epsteinexposed.com/api/v2";

// Search persons
const resp = await fetch(`${API}/persons?q=epstein&per_page=5`);
const { data, meta } = await resp.json();

console.log(`Found ${meta.total} persons`);
data.forEach(p => console.log(`${p.name} - ${p.stats.documents} docs`));

// With API key
const resp2 = await fetch(`${API}/documents?q=deposition`, {
  headers: { "X-API-Key": "ee_v2_issued_key" }
});

OpenAPI Spec

A machine-readable OpenAPI 3.1.0 specification is available for code generation, testing, and integration with API tools like Postman or Swagger UI:

https://epsteinexposed.com/api/v2/openapi.json

Citation

When using this data in research, journalism, or applications, please cite:

Epstein Exposed (https://epsteinexposed.com)
Public interest database of the Jeffrey Epstein case files.
Data derived from government records and court filings.

Every API response includes a citation object with source, URL, license, and access timestamp.

Inclusion in this database does not imply guilt or wrongdoing. All data is derived from publicly available records.

Support

For API questions, bug reports, or feature requests, visit the community forum:

board.epsteinexposed.com

See also the FAQ and About pages for general project information.