Skip to main content
Each time a monitor runs and finds new results, it records a match. A match is a header (which monitor, which source, which time window, a review status) plus the result rows found in that window. The dashboard shows matches under Monitoring → Incidents. In the API a monitor is an alert rule, so a match header names its monitor in alert_rule. The flow: list matches, open one, page through its rows, set a status, and export the rows when you need a file.

Availability and cost

Availability: every plan with a license in force. These endpoints do not check the monitor’s data source against your plan, so matches recorded before a plan change stay readable. Cost: no metered allowance. With an API key, each call counts once toward your monthly API Calls allowance, and only 2xx responses count. See Rate limits. When your organization’s license is not active, every endpoint on this page returns 403:
Plans and quotas explains license states, and Errors lists every error body.

List matches

alert_system_alert_get_alert_match_list returns your organization’s matches, newest first:
Page with page and page_size, and stop once you have read count items. Build each page request yourself. The next and previous values are passed through from the monitoring service and may not point at client-api.leak.center. A page number past the end returns 404.
A generic webhook delivery carries match_detail_id. That value is the match id, so a webhook receiver can call the endpoints below directly.

Open a match

alert_system_alert_get_alert_match_detail returns one match header, with the same fields as a list item:
It returns any match of your organization, including one whose rows are all excluded. A match ID from another organization returns 404.

Read the result rows

The header does not carry the rows. alert_system_alert_get_alert_match_detail_results returns them, 10 per page by default and up to 100:
data is the row the source returned, stored as is. Only control characters are removed. Its fields follow that source, so the source’s guide is the reference for what they mean: a Telegram monitor carries Telegram messages, a Phishing monitor carries phishing records, a Filtered credentials monitor carries credential rows, a Pastebin monitor carries the paste rows a paste search returns, and a Data Brokers monitor carries Data Brokers listings. Excluded rows are hidden unless you send show_excluded=true. count is the total number of rows that match your show_excluded setting and filters, across all pages.

Filter and sort the rows

Each source’s entry in the service catalog lists filterable_fields (a name and a filter type each) and sortable_fields (names). The results endpoint and the export accept two parameters built from them. filters is a JSON object, URL-encoded. Each key is a field name from filterable_fields. The value’s shape depends on the field’s type: Several keys combine with AND. A key that is not in the source’s filterable_fields is ignored without an error, so a misspelt key returns unfiltered rows with 200. Check your keys against the catalog. ordering takes one name from sortable_fields. Prefix it with - for descending order. Without ordering, rows are sorted by created_at, newest first. The rows of one match are recorded together, so send ordering when the order matters. The Data Brokers source, for example, lists site_name, data_type and seller (icontains), country (exact) and scraped_at (date_range) as filterable, and scraped_at, listing_date, price, site_name and country as sortable. This request returns rows whose data_type contains database, scraped from 1 through 7 October, newest first:
These requests return 400:

Set a review status

A match carries one of four statuses: Open (the default), In Progress, False Positive or Resolved. Set it with alert_system_alert_update_alert_match_status:
The status is a label for your workflow. It does not change the rows, the exclusions or the notifications.
The dashboard shows two states: Not Seen (Open) and Seen (Resolved). Opening a match in the dashboard sets it to Resolved unless it already is, whether the person arrives from the incident list, an email or webhook link, or a bookmark. A status of In Progress or False Positive set through the API is replaced with Resolved the first time someone opens that match in the dashboard. If your team also reviews matches in the dashboard, rely on Open and Resolved only.

Export the rows

alert_system_alert_download_alert_match_detail returns a match’s rows as a file. file_type is required: json, csv or excel. The same show_excluded, filters and ordering parameters apply.
The file holds the data object of each row. It is named match_detail_<id>.json, match_detail_<id>.csv or match_detail_<id>.xlsx (excel produces an .xlsx workbook).
  • No rows. When the selection is empty, the call returns 404 with {"error": "No content found."}. That includes a match whose rows are all excluded, unless you send show_excluded=true.
  • Bad file_type. A missing or unknown value returns 400 with {"error": "Invalid file type. Choose 'json', 'csv', or 'excel'."}. The empty-selection check runs first, so when the selection is also empty you get the 404.
  • CSV columns come from the first row. A row that lacks a column gets an empty cell. A later row that carries a field the first row lacks makes the export fail with 502 and {"detail": "The requested service is temporarily unavailable."}. CSV also writes a nested object into one cell as text. For sources whose rows vary in shape, export json, which keeps every field and its structure.
To compare this with the other download routes, see Downloads and exports.

Delete a match

alert_system_alert_delete_alert_match removes a match and all its rows. It returns 204, and the delete cannot be undone.
The monthly distribution and alert-hit statistics on the Metrics page stop counting a deleted match. The overview and history keep counting it for the day it was recorded, today included, unless another match for that source is recorded later that UTC day.

How excluded rows show up

An exclusion flags a row with is_excluded: true when the match is recorded. It never removes the row.
  • The match list and the alert-hit statistics hide matches whose rows are all excluded. Send show_excluded=true to include them.
  • The results endpoint and the export hide flagged rows. Send show_excluded=true to include them.
  • Opening a match by id always works.
  • total_results_count counts every row. excluded_results_count counts the flagged ones.

Endpoints