Search Data Leaks Dashboard Pricing API Donate Contact Terms of Use Privacy & Legal Blog Crawler Login Register
REST · JSON · HTTPS

API Documentation

Search billions of leaked records programmatically — credentials, infostealer logs, ransomware leaks and data breaches. Every endpoint is a simple GET request that returns clean JSON.

Base URLhttps://haveibeenransom.com

Get started in 3 steps

New here? You can make your first call in under a minute. No SDK needed — just curl or any HTTP client.

1

Get your API token

Grab your personal token from your plan dashboard. It looks like a long random string and is yours alone — keep it secret.

2

Add the auth header

Send your token on every request inside the Authorization header, in the form Bearer YOUR_TOKEN.

3

Make your first request

Copy the example on the right, paste in your token, and run it. That's it — you'll get JSON back.

Your first request — copy, paste your token, run

curl -H "Authorization: Bearer YOUR_TOKEN" \
  "https://haveibeenransom.com/api/metadata/email/[email protected]"

Authentication

Every request (except the public breach counters below) must include your API token. We use the standard Bearer token scheme: put your token in the Authorization header like this:

Authorization: Bearer YOUR_TOKEN

That's the only auth you need — no signatures, no OAuth dance. If the token is missing or wrong you'll get a 401 Unauthorized. Need a token? Pick a plan or email [email protected].

Keep your token private

Anyone with your token can spend your daily quota. Never commit it to public repos or ship it in front-end code. Send requests from your server, not the browser.

You search by field and term. The field tells us what kind of value you're looking for (an email, a domain, a wallet…) and the term is the value itself. Searches are case-insensitive and support partial matching.

You can also search multiple fields at once by separating them with commas — e.g. email,username. The two big datasets accept different fields:

Ransomware leaks & data breaches
nameemailusernamedomainphoneidcountrypassword

Used by metadata, fulldata, fullransom and fullbreach. Great for checking which companies leaked a person's data.

Infostealer logs
emailnamephoneusernameidcountrydomainpasswordwalletssteamidsteamuserteleidteleusertelephonetelelinkvpnftphwid

Used by fullstealer. Includes crypto wallets, gaming accounts, Telegram and machine identifiers.

Field reference

FieldWhat it matchesDatasets
nameFull names and name-related informationall
emailEmail addressesall
usernameUsernames and login identifiersall
domainWebsite domains / leaked email domains — returns every record tied to that domainall
phonePhone numbers and contact infoall
idID / document numbers (DNI, passport…)all
countryCountry (2-letter code, e.g. US, AU)all
passwordPasswords found in breaches / logsall
walletsCryptocurrency wallet addressesstealer
steamidSteam account IDsstealer
steamuserSteam usernamesstealer
teleidTelegram user IDsstealer
teleuserTelegram usernamesstealer
telephoneTelegram phone numbersstealer
telelinkTelegram group linksstealer
vpnVPN domains or IP addressesstealer
ftpFTP domains or IP addressesstealer
hwidHardware / computer IDsstealer

Good to know

  • Some fields map to several underlying columns so you get the widest possible match.
  • Domain searches return all records associated with that domain.
  • Combine fields with commas to widen a search: email,username,name.
  • The email_context value attached to breach records bundles extra personal info (phone, name…) tied to that email.

Endpoint reference

Every endpoint is a GET request. Pick the one that matches what you need. The pattern is always /api/<endpoint>/<fields>/<term>.

Breach counters No auth

Two tiny public endpoints. Get the total number of breaches we track, or the full list of breaches sorted oldest-to-newest.

GET/breaches/total
GET/breaches/full

Example request

curl "https://haveibeenransom.com/breaches/total"

Example response — /breaches/total

{
  "total": 1113
}

Example response — /breaches/full

{
  "breaches": [
    {
      "id": "11111",
      "id_source": "11111",
      "group_name": "ransomgang name",
      "post_title": "Example Company Breached",
      "post_url": "http://example3wh7hnmaiokchk7qoebupfgoik6rhaexample.onion/id=1234",
      "website": "example.com",
      "country": "US",
      "description": "United States",
      "discovered": "2024-12-16 21:07:57.040833",
      "indexed": "2025-07-11T00:33:13.072665",
      "Identities Found": 1872
    }
  ]
}

1 · Metadata search

Which breaches affected this person/domain? Returns lightweight breach metadata (company, group, date, country) without exposing the sensitive records. Results are paginated, 20 per page.

GET/api/metadata/<fields>/<term>
GET/api/metadata/<fields>/<term>/<page>
GET/api/metadata/<fields>/<term>/completeEnterprise

Parameters

ParamMeaningExample
fieldsrequired · what to match: name, phone, email, username, id, country, domain, passwordemail
termrequired · the value to search[email protected]
pageoptional · page number (default 1)2

Example — single field

curl -H "Authorization: Bearer YOUR_TOKEN" \
  "https://haveibeenransom.com/api/metadata/domain/example.com"

Example — multiple fields

curl -H "Authorization: Bearer YOUR_TOKEN" \
  "https://haveibeenransom.com/api/metadata/email,username/[email protected]"

Example response

{
  "success": true,
  "results": [
    {
      "Identities Found": 1872,
      "country": "US",
      "description": "United States",
      "discovered": "2024-12-16 21:07:57.040833",
      "group_name": "ransomgang name",
      "id": "11111",
      "id_source": "11111",
      "indexed": "2025-07-11T00:33:13.072665",
      "post_title": "Example Company Breached",
      "post_url": "http://example3wh7hnmaiokchk7qoebupfgoik6rhaexample.onion/id=1234",
      "website": "example.com"
    }
  ],
  "pagination": {
    "current_page": 1,
    "total_pages": 3,
    "total_sources": 45,
    "has_next": true,
    "has_previous": false
  }
}

2 · Full data search

The actual records, not just metadata. Same shape across three sibling endpoints — pick one depending on which dataset you want to search:

EndpointSearches
/api/fulldataEverything combined — ransomware leaks + traditional breaches + ULP/combolists
/api/fullransomRansomware leaks only
/api/fullbreachTraditional data breaches only
GET/api/fulldata/<fields>/<term>
GET/api/fulldata/<fields>/<term>/<id_source>
GET/api/fulldata/<fields>/<term>/completeEnterprise

/api/fullransom/… and /api/fullbreach/… accept the exact same path variants.

Parameters

ParamMeaningExample
fieldsrequired · email, name, phone, username, id, country, domain, passworddomain
termrequired · the value to searchexample.com
search_afteroptional query param · cursor for the next page (default 0)?search_after=253941
id_sourceoptional · restrict results to one breach source11111

Paid plans only

Full data endpoints require a paid data plan. Requests from a Basic token get a 403 asking you to upgrade.

Example — single field

curl -H "Authorization: Bearer YOUR_TOKEN" \
  "https://haveibeenransom.com/api/fulldata/domain/example.com"

Example — next page (cursor pagination)

curl -H "Authorization: Bearer YOUR_TOKEN" \
  "https://haveibeenransom.com/api/fulldata/email/[email protected]?search_after=253941"

Example response

{
  "success": true,
  "email": "[email protected]",
  "data": [
    {
      "email": "[email protected]",
      "email_context": "phone, name, etc",
      "From archive": "This domain has been in PDF archive example.pdf",
      "source_metadata": {
        "country": "US",
        "description": "Lorem ipsum......",
        "group_name": "play",
        "company_affected": "Company XYZ",
        "post_url": "http://example3wh7hnmaiokchk7qoebupfgoik6rhaexample.onion/id=1234",
        "website": "example.com"
      }
    }
  ],
  "has_next_page": true,
  "search_after": 253941,
  "total_hits": 325478
}

To page through results, take search_after from the response and pass it back as ?search_after=.... When has_next_page is false, you've reached the end.

3 · Full stealer search Infostealer logs

Stolen credentials, crypto wallets, gaming accounts, Telegram and more — straight from infected machines. This is the richest dataset, so its response can take three different shapes. Read the top-level "mode" first.

GET/api/fullstealer/<fields>/<term>
GET/api/fullstealer/<fields>/<term>?search_after=X
GET/api/fullstealer/<fields>/<term>/completeEnterprise

Parameters

ParamMeaningExample
fieldsrequired · any infostealer field (email, username, wallets, steamid, teleuser, vpn, country…)email
termrequired · the value to search (country must be a 2-letter code)[email protected]
search_afteroptional query param · cursor for the next page (default 0)?search_after=2587

First, how infostealer data is organized

When a machine is infected, the stealer dumps everything into 5 buckets (indexes):

  • Credential → saved logins (URL / user / password)
  • Cookies → browser cookies / sessions
  • Info → system info (Country, OS, HWID, log date…)
  • plus → extras: crypto wallets, VPN, FTP, Steam, Telegram…
  • Filelist → list of files grabbed from the machine

Every document shares the same Filename — a unique ID for the infected machine, e.g. HWID E32F8AFB9CF347BA22FCCF354C9E9B5C_analysis14951. Think of Filename as the "victim machine ID" that glues all the pieces together.

The response has 3 shapes — always check "mode"

The field you search by decides the shape. Read the top-level "mode" value and parse accordingly:

modeWhen you search by…What you get
fragmentsemail, username, phone, id, domain, passwordA flat list in "matches", one item per credential: {URL, USER, PASS, Filename}.
documentswallets, steamid, steamuser, teleid, teleuser, telephone, telelink, vpn, ftp, hwidRaw documents in "data", each as {_index, _source}.
stealerscountryResults grouped per infected machine in "data" — every document from all 5 indexes bundled together.

Example — by email (mode: fragments)

curl -H "Authorization: Bearer YOUR_TOKEN" \
  "https://haveibeenransom.com/api/fullstealer/email/[email protected]"

Example — by country (mode: stealers)

curl -H "Authorization: Bearer YOUR_TOKEN" \
  "https://haveibeenransom.com/api/fullstealer/country/AU"

Response A — mode: "fragments"

When you search by email, username, phone, id, domain or password. Each item in matches is one matching login; Filename tells you which machine it came from.

{
  "mode": "fragments",
  "matches": [
    {
      "URL": "https://login.example.com",
      "USER": "[email protected]",
      "PASS": "leaked_password_123",
      "Filename": "HWID E32F8AFB9CF347BA22FCCF354C9E9B5C_analysis14951"
    }
  ],
  "count": 1,
  "total_docs": 14356,
  "search_term": "example.com",
  "fields": ["domain"],
  "search_after": 2587,
  "has_next_page": true
}

Response B — mode: "documents"

When you search by wallets, steamid, steamuser, Telegram fields, vpn, ftp or hwid. Each entry in data is a raw document; the real content lives in _source, and _index tells you which bucket it came from.

{
  "mode": "documents",
  "data": [
    {
      "_id": "kJ3l9ZcBxq",
      "_index": "logs_plus",
      "_score": null,
      "_source": {
        "Filename": "HWID E32F8AFB9CF347BA22FCCF354C9E9B5C_analysis14951",
        "HWID": "E32F8AFB9CF347BA22FCCF354C9E9B5C",
        "Country": "AU",
        "Wallets Cracked": ["bc1qxy2k...", "0x1283921ASDK..."]
      }
    }
  ],
  "count": 1,
  "total_hits": 320,
  "search_term": "76561198012345678",
  "fields": ["steamid"],
  "has_next_page": false
}

Response C — mode: "stealers" (country search)

Only when you search by country. data is a list of infected machines. Each machine has its filename, a count of its documents, and a documents array bundling everything found for that machine across the 5 indexes.

{
  "mode": "stealers",
  "data": [
    {
      "filename": "HWID E32F8AFB9CF347BA22FCCF354C9E9B5C_analysis14951",
      "count": 4,
      "documents": [
        {
          "_index": "logs_info",
          "_source": {
            "Filename": "HWID E32F8AFB...analysis14951",
            "Country": "AU",
            "HWID": "E32F8AFB9CF347BA22FCCF354C9E9B5C",
            "LogDate": "2024-11-02"
          }
        },
        {
          "_index": "logs_credential",
          "_source": {
            "Filename": "HWID E32F8AFB...analysis14951",
            "Credentials": [
              {
                "URL": "https://mail.example.com",
                "USER": "[email protected]",
                "PASS": "hunter2"
              }
            ]
          }
        },
        {
          "_index": "logs_plus",
          "_source": {
            "Filename": "HWID E32F8AFB...analysis14951",
            "Wallets Cracked": ["bc1qxy2k...", "0x9aF3..."],
            "VPN info": "nordvpn.com"
          }
        },
        {
          "_index": "logs_filelist",
          "_source": {
            "Filename": "HWID E32F8AFB...analysis14951",
            "Files": ["C:\\Users\\victim\\Desktop\\passwords.txt"]
          }
        }
      ]
    }
  ],
  "count": 1,
  "total_hits": 5821,
  "search_term": "AU",
  "fields": ["country"],
  "search_after": 1024,
  "has_next_page": true
}

How to read it

  • count (top level) → machines returned on this page.
  • total_hits → total country matches across all pages.
  • data[].count → how many documents that single machine has.
  • Use search_after + has_next_page to page through more machines.

4 · Leak analytics

Profile a single breach. Give it a breach's id_source and get aggregated analytics: corporate vs personal email split, how many identity documents, a file-type breakdown, and the breach's metadata.

GET/api/fullmetadata/<id_source>

Parameters

ParamMeaningExample
id_sourcerequired · the breach source ID (from a metadata or breaches result)11111

Example request

curl -H "Authorization: Bearer YOUR_TOKEN" \
  "https://haveibeenransom.com/api/fullmetadata/11111"

Example response

{
  "id_source": "11111",
  "leak_type": "ransomware_leak",
  "total_records": 1872,
  "breach_metadata": {
    "post_title": "Example Company Breached",
    "group_name": "play",
    "country": "US",
    "discovered": "2024-12-16 21:07:57.040833"
  },
  "email_origin": {
    "total_emails": 1500,
    "records_with_email": 1450,
    "internal_corporate": { "count": 900, "percentage": 60.0 },
    "external_personal": { "count": 600, "percentage": 40.0 }
  },
  "identity_documents": {
    "count": 120,
    "percentage_of_records": 6.41
  },
  "file_types": {
    "distinct_types_present": 4,
    "breakdown": {
      "pdf": 150,
      "csv": 80,
      "xlsx": 30,
      "databases": 200
    }
  }
}

5 · Domain overview Enterprise

One call, full picture of a domain's exposure. Runs infostealer (clients & employees), breaches and ransomware lookups in parallel and returns the totals plus top URLs and users. Non-Enterprise tokens receive a safe demo response with "is_demo": true.

GET/api/domain_overview/<domain>

Parameters

ParamMeaningExample
domainrequired · the domain to profile (use example.* to match all TLDs)example.com

Example request

curl -H "Authorization: Bearer YOUR_TOKEN" \
  "https://haveibeenransom.com/api/domain_overview/example.com"

Example response (trimmed)

{
  "domain": "example.com",
  "exposures": {
    "infostealer": {
      "clients": {
        "total_exposures": 1820,
        "unique_urls": 45,
        "urls": [{ "url": "https://login.example.com", "count": 320 }],
        "users": [{ "user": "[email protected]", "count": 12 }],
        "status": "success"
      },
      "employees": {
        "total_exposures": 230,
        "unique_urls": 8,
        "urls": [],
        "users": [{ "user": "[email protected]", "count": 3 }],
        "status": "success"
      },
      "total": 2050
    },
    "breaches": {
      "count": 540,
      "unique_sources": 6,
      "sources": [
        { "source_id": "abc123", "count": 320, "metadata": { "name": "Acme DB" } }
      ],
      "status": "success"
    },
    "ransomware": {
      "count": 1872,
      "unique_sources": 3,
      "sources": [
        { "source_id": "11111", "count": 1872, "metadata": { "name": "play" } }
      ],
      "status": "success"
    }
  },
  "total_exposures": 4462,
  "execution_time_seconds": 1.234,
  "timestamp": 1735000000.0
}

6 · Usage stats

See how the API is being used. Get your own token's daily usage, or the global, anonymized stats. Both accept optional ?date=YYYY-MM-DD and ?days=N query params.

GET/api/<token>/stats
GET/api/general/stats

Parameters

ParamMeaningExample
tokenrequired (per-token route only) · your API token, in the pathYOUR_TOKEN
dateoptional query param · day to report (default today)?date=2026-06-26
daysoptional query param · how many days back to aggregate (default 1)?days=7

Example request

curl "https://haveibeenransom.com/api/YOUR_TOKEN/stats?days=7"

Example response — per token

{
  "date": "2026-06-26",
  "token": "abc12345...",
  "statistics": {
    "total_queries": 42,
    "by_field": { "email": 30, "domain": 12 },
    "by_query_type": { "metadata": 18, "fulldata": 24 },
    "unique_terms": ["[email protected]", "example.com"],
    "hourly_distribution": { "9": 10, "14": 32 }
  }
}

Complete mode

Add /complete to the end of a metadata, fulldata, fullransom, fullbreach or fullstealer request to get every result at once, with no pagination.

Enterprise only

Because /complete can return enormous datasets, it's reserved for Enterprise license holders. Other plans get a 403 telling them to upgrade. Everyone else should page normally with page (metadata) or search_after (fulldata / fullstealer).

curl -H "Authorization: Bearer YOUR_TOKEN" \
  "https://haveibeenransom.com/api/fulldata/email/[email protected]/complete"

Rate limits

Each plan includes a daily API quota (requests per day). Every response carries rate-limit headers so you can track your usage. Go over the limit and you'll get a 429 Too Many Requests until the next reset.

Basic
100requests / day
Professional
2,000requests / day
Cybersecurity Agency
20,000requests / day
Enterprise / Gov
unlimited
PlanAPI requests / dayComplete mode
Basic100
Professional2,000
Cybersecurity Agency20,000
Enterprise / GovUnlimitedIncluded

Error responses

The API uses standard HTTP status codes. When something goes wrong you get a JSON body explaining it. Here's what each code means and what to do:

CodeMeaningWhat to do
400Bad request — invalid parameters (bad field, empty term, malformed email or country code)Check your field name, term and format, then retry.
401Unauthorized — missing or invalid tokenConfirm your Authorization: Bearer header and token.
403Forbidden — your plan doesn't include this feature (e.g. full data, or /complete)Upgrade your plan to unlock it.
429Too many requests — daily rate limit exceededWait for the daily reset or upgrade for a higher quota.
500Internal server errorRetry shortly; if it persists, contact support.

Example error body

{
  "success": false,
  "error": {
    "code": 403,
    "message": "Enterprise feature required",
    "details": "The /complete endpoint is only available for Enterprise license holders"
  }
}

Frequently asked questions

QWhat's the difference between metadata and full data search?

Metadata search returns basic breach information (which companies, groups and dates) without sensitive details. Full data search returns the comprehensive records about the specific data that was compromised.

QWhat's the difference between fulldata and fullstealer?

fulldata searches ransomware breach and traditional breach data. fullstealer searches infostealer logs — stolen credentials, crypto wallets, gaming accounts and other sensitive data pulled from infected machines.

QHow often is the database updated?

Continuously, as new ransomware breaches and infostealer logs are discovered and verified. Updates typically land within 24–48 hours of breach disclosure.

QCan I search for domains instead of specific emails?

Yes. All endpoints support domain queries (e.g. example.com) to find every breach or log affecting that domain.

QWhat is Complete mode and how do I access it?

Complete mode returns all results without pagination — handy for full exports. It's exclusive to Enterprise license holders. Email [email protected] to upgrade.

QHow does pagination work?

Metadata search uses page numbers (up to 20 per page). fulldata and fullstealer use cursor-based pagination via search_after (20 per request). Take the search_after value from the response and pass it as a query parameter for the next batch: ?search_after=2587. When has_next_page is false, you've reached the end.

QWhy does a country search on fullstealer look different?

A country search returns "mode": "stealers" — results grouped per infected machine. Instead of one isolated row, each machine comes with all of its documents (credentials, cookies, system info, wallets, file list) bundled under its Filename. That gives you the complete profile of every victim machine in that country in one call. All other fields keep their fragments / documents shapes.

QHow do I know which response shape to expect from fullstealer?

Always read the top-level "mode" field. fragments → look in matches (flat list of {URL, USER, PASS, Filename}). documents → look in data (raw docs, real content inside _source). stealers → look in data (one entry per machine, documents bundled inside).

Ready to start building?

Pick a plan to get your API token, or reach out and we'll help you choose.