---
title: "Check an email address against known data breaches"
method: POST
path: "/v1/metered/breach"
tags: ["Identity exposure"]
---

# Check an email address against known data breaches

`POST /v1/metered/breach`

## Request

- Base URL: `https://api.relayshield.net`
- URL: `https://api.relayshield.net/v1/metered/breach`
- Auth: one of:
  - API key in header `X-RS-API-KEY`
  - HTTP bearer

Looks the address up across 13B+ compromised accounts and returns every breach it appears in, with the date and the classes of data exposed. Call it before trusting a new user identity or granting elevated access.

**Billing.** $0.10 per successful call. Failed calls are never billed. Charged against prepaid credits when the balance covers it, otherwise metered to your card. Threat Intelligence subscribers and AWS Marketplace bundle customers call this at no extra charge.

## Request body

- object
  - `email` string, email, required: Email address to check. Case-insensitive; whitespace is trimmed. Must contain '@'.

## Response `200`

Success. `ok` is true and `data` holds the result.

- object
  - `ok` true, required
  - `data` object, required
    - `observed_at` string, date-time: When this verdict was observed. Cache keyed on this, not on receipt time.
    - `valid_for_seconds` integer: How long this verdict can be cached before it should be re-checked. Flagged results live 7 days; clean results live 12 hours, because a hit stays a hit while a clean answer is the one that flips without telling whoever cached it. A degraded result lives 5 minutes. This is a caching hint and a policy default, not a measurement and not a safety guarantee: how fast a verdict really goes stale is bounded by upstream detection latency, which we do not control.
    - `expires_at` string, date-time: observed_at plus valid_for_seconds, precomputed.
    - `degraded` boolean: True when this answer was assembled from incomplete or failed upstream data. Treat it as NO VERDICT, never as clean. An outage that returns an empty finding list is otherwise indistinguishable from a real all-clear, and it fails in the permissive direction.
    - `email` string: The normalised address that was checked.
    - `record_type` string: Always `credential_exposure`. Lets a SIEM route every identity finding on one field.
    - `breach_count` integer: Number of breaches the address appears in. 0 means no known exposure.
    - `breaches` object[]: One entry per breach, unordered.
      - `name` string: Breach identifier, e.g. `LinkedIn`.
      - `domain` string: Domain of the breached service. May be empty.
      - `breach_date` string: Date of the breach, YYYY-MM-DD.
      - `data_classes` string[]: Data types exposed.
      - `is_verified` boolean: Whether the breach has been verified as genuine.

## Other responses

- `400`: `email` is missing or contains no '@'.
- `401`: Missing or invalid API key.
- `402`: No credits and no active subscription. The response carries `topup_url`.
- `405`: Wrong HTTP method. Every endpoint is POST.
- `429`: Upstream breach database rate limit reached. Retry in a few seconds.
- `502`: Upstream breach database unavailable or returned an unexpected status.

---

[API](https://skmtc.dev/relayshield/apis/relayshield-api.md) · [All operations](https://skmtc.dev/relayshield/apis/relayshield-api/llms.txt) · [OpenAPI document](https://skmtc.dev/relayshield/apis/relayshield-api/revisions/4d4721b936dd?raw)
