Two routes give the public breach data behind orelys.io/pwned and the breach search on the orelys.io homepage: the list of known data breaches, and the breach search, which tells which of them hold an email address. They are free: no API key, no account, no credits, nothing taken from a quota. Their limits are per address.

List data breaches

GET /v1/breaches — every known breach: name, dates, size, kinds of data.

Breach search

POST /v1/breaches/check — the breaches an email address appears in, and under which kinds of data.
The data comes from our breach-data provider. Orelys passes on what it publishes about each breach; it does not host the breached records, and never returns them. Call these routes from a script or from your server. The API does not answer browser calls (fetch, XHR) from other sites — there is no CORS for them — so a web page should go through its own backend.

The breach list

One call, no parameters: every known breach, the most recently added first.
The answer holds count, records, updated_at and breaches, each breach with its name, dates, size, kinds of data and flags. Fields, code and limits → Send the address in a JSON body, with POST. A search can take up to about 45 seconds, so give your client a minute.
The answer lists the named breaches holding the address, each with found_types: the kinds of data the address was found under. The values themselves are never returned. The address is never stored. Fields, code and limits →

Hidden breaches

Some breaches are sensitive, and our breach-data provider does not name them publicly. When one of them holds the address, the breach search counts it in hidden but does not list it: you learn how many there are, not which ones. The same goes for every breach marked sensitive: true in the breach list: anyone can search any address, so the breach search never names one. found is true as soon as count + hidden is above zero.

Data removal

An address removed at its owner’s request through orelys.io/data-removal, or an address on a removed domain, answers the breach search exactly like an address found nowhere: found: false, count: 0, hidden: 0, breaches: [], after about as long as a search that finds nothing. Nothing tells a removed address from a clean one, and our breach-data provider is not even asked. More on data removal →

Limits

Both routes take nothing from a quota and need no account. Their limits are per address: The breach search also has an hourly and a daily cap for the whole service, all callers together: once it is reached, every breach search answers 503 breach_check_unavailable until the hour or the day ends. Calls made straight to the API (not through orelys.io) also have an hourly and a daily share of that cap, all of them together: once it is used, their breach searches answer 503 breach_check_unavailable until the hour or the day ends. And one address (an IPv6 /48) can start only a limited number of new breach searches an hour: past it, 429 rate_limited until the hour ends.

Data types

data_types and found_types use the same raw keys, as our breach-data provider names them. The most common: A key with a dot is a part of a larger one: job.job_title is the title within job.
The list is not closed: other keys can appear as new breaches are added. Show a key you do not know as it is, rather than dropping it.
Use these routes only for lawful purposes, on addresses you are entitled to check. The Terms and the Acceptable Use Policy apply to them as they do to the rest of Orelys.