Skip to main content
POST
List suspected threats for organization

Overview

Lists your organization’s suspected threats: assets that ChainPatrol’s automated detection flagged. A suspected threat is not confirmed until it is reviewed and blocked. Use the blockStatus filter below to select the ones that have since been confirmed. The API keeps the detection name: the endpoint is /detection/list, results come back in the detections array, and each item is a detection result.

Quick Start

Authentication

Include your API key in the X-API-KEY header:

Example Request

Request Schema

Request Body

startDate and endDate filter on when the suspected threat was created, not on when the asset was first seen, reported or blocked. Leave both out when you want every suspected threat: a date window silently drops older history, which reads as missing results rather than as a filter.

Filter Schema

Each filter object must have the following structure:

Filter Properties

1. Source Filter ("source")
  • "ASSET_CHECK" - Asset verification checks
  • "BING_SEARCH" - Bing search results
  • "CERTSTREAM" - Certificate transparency logs
  • "DNS_TWIST" - DNS twist detection
  • "DUCK_DUCK_GO_SEARCH" - DuckDuckGo search results
  • "EXTERNAL" - External threat submissions
  • "GOOGLE_SEARCH" - Google search results
  • "GUESTBOOK" - Guestbook submissions
  • "MEDIUM_TAG_RSS" - Medium RSS feeds
  • "MOZILLA_ADDON_SEARCH" - Mozilla addon searches
  • "REDDIT_SUBREDDIT_SEARCH" - Reddit subreddit searches
  • "TWITTER" - Twitter monitoring
  • "TWITTER_POST_SEARCH" - Twitter post searches
  • "TWITTER_SEARCH" - Twitter search results
  • "URLSCAN" - URLScan.io results
  • "YAHOO_SEARCH" - Yahoo search results
  • "YANDEX_IMAGE_SEARCH" - Yandex reverse image search results for your brand imagery
  • "YOUTUBE_SEARCH" - YouTube search results
2. Asset Status Filter ("assetStatus")
Available Asset Status Values:
  • "UNKNOWN" - Status not yet determined
  • "ALLOWED" - Asset is legitimate/allowed
  • "BLOCKED" - Asset is blocked/malicious
3. Confidence Filter ("confidence")
Available Confidence Level Values:
  • "none" - No confidence threshold met
  • "low" - Low-confidence suspected threat
  • "medium" - Medium-confidence suspected threat
  • "high" - High-confidence suspected threat
4. Block Status Filter ("blockStatus")
Selects suspected threats whose asset has since become a confirmed threat:
  • "blocked" - the asset is on the blocklist (asset.status is "BLOCKED")
  • "pending" - the asset was confirmed malicious but is not enforced yet, because protection is not active for your organization (asset.pendingStatus is "BLOCKED"). The ChainPatrol app labels these Pending Blocked.
Pass both values to get every confirmed threat, the way the app counts them. The assetStatus filter only sees asset.status, so assetStatus: ["BLOCKED"] leaves pending blocks out. 5. Deleted Filter ("deleted")
Deleted suspected threats are included by default. Add { "property": "deleted", "operator": "notIn", "value": ["deleted"] } to leave them out, or use "in" to return only deleted ones. 6. Asset Type Filter ("assetType")
  • "URL" - Website URLs
  • "PAGE" - Web pages
  • "ADDRESS" - Blockchain addresses
  • "TWITTER" - Twitter profiles/posts
  • "FACEBOOK" - Facebook profiles/pages
  • "YOUTUBE" - YouTube channels/videos
  • "REDDIT" - Reddit posts/subreddits
  • "TELEGRAM" - Telegram channels/groups
  • "DISCORD" - Discord servers (deprecated)
  • "DISCORD_USER" - Discord users
  • "LINKEDIN" - LinkedIn profiles
  • "INSTAGRAM" - Instagram profiles
  • "THREADS" - Threads profiles
  • "TIKTOK" - TikTok profiles
  • "MEDIUM" - Medium articles/profiles
  • "EMAIL" - Email addresses
  • "WHATSAPP" - WhatsApp contacts
  • "GOOGLE_APP_STORE" - Google Play Store apps
  • "APPLE_APP_STORE" - Apple App Store apps
  • "AMAZON_APP_STORE" - Amazon App Store apps
  • "MICROSOFT_APP_STORE" - Microsoft Store apps
  • "CHROME_WEB_STORE" - Chrome extensions
  • "MOZILLA_ADDONS" - Firefox addons
  • "OPERA_ADDONS" - Opera addons
  • "PATREON" - Patreon profiles
  • "OPENSEA" - OpenSea collections/profiles
  • "FARCASTER" - Farcaster profiles
  • "IPFS" - IPFS hashes
  • "GOOGLE_FORM" - Google Forms
  • "QUORA" - Quora profiles/posts
  • "GITHUB" - GitHub repositories/profiles
  • "TEACHABLE" - Teachable courses
  • "SUBSTACK" - Substack publications
  • "DEBANK" - DeBank profiles
  • "TAWK_TO" - Tawk.to chat widgets
  • "JOTFORM" - JotForm forms
  • "PRIMAL" - Primal profiles
  • "BLUESKY" - Bluesky profiles
  • "SNAPCHAT" - Snapchat profiles
  • "DESO" - DeSo profiles

Response Schema

Response Body

Detection Result Object

Each item in the detections array is one suspected threat, with the following structure:

Asset Object

Complete Response Example

Counting and Score Cut-offs

To count suspected threats without paging through them, send includeTotal: true. The response then carries total: how many suspected threats match your filters, search and date range across all pages. It is counted before the cursor is applied, so every page of a sweep reports the same number. It costs an extra count query, so ask for it on the first page rather than on every page. confidence is bucketed from score using your organization’s own thresholds, so "high" does not mean a fixed score. For a fixed cut-off such as “over 80%”, use minScore (and optionally maxScore) instead:
minScore greater than maxScore is rejected with a 400. See Evaluating suspected threats for the questions people usually ask when they first look at this data, and the request that answers each one.

Pagination and Incremental Sync

Suspected threats are returned newest first. There is no single-call export: an organization can hold hundreds of thousands of suspected threats, far more than fit in one response. Page through them instead:
  • Set limit up to 1000.
  • Pass the nextCursor from each response back as cursor.
  • Stop when a response has no nextCursor.
Responses are capped at 4MB. A page that would exceed it fails with a 413 error instead of being cut short. Retry with a smaller limit. A 1000-row page is usually well under 1MB.

Fetching only new suspected threats

After an initial full sync, use startDate so each run only fetches what was created since the previous one. For 1,000–10,000 new suspected threats a day, that is a handful of 1000-row pages.
  1. Record the time the sync starts, and send it as endDate. Suspected threats created while you are paging land at the front of the newest-first order, so without a fixed endDate they would be skipped. The next run picks them up instead.
  2. Set startDate to the previous run’s start time, minus a few minutes of overlap. A suspected threat can take a few seconds to become visible after its createdAt, and the overlap catches it.
  3. Page until nextCursor is absent, and de-duplicate by id. The overlap means some suspected threats come back in two runs.
Deleted suspected threats are included unless you add { "property": "deleted", "operator": "notIn", "value": ["deleted"] } to filters. To fetch only suspected fake domains, add { "property": "assetType", "operator": "in", "value": ["URL"] }.
A startDate sync only returns suspected threats created in the window. If a suspected threat is reported or deleted after you fetched it, the next incremental run will not return it again. Run a periodic full sync (for example, daily) if you need those changes.

Access Control

The API enforces strict access control based on your API key:
  1. Organization API Keys:
    • Can only access suspected threats for their associated organization
    • Must match the slug parameter exactly
    • Example: An API key for “acme-org” can only query results for “acme-org”
  2. User API Keys:
    • Can access suspected threats for any organization where the user is a member
    • Requires the user to be an active member of the queried organization
If you attempt to query an organization without proper permissions, you will receive a 403 Forbidden error with the message: “API key does not have access to this organization”

Example Implementation

Authorizations

X-API-KEY
string
header
required

Your API key. This is required by most endpoints to access our API programatically. Reach out to us at support@chainpatrol.io to get an API key for your use.

Body

application/json
slug
string
required

Organization slug

cursor
number

Pass the nextCursor from the previous response to fetch the next page. Omit it for the first page.

limit
number
default:50

Number of results per page, between 1 and 1000. Defaults to 50.

Required range: 1 <= x <= 1000
filters
object[]

Filters to apply to the results

query
string
default:""

Search query for threat content

minScore
number

Only return suspected threats whose raw score is at least this value (inclusive, 0-1). Use this rather than the confidence filter when you need a fixed cut-off such as 0.8: confidence buckets depend on your organization's thresholds.

Required range: 0 <= x <= 1
maxScore
number

Only return suspected threats whose raw score is at most this value (inclusive, 0-1). Must not be below minScore.

Required range: 0 <= x <= 1
includeTotal
boolean
default:false

Also return total: how many suspected threats match the filters, search and date range across all pages. Costs an extra count query, so request it on the first page of a sweep rather than every page.

startDate
string

Only return suspected threats created at or after this time (inclusive). For incremental syncs, pass the time your previous sync started minus a few minutes of overlap, and de-duplicate by id.

endDate
string

Only return suspected threats created at or before this time (inclusive). Pin it to the time a sync starts so every page of that sync sees the same result set.

Response

Successful response

detections
object[]
required
nextCursor
number
total
number

How many suspected threats match the filters, search and date range across all pages, regardless of cursor. Present only when includeTotal is true.