> ## Documentation Index
> Fetch the complete documentation index at: https://chainpatrol.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# List Organization Threats

> List every asset your organization has reported, with the lifecycle state of each investigation: report opened, escalated, blocklisted, takedown submitted, takedown completed. Built for threat-intel platforms that poll for changes and upsert on asset ID. Supports pagination.

## Overview

List every asset reported for your organization, by your team or by ChainPatrol, with
where each one stands: still under investigation, escalated to you, blocked or
allowed, and how far its takedown has got.

Use it to keep a threat-intel platform, SIEM or ticketing system in step with
ChainPatrol. Page through it once for a backfill, then poll with `updatedSince` and
upsert each row on `id`.

To list only confirmed threats blocked in a date range, use
[`/threats/list`](https://chainpatrol.com/docs/external-api/threats-list). To list unconfirmed detections, use
[`/detection/list`](https://chainpatrol.com/docs/external-api/detection-list).

## Quick Start

### Authentication

Include your API key in the `X-API-KEY` header. Organization API keys resolve the
organization from the key, so `slug` is optional for them.

```bash theme={null}
X-API-KEY: <api-key>
```

### Example Request

```bash theme={null}
curl --request GET \
  --url 'https://app.chainpatrol.io/api/v2/organization/threats?updatedSince=2026-11-01T00:00:00Z&per_page=500' \
  --header 'X-API-KEY: <api-key>'
```

## Query Parameters

| Parameter | Type | Required | Default | Description |
| - | - | - | - | - |
| `slug` | `string` | ❌ No | - | Organization slug. Needed only when your credentials can reach more than one organization. |
| `updatedSince` | `string` | ❌ No | - | ISO 8601 timestamp. Only threats whose asset, reports or takedown changed at or after this time. Omit to backfill. |
| `assetType` | `AssetType` | ❌ No | - | Only threats of this asset type. |
| `per_page` | `number` | ❌ No | `100` | Threats per page, 1 to 1000. |
| `next_page` | `string` | ❌ No | - | The `next_page` value from the previous response. |

## Lifecycle states

`state` sums up each asset's reports and the decision on it:

| `state` | Meaning |
| - | - |
| `investigating` | A report is open and ChainPatrol is reviewing it. |
| `escalated` | A report is open and waiting on a decision from your organization. |
| `blocked` | The asset is on the blocklist. |
| `allowed` | The asset is on the allowlist. |
| `closed` | Every report was reviewed and nothing was blocked. |

A decision on the asset wins over open reports: once it is blocked or allowed,
`state` stays there even if someone reports it again. An asset that was escalated,
decided and then reported again goes back to `investigating`.

The timestamps on each threat:

* `firstReportedAt`: the first report for your organization.
* `escalatedAt`: the first time the asset was escalated to your organization, or
  `null` if it never was.
* `blockedAt`: when the asset was blocked, or `null`.
* `takedown`: `null` until a takedown is opened. `submittedAt` is the first time it
  was filed with a provider, and `completedAt` the first time it was completed. If
  the site comes back, the takedown reopens: `status` goes back to `IN_PROGRESS` while
  `completedAt` keeps the first completion. Watch `status` to catch re-emergence.
* `updatedAt`: the latest change to the asset, its reports or its takedown. This is
  the value `updatedSince` compares against.

## Polling for changes

1. **Backfill.** Call without `updatedSince` and follow `next_page` until it is
   `null`. Note the time you started.
2. **Poll.** Send `updatedSince` set a few minutes before the start of your last
   successful sync, and follow `next_page` until it is `null`, keeping the same
   `updatedSince` on every page. Upsert each threat on `id`.
3. **Advance.** Use the start time of this sync as the watermark for the next one.

> [!WARNING]
>
> Overlap your windows by a few minutes. A change written while a request is running
> can otherwise fall between two polls. The overlap re-sends a few threats you
> already have, which an upsert absorbs.

Pages are ordered by asset `id`, ascending, and the cursor is the last `id` returned,
so assets reported mid-sync land on later pages instead of shifting earlier ones. A
page can hold fewer than `per_page` threats while `next_page` is still set; keep
going until `next_page` is `null`.

```javascript theme={null}
async function syncThreats(apiKey, updatedSince) {
  const threats = [];
  let nextPage = null;

  do {
    const params = new URLSearchParams({ per_page: "1000" });
    if (updatedSince) params.set("updatedSince", updatedSince);
    if (nextPage) params.set("next_page", nextPage);

    const response = await fetch(
      `https://app.chainpatrol.io/api/v2/organization/threats?${params}`,
      { headers: { "X-API-KEY": apiKey } },
    );
    if (!response.ok) throw new Error(`HTTP ${response.status}`);

    const page = await response.json();
    threats.push(...page.threats);
    nextPage = page.next_page;
  } while (nextPage);

  return threats;
}
```


## OpenAPI

````yaml GET /organization/threats
openapi: 3.0.3
info:
  title: ChainPatrol External API - OpenAPI 3.0
  description: ChainPatrol External API documentation
  version: 2.0.0
servers:
  - url: https://app.chainpatrol.io/api/v2
security: []
tags:
  - name: asset
  - name: report
  - name: dark-web
externalDocs:
  url: https://chainpatrol.com/docs
paths:
  /organization/threats:
    get:
      tags:
        - organization
      summary: List organization threats
      description: >-
        List every asset your organization has reported, with the lifecycle
        state of each investigation: report opened, escalated, blocklisted,
        takedown submitted, takedown completed. Built for threat-intel platforms
        that poll for changes and upsert on asset ID. Supports pagination.
      operationId: organizationThreatsList
      parameters:
        - in: query
          name: slug
          schema:
            type: string
        - in: query
          name: updatedSince
          schema:
            type: string
        - in: query
          name: assetType
          schema:
            type: string
            enum:
              - URL
              - PAGE
              - ADDRESS
              - DISCORD
              - LINKEDIN
              - TWITTER
              - FACEBOOK
              - YOUTUBE
              - REDDIT
              - TELEGRAM
              - GOOGLE_APP_STORE
              - APPLE_APP_STORE
              - AMAZON_APP_STORE
              - MICROSOFT_APP_STORE
              - TIKTOK
              - INSTAGRAM
              - THREADS
              - MEDIUM
              - CHROME_WEB_STORE
              - MOZILLA_ADDONS
              - OPERA_ADDONS
              - EMAIL
              - PATREON
              - OPENSEA
              - FARCASTER
              - IPFS
              - GOOGLE_FORM
              - WHATSAPP
              - DISCORD_USER
              - QUORA
              - GITHUB
              - TEACHABLE
              - SUBSTACK
              - DEBANK
              - TAWK_TO
              - JOTFORM
              - PRIMAL
              - BLUESKY
              - SNAPCHAT
              - DESO
              - PINTEREST
              - FLICKR
              - GALXE
              - VELOG
              - NPM
              - PYPI
              - HEX
              - DOCKER_HUB
              - VOCAL_MEDIA
              - TECKFINE
              - TENDERLY
              - HACKMD
              - ETSY
              - ZAZZLE
              - BASENAME
              - BILIBILI_TV
              - VIMEO
              - DAILYMOTION
              - PHONE_NUMBER
              - SLACK
              - CALENDLY
              - NGROK
              - RARIBLE
              - RUST_PACKAGE
              - FLATHUB
              - VIDLII
              - VEVIOZ
              - ISSUU
              - SOUNDCLOUD
              - ZAPPER
              - REDNOTE
              - SAMSUNG_APP_STORE
              - HUAWEI_APP_STORE
              - XIAOMI_APP_STORE
              - TENCENT_APP_STORE
              - OPPO_APP_STORE
              - VIVO_APP_STORE
              - F_DROID
              - GOOGLE_AD
              - BING_AD
              - TWITCH
              - BEHANCE
              - ZORA
              - META_AD
              - SIGNAL
              - DEVIANTART
              - BANDCAMP
              - ARCHIVE_ORG
              - FIVE_HUNDRED_PX
              - LUMA
              - SMARTMONEYMATCH
              - APK_GOLD
              - GLASSDOOR
              - PUMP_FUN
              - TUMBLR
              - MASTODON
        - in: query
          name: per_page
          description: The number of threats to return per page (max 1000)
          schema:
            type: integer
            minimum: 1
            maximum: 1000
            default: 100
            description: The number of threats to return per page (max 1000)
        - in: query
          name: next_page
          description: Cursor for fetching the next page of results
          schema:
            type: string
            nullable: true
            description: Cursor for fetching the next page of results
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                type: object
                properties:
                  threats:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: number
                          description: Asset ID
                        content:
                          type: string
                          description: Asset content (URL, handle, email, etc.)
                        type:
                          type: string
                          enum:
                            - URL
                            - PAGE
                            - ADDRESS
                            - DISCORD
                            - LINKEDIN
                            - TWITTER
                            - FACEBOOK
                            - YOUTUBE
                            - REDDIT
                            - TELEGRAM
                            - GOOGLE_APP_STORE
                            - APPLE_APP_STORE
                            - AMAZON_APP_STORE
                            - MICROSOFT_APP_STORE
                            - TIKTOK
                            - INSTAGRAM
                            - THREADS
                            - MEDIUM
                            - CHROME_WEB_STORE
                            - MOZILLA_ADDONS
                            - OPERA_ADDONS
                            - EMAIL
                            - PATREON
                            - OPENSEA
                            - FARCASTER
                            - IPFS
                            - GOOGLE_FORM
                            - WHATSAPP
                            - DISCORD_USER
                            - QUORA
                            - GITHUB
                            - TEACHABLE
                            - SUBSTACK
                            - DEBANK
                            - TAWK_TO
                            - JOTFORM
                            - PRIMAL
                            - BLUESKY
                            - SNAPCHAT
                            - DESO
                            - PINTEREST
                            - FLICKR
                            - GALXE
                            - VELOG
                            - NPM
                            - PYPI
                            - HEX
                            - DOCKER_HUB
                            - VOCAL_MEDIA
                            - TECKFINE
                            - TENDERLY
                            - HACKMD
                            - ETSY
                            - ZAZZLE
                            - BASENAME
                            - BILIBILI_TV
                            - VIMEO
                            - DAILYMOTION
                            - PHONE_NUMBER
                            - SLACK
                            - CALENDLY
                            - NGROK
                            - RARIBLE
                            - RUST_PACKAGE
                            - FLATHUB
                            - VIDLII
                            - VEVIOZ
                            - ISSUU
                            - SOUNDCLOUD
                            - ZAPPER
                            - REDNOTE
                            - SAMSUNG_APP_STORE
                            - HUAWEI_APP_STORE
                            - XIAOMI_APP_STORE
                            - TENCENT_APP_STORE
                            - OPPO_APP_STORE
                            - VIVO_APP_STORE
                            - F_DROID
                            - GOOGLE_AD
                            - BING_AD
                            - TWITCH
                            - BEHANCE
                            - ZORA
                            - META_AD
                            - SIGNAL
                            - DEVIANTART
                            - BANDCAMP
                            - ARCHIVE_ORG
                            - FIVE_HUNDRED_PX
                            - LUMA
                            - SMARTMONEYMATCH
                            - APK_GOLD
                            - GLASSDOOR
                            - PUMP_FUN
                            - TUMBLR
                            - MASTODON
                          description: Asset type
                        status:
                          type: string
                          enum:
                            - UNKNOWN
                            - ALLOWED
                            - BLOCKED
                          description: Raw asset status
                        pendingStatus:
                          type: string
                          nullable: true
                          enum:
                            - UNKNOWN
                            - ALLOWED
                            - BLOCKED
                            - null
                          description: >-
                            A reviewed status that has not taken effect yet, or
                            null when nothing is pending. `BLOCKED` here means
                            the asset was confirmed malicious but is not
                            enforced on the blocklist because protection is not
                            active for your organization — shown as "Pending
                            Blocked" in the ChainPatrol app. It becomes `status`
                            once protection is activated.
                        state:
                          type: string
                          enum:
                            - investigating
                            - escalated
                            - blocked
                            - allowed
                            - closed
                          description: >-
                            Lifecycle stage: `investigating` (a report is open
                            and under review), `escalated` (an open report has
                            been passed to the organization for a decision),
                            `blocked` (confirmed malicious), `allowed`
                            (confirmed benign / false positive), `closed` (every
                            report reviewed, asset neither blocked nor allowed).
                            `escalated` reflects an escalation that is still
                            open, not one that was decided and followed by a new
                            report. A threat confirmed malicious while
                            protection is not active reports `closed` with
                            `pendingStatus` set to `BLOCKED` — check
                            `pendingStatus` before treating `closed` as benign.
                        livenessStatus:
                          type: string
                          enum:
                            - UNKNOWN
                            - ALIVE
                            - DEAD
                          description: >-
                            Whether the threat is currently reachable (`ALIVE`),
                            gone (`DEAD`), or unchecked (`UNKNOWN`)
                        brands:
                          type: array
                          items:
                            type: object
                            properties:
                              slug:
                                type: string
                                description: Brand slug
                              name:
                                type: string
                                description: Brand name
                            required:
                              - slug
                              - name
                          description: >-
                            The brands of yours this threat was reported
                            against. Empty when no report named one.
                        firstReportedAt:
                          type: string
                          description: >-
                            When this organization first filed a report against
                            the asset
                        escalatedAt:
                          type: string
                          nullable: true
                          description: >-
                            When the asset was *first* escalated to this
                            organization for a decision, or null if it never
                            was. This is escalation history, not current state:
                            an asset escalated once and later reported again
                            reports `escalated_at` alongside a `state` of
                            `investigating`. Read `state` to know whether
                            anything is waiting on you right now.
                        blockedAt:
                          type: string
                          nullable: true
                          description: >-
                            When the asset was blocklisted, or null if it has
                            not been. For a threat whose `pendingStatus` is
                            `BLOCKED`, this is when the block was confirmed; it
                            is not enforced until protection is activated.
                        takedown:
                          type: object
                          nullable: true
                          properties:
                            status:
                              type: string
                              enum:
                                - TODO
                                - IN_PROGRESS
                                - COMPLETED
                                - CANCELLED
                                - PENDING_RETRACTION
                                - RETRACTION_SENT
                                - RETRACTED
                                - PENDING_INPUT
                                - PENDING_EVIDENCE
                              description: Current takedown status
                            submittedAt:
                              type: string
                              nullable: true
                              description: >-
                                When the first takedown request was submitted to
                                a provider, or null if nothing has been
                                submitted yet
                            completedAt:
                              type: string
                              nullable: true
                              description: >-
                                When the takedown was marked completed, or null
                                if it has not been
                          required:
                            - status
                            - submittedAt
                            - completedAt
                          description: Takedown progress, or null if no takedown was opened
                        detailsUrl:
                          type: string
                          description: >-
                            Deep link to the asset's reports and takedowns in
                            the ChainPatrol app
                        updatedAt:
                          type: string
                          description: >-
                            The most recent change to anything in this record —
                            the asset, its reports, its takedown or that
                            takedown's tasks. Matches what `updatedSince`
                            filters on. To derive your next watermark, drain
                            every page until `next_page` is null and take the
                            highest value across the whole sweep: results are
                            ordered by asset ID, not by this field, so a later
                            page can carry an earlier timestamp and a per-page
                            watermark would skip it.
                      required:
                        - id
                        - content
                        - type
                        - status
                        - pendingStatus
                        - state
                        - livenessStatus
                        - brands
                        - firstReportedAt
                        - escalatedAt
                        - blockedAt
                        - takedown
                        - detailsUrl
                        - updatedAt
                  next_page:
                    type: string
                    nullable: true
                    description: >-
                      Cursor for fetching the next page of results, or null on
                      the last page. Drain it to null before advancing your
                      `updatedSince` watermark — see `updatedAt`.
                required:
                  - threats
                description: Successful operation
        '400':
          description: Invalid input data
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error.BAD_REQUEST'
        '401':
          description: Authorization not provided
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error.UNAUTHORIZED'
        '403':
          description: Insufficient access
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error.FORBIDDEN'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error.NOT_FOUND'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error.INTERNAL_SERVER_ERROR'
      security:
        - ApiKey: []
components:
  schemas:
    error.BAD_REQUEST:
      type: object
      properties:
        message:
          type: string
          description: The error message
          example: Invalid input data
        code:
          type: string
          description: The error code
          example: BAD_REQUEST
        issues:
          type: array
          items:
            type: object
            properties:
              message:
                type: string
            required:
              - message
          description: An array of issues that were responsible for the error
          example: []
      required:
        - message
        - code
      title: Invalid input data error (400)
      description: The error information
      example:
        code: BAD_REQUEST
        message: Invalid input data
        issues: []
    error.UNAUTHORIZED:
      type: object
      properties:
        message:
          type: string
          description: The error message
          example: Authorization not provided
        code:
          type: string
          description: The error code
          example: UNAUTHORIZED
        issues:
          type: array
          items:
            type: object
            properties:
              message:
                type: string
            required:
              - message
          description: An array of issues that were responsible for the error
          example: []
      required:
        - message
        - code
      title: Authorization not provided error (401)
      description: The error information
      example:
        code: UNAUTHORIZED
        message: Authorization not provided
        issues: []
    error.FORBIDDEN:
      type: object
      properties:
        message:
          type: string
          description: The error message
          example: Insufficient access
        code:
          type: string
          description: The error code
          example: FORBIDDEN
        issues:
          type: array
          items:
            type: object
            properties:
              message:
                type: string
            required:
              - message
          description: An array of issues that were responsible for the error
          example: []
      required:
        - message
        - code
      title: Insufficient access error (403)
      description: The error information
      example:
        code: FORBIDDEN
        message: Insufficient access
        issues: []
    error.NOT_FOUND:
      type: object
      properties:
        message:
          type: string
          description: The error message
          example: Not found
        code:
          type: string
          description: The error code
          example: NOT_FOUND
        issues:
          type: array
          items:
            type: object
            properties:
              message:
                type: string
            required:
              - message
          description: An array of issues that were responsible for the error
          example: []
      required:
        - message
        - code
      title: Not found error (404)
      description: The error information
      example:
        code: NOT_FOUND
        message: Not found
        issues: []
    error.INTERNAL_SERVER_ERROR:
      type: object
      properties:
        message:
          type: string
          description: The error message
          example: Internal server error
        code:
          type: string
          description: The error code
          example: INTERNAL_SERVER_ERROR
        issues:
          type: array
          items:
            type: object
            properties:
              message:
                type: string
            required:
              - message
          description: An array of issues that were responsible for the error
          example: []
      required:
        - message
        - code
      title: Internal server error error (500)
      description: The error information
      example:
        code: INTERNAL_SERVER_ERROR
        message: Internal server error
        issues: []
  securitySchemes:
    ApiKey:
      type: apiKey
      in: header
      name: X-API-KEY
      description: >-
        Your API key. This is required by most endpoints to access our API
        programatically. Reach out to us at
        [support@chainpatrol.io](mailto:support@chainpatrol.io?subject=Re:%20API%20Key%20for%20SDK&body=Company:%20%0AName:%20%0APurpose:%20)
        to get an API key for your use.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.