> ## 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.

# Asset List

> Answers 'which assets does ChainPatrol hold at this status?'. Returns a paginated list defaulting to `BLOCKED`, optionally narrowed to a single `type` and to a date range. Omit `type` to sweep every asset type on one cursor, which is the cheapest way to mirror the whole blocklist. Built for bulk export and sync — pass `next_page` from the previous response to continue. To check one specific asset, use `/asset/check` instead; for an organization's own monitored assets, use `/organization/assets`.

## Quick Start

### Authentication

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

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

## Asset Types

`type` is optional. Omit it to return assets of **every** asset type on a single
pagination cursor:

```json theme={null}
{ "status": "BLOCKED", "per_page": 1000 }
```

This is the cheapest way to mirror the full blocklist — one paginated sweep
instead of one sweep per member of the `AssetType` enum. Each returned asset
still carries its own `type`, so you can bucket the results client-side.

Supply `type` to narrow the sweep to a single asset type, exactly as before:

```json theme={null}
{ "type": "URL", "status": "BLOCKED", "per_page": 1000 }
```

Omit the field entirely to get the full sweep. An explicit `"type": null` is
rejected with a 400, so a client that builds the body from a struct should leave
the key out rather than setting it to null.

> [!NOTE]
>
> A single response returns at most **1000** assets, whatever `per_page` asks for.
> Larger values are accepted but clamped, so always keep following `next_page`
> until it comes back `null` rather than assuming one page holds everything.
> Responses are also capped at 4MB.

## Sync Strategy and Removals

> [!WARNING]
>
> When using time-based filtering (e.g., fetching only the last 5 minutes of blocklist data), you may miss asset removals from the blocklist. To ensure complete data consistency, use one of these approaches:

### Recommended Approaches

1. **Monitor allowlist and unknown list for removals**: Check both the allowlist and unknown list endpoints periodically to detect assets that have been removed from the blocklist.

2. **Periodic full sync**: Perform a complete sync of the full blocklist at regular intervals (e.g., hourly or daily) to catch any missed changes.

3. **Hybrid approach**: Use time-based filtering for frequent updates combined with periodic full syncs for comprehensive coverage.

### Why This Matters

Asset status changes can move assets between different lists (blocklist, allowlist, unknown). Time-based queries on a single endpoint may not capture these transitions, potentially leaving your local cache with outdated information about blocked assets that should no longer be blocked.

### Soft-Deleted Assets

Assets that ChainPatrol has soft-deleted are excluded from every response, so a
mirror built from this endpoint matches ChainPatrol's own blocklist snapshot.

This is a change in behaviour: the endpoint previously returned soft-deleted
assets. A mirror built before the change may be holding rows that will never
appear again — a full re-sync clears them.

## Pagination

To use pagination, include the `per_page` and `next_page` parameters in your request:

* `per_page <number>`: Items per page. Accepted up to 10000, but a response returns at most 1000 — always follow `next_page`.
* `next_page <string>`: Cursor for the next page of results

### Example implementation for pagination:

```javascript JavaScript theme={null}
// Pass `type` to sweep one asset type, or leave it out to sweep them all.
async function fetchAllAssets(status, type) {
  let allAssets = [];
  let nextPage = null;
  while (true) {
    const response = await fetch(
      "https://app.chainpatrol.io/api/v2/asset/list",
      {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "X-API-KEY": "YOUR_API_KEY_HERE",
        },
        body: JSON.stringify({
          ...(type ? { type } : {}),
          status,
          per_page: 1000,
          next_page: nextPage,
        }),
      }
    );
    const data = await response.json();
    allAssets = allAssets.concat(data.assets);
    nextPage = data.next_page;
    if (!nextPage) {
      break;
    }
  }
  return allAssets;
}
// Every asset type in one sweep:
fetchAllAssets("BLOCKED")
  .then((assets) => console.log("All assets:", assets))
  .catch((error) => console.error("Error fetching assets:", error));
```

```typescript TypeScript theme={null}
// `type` is optional — omit it to sweep every asset type on one cursor.
async function fetchAllAssets(status: string, type?: string): Promise<any[]> {
  let allAssets: any[] = [];
  let nextPage: string | null = null;

  while (true) {
    const response = await fetch(
      "https://app.chainpatrol.io/api/v2/asset/list",
      {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "X-API-KEY": "YOUR_API_KEY_HERE",
        },
        body: JSON.stringify({
          ...(type ? { type } : {}),
          status,
          per_page: 1000,
          next_page: nextPage,
        }),
      }
    );
    const data = await response.json();
    allAssets = allAssets.concat(data.assets);
    nextPage = data.next_page;

    if (!nextPage) {
      break;
    }
  }
  return allAssets;
}

// Every asset type in one sweep:
fetchAllAssets("BLOCKED")
  .then((assets) => console.log("All assets:", assets))
  .catch((error) => console.error("Error fetching assets:", error));
```

```python Python theme={null}
import requests

# `type` is optional. Leave the key out of the body entirely to sweep every
# asset type on one cursor.
def fetch_all_assets(status: str, type: str | None = None) -> list:
    all_assets = []
    next_page = None
    while True:
        body = {
            "status": status,
            "per_page": 1000,
            "next_page": next_page,
        }
        if type is not None:
            body["type"] = type
        response = requests.post(
            "https://app.chainpatrol.io/api/v2/asset/list",
            headers={
                "Content-Type": "application/json",
                "X-API-KEY": "YOUR_API_KEY_HERE",
            },
            json=body,
        )
        data = response.json()
        all_assets.extend(data["assets"])
        next_page = data.get("next_page")
        if not next_page:
            break
    return all_assets

try:
    # Every asset type in one sweep:
    assets = fetch_all_assets("BLOCKED")
    print("All assets:", assets)
except Exception as error:
    print("Error fetching assets:", str(error))
```


## OpenAPI

````yaml POST /asset/list
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:
  /asset/list:
    post:
      tags:
        - asset
      summary: List assets
      description: >-
        Answers 'which assets does ChainPatrol hold at this status?'. Returns a
        paginated list defaulting to `BLOCKED`, optionally narrowed to a single
        `type` and to a date range. Omit `type` to sweep every asset type on one
        cursor, which is the cheapest way to mirror the whole blocklist. Built
        for bulk export and sync — pass `next_page` from the previous response
        to continue. To check one specific asset, use `/asset/check` instead;
        for an organization's own monitored assets, use `/organization/assets`.
      operationId: assetList
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                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 to retrieve. Omit the field entirely to retrieve
                    assets of every type in a single paginated sweep; an
                    explicit null is rejected.
                status:
                  type: string
                  enum:
                    - UNKNOWN
                    - ALLOWED
                    - BLOCKED
                  default: BLOCKED
                  description: Status of the assets to retrieve
                startDate:
                  type: string
                  description: >-
                    The start date to list assets from. This should be in the
                    format `YYYY-MM-DD` and is inclusive.
                endDate:
                  type: string
                  description: >-
                    The end date to list assets from. This should be in the
                    format `YYYY-MM-DD` and is inclusive.
                per_page:
                  type: integer
                  minimum: 1
                  maximum: 10000
                  default: 100
                  description: The number of assets to return per page
                next_page:
                  type: string
                  nullable: true
                  description: Cursor for fetching the next page of results
              description: >-
                List asset request body


                With no `startDate`, this returns every matching asset
                regardless of age — there

                is no implicit one-day window. Pass `startDate` to get a delta
                instead.


                You can also choose a `startDate` and `endDate` for the range of
                asset updates, most 

                timestamp formats should work, we use
                [Luxon](https://moment.github.io/luxon/#/parsing) 

                for parsing the dates.
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                type: object
                properties:
                  assets:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: number
                          description: >-
                            Asset ID — use to reference the asset in follow-up
                            calls
                        content:
                          type: string
                          description: Asset content
                        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: The result of the asset status check
                        watchStatus:
                          type: string
                          enum:
                            - ENABLED
                            - DISABLED
                          description: The watch status of the asset
                        livenessStatus:
                          type: string
                          nullable: true
                          enum:
                            - UNKNOWN
                            - ALIVE
                            - DEAD
                            - null
                          description: >-
                            Whether the asset is currently reachable (`ALIVE`),
                            gone (`DEAD`), or hasn't been checked (`UNKNOWN`).
                            `null` when liveness has never been evaluated.
                        blockedAt:
                          type: string
                          nullable: true
                          description: >-
                            When the asset transitioned to BLOCKED status.
                            `null` for non-blocked assets or blocks predating
                            the field. Distinct from `updatedAt`, which changes
                            on any mutation.
                        updatedAt:
                          type: string
                      required:
                        - id
                        - content
                        - type
                        - status
                        - watchStatus
                        - livenessStatus
                        - blockedAt
                        - updatedAt
                  next_page:
                    type: string
                    nullable: true
                    description: Cursor for fetching the next page of results
                required:
                  - assets
                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'
        '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.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.