Skip to main content
POST
List threat detection results for organization

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 detection was created, not on when the asset was first seen, reported or blocked. Leave both out when you want every detection: 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 threat detection
  • "medium" - Medium confidence threat detection
  • "high" - High confidence threat detection
4. Block Status Filter ("blockStatus")
Selects detections whose asset is 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 detections are included by default. Add { "property": "deleted", "operator": "notIn", "value": ["deleted"] } to leave them out, or use "in" to return only deleted detections. 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 has the following structure:

Asset Object

Complete Response Example

Counting and Score Cut-offs

To count detections without paging through them, send includeTotal: true. The response then carries total: how many detections 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 detections for the questions people usually ask when they first look at this data, and the request that answers each one.

Pagination and Incremental Sync

Detections are returned newest first. There is no single-call export: an organization can hold hundreds of thousands of detections, 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 detections

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 detections a day, that is a handful of 1000-row pages.
  1. Record the time the sync starts, and send it as endDate. Detections 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 detection 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 detections come back in two runs.
Deleted detections are included unless you add { "property": "deleted", "operator": "notIn", "value": ["deleted"] } to filters. To fetch only fake-domain detections, add { "property": "assetType", "operator": "in", "value": ["URL"] }.
A startDate sync only returns detections created in the window. If a detection 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 detection results 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 detection results 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 detections 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 detections 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 detections 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 detections 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 detections 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 detections match the filters, search and date range across all pages, regardless of cursor. Present only when includeTotal is true.