Retrieve every occurrence (source + file) for a specific leak hash
Retrieve every distinct detection of a deduplicated credential — one row per
(telegram_channel, file_name) pair — read directly from the tenant-routed
leaks_matched_* table (no separate occurrence store, no JOIN). The row count
EQUALS the occurrences figure shown in the /leaks/details list (same grain),
across ALL types (Combo and Stealer).
Use this after /leaks/details to drill into a credential and see each
detection. The proprietary telegram_channel and file_name are NEVER
returned: the source is replaced by a stable opaque id (opaque_source_id,
"Source #" + md5(channel)[:6]) and, when the detection carried a published
file, an opaque lot id (opaque_lot_id, md5(file_name)[:6]). Backfilled /
historical detections have no file, hence no lot. computer_name is never
selected nor returned.
Parameters:
hash(required): The leak hash from the/leaks/detailsresponsetenant_id_override(optional): workspace (MSSP) only — inspect a child tenant's detail; validated against the caller's portfolio (403/404 otherwise)
Tenant isolation: the query is scoped WHERE tenant_id = <server-derived> AND hash = <param>, so a hash belonging to another tenant returns nothing.
Response:
{
"total_occurrences": 2,
"occurrences": [
{"date": "2026-06-01T10:30:00", "source": "Source #a1b2c3", "lot": "d4e5f6",
"type": "Stealer", "country": "FR", "stealer_name": "RedLine",
"software": "Chrome", "ip_address": "1.2.3.4", "machine_user": "admin",
"machine_id": "…", "protocol": "https"},
{"date": "2026-05-20T08:00:00", "source": "Source #99aa11", "lot": null,
"type": "Combo", "country": null, "stealer_name": null, "software": null,
"ip_address": null, "machine_user": null, "machine_id": null,
"protocol": null}
]
}Example:
GET /leaks/details/occurrences?hash=5d41402abc4b2a76b9719d911017c592Authorization
ApiKeyAuth API key for authentication
In: header
Query Parameters
The leak hash to look up
Response Body
application/json
application/json
curl -X GET "https://api.stealed.io/leaks/details/occurrences?hash=string"{
"total_occurrences": 0,
"occurrences": [
{
"date": "2019-08-24T14:15:22Z",
"source": "string",
"lot": "string",
"type": "string",
"country": "string",
"stealer_name": "string",
"software": "string",
"ip_address": "string",
"machine_user": "string",
"machine_id": "string",
"protocol": "string"
}
]
}{
"detail": [
{
"loc": [
"string"
],
"msg": "string",
"type": "string"
}
]
}Retrieve all occurrences of a specific leak by hash GET
Retrieve all individual occurrences (raw records) for a specific leak hash. Use this after `/leaks/details` to drill down into a deduplicated leak and see every source where the credential was found. **Parameters:** - `hash` (required): The leak hash from the `/leaks/details` response - `identifier_column` (required): `root_domain`, `email_domain`, or `username` **Response:** ```json { "data": [ { "type": "Stealer", "username": "[email protected]", "password": "p****d", "domain": "example.com", "upload_stealed": "2025-01-15T10:30:00", "upload_date": "2025-01-14T08:00:00", "stealer_name": "RedLine", "country": "FR", "ip_address": "1.2.3.4", "computer_name": "DESKTOP-ABC", "software": "Chrome" }, ... ] } ``` **Example:** ```bash GET /leaks/details/by-hash?hash=5d41402abc4b2a76b9719d911017c592&identifier_column=root_domain ```
Paginated, count-sorted distinct-value breakdown for a KPI tile drill-down GET
Drill into a KPI tile (Total Users / Total Domains / Total Sources) with a server-paginated, count-sorted list of distinct values. Reuses the exact same tenant scoping as `GET /leaks/details`: results come from the tenant-routed `leaks_matched_*` table, restricted to the org's active domains, plus all standard `DynamicFilters` (dates, type, domain, not_domain, country, etc.). **Parameters:** | Parameter | Default | Description | |-----------|---------|-------------| | `field` | *required* | `username`, `domain`, or `source` | | `identifier_column` | *required* | `root_domain`, `email_domain`, `username`, or `all` | | `page` | 1 | Page number | | `page_size` | 50 | Items per page (max 200) | | `search` | - | Substring filter on the returned `value` | | `leak_mode` | `new` | `new` (first-seen in period) or `all` (any occurrence in period) -- must match the `/leaks/stats` KPI tile being drilled into | `domain` only counts round-trippable hostnames (drops base64 "email-blob" parsing garbage), matching the Insights domain pie. `source` emits an opaque label (`Source-<md5 prefix>`) -- the real channel name never leaves the API. **Response:** ```json { "data": [{"value": "[email protected]", "count": 42}], "total": 118, "page": 1, "page_size": 50, "total_pages": 3 } ``` `total` is the number of distinct `field` values matching the filters -- the same figure as the corresponding `/leaks/stats` KPI (`unique_usernames` / `unique_domains` / `unique_sources`). **Example:** ```bash GET /leaks/breakdown?field=domain&identifier_column=root_domain&page=1&page_size=50 ```