NAV NAV
cURL

Introduction

You can use the Entity Risking API to retrieve risk assessments of address-based entities, such as personal wallets or contract addresses. Once you have the risk assessments, you can use them to help determine whether to interact with the address. If you have a dApp, you can control the address's access to your application. Or, if you're a liquidity provider, you can better understand the risks of contributing to a liquidity pool.

Getting started

Creating an API key

To create an API key:

  1. Sign in to the Risk UI.
  2. From the navigation menu, click Tools, select the Developers drop-down, then select API keys.
  3. If an API Key is present, copy it. Alternatively, click Generate API Key and copy it. Use the API Key to authenticate the Entities endpoints and learn more about workflows in Workflows.

Authentication

The Entities API uses a unique API token to authorize calls. You pass this unique token in the header:

curl -X GET {API URL} \
--header "Token: {YOUR_API_TOKEN}" \
--header "Accept: application/json" 

Environments

We recommend using a sandbox instance to test initial API integration and validation. Once you have finished testing and completed the integration, you can move to a second, "clean" instance with a new API key. This second instance will be your primary, ongoing instance.

Please contact your CSM to help you create your instances and obtain their credentials.

Environment URLs:

Security: All API access is secured using HTTPS with TLS (v1.2) being supported.

Base URL

The base URL of the API is: api.chainalysis.com/api/risk.

Rate limits

The Entity Risking API uses rate limiters to help manage the flow of requests to the API, increasing its stability. If you send too many requests in quick succession, you will see error responses with status code 429. The rate limiter restricts requests to 40 per second.

Workflows

Below are example workflows that can be used with the Entities API.

Get risk for a private address

  1. An end-user connects their private wallet to your application.
  2. Call the GET endpoint with the end-users address to retrieve the address's risk assessment.
  3. Using the risk assessment, decide whether to allow the address to interact with your application.

Get risk for a contract address

  1. Identify a liquidity pool you're interested in providing liquidity for.
  2. Call the GET endpoint with the liqduidity pool's contract address to retrieve its risk assessment.
  3. Using the risk assessment, decide whether to contribute liquidity to the pool.

Rescreen an address for changes in risk

  1. Determine a cadence to rescreen addresses based on your compliance needs (e.g., monthly).
  2. Call the GET endpoint with the chosen address at that cadence to check for changes in risk.
  3. Decide whether to take an action based on any updated information.

Get an audit trail of the risk of screened addresses

  1. Call the GET endpoint to screen an address, then store the results of the screen.
  2. Rescreen addresses and store results of the rescreen.
  3. Aggregate all responses and create a report as needed.

Risk

How risk is determined

Risk assessments come as either Severe, High, Medium, or Low scores. Entity risking provides two vectors to determine an address's score:

Each category has a starter risk assessment and starter exposure threshold (a percentage of total exposure) to a given category. If an address meets two or more criteria, whichever score is greater is assigned to the address.

For example, address 0x123abc may have an entity category of Darknet Market (constituting a score of High) and have 20% direct exposure to a sanctioned entity (constituting a risk score of Severe). Since the exposure score is the greater of the two, the address 0x123abc will have a Severe score. We calculate exposure values using both directions (sent and received).

To learn more about how Chainalysis defines exposure and categorizes entities, see:

Viewing and customizing risk settings

Entity risking’s starter rules should be tailored to meet your compliance needs. Today, we only provide starter rules for direct exposure and don’t provide starter rules for indirect exposure. You can view your organization’s risk settings by clicking Tools > Risk settings, then navigating to the Entities tab.

Since indirect exposure does not come with starter rules, you must configure them. Until you do, the risk value will remain unaffected by indirect exposure, even though indirect exposure values return in the exposures array.

Example

As an example, if you’re in a jurisdiction where gambling is legal, you might want to set addresses categorized as Gambling to Low to help reduce false positives. If set to Low, these addresses will only return a Low score unless they also meet a specific exposure percentage threshold.

As a second step, you can adjust the exposure percentage thresholds. For example, you can set 1%-25% exposure to Mixing to return Medium, 25%-90% to return High, and 90%-100% to return Severe. Setup like this, a Gambling address will always score Low unless it has Mixing exposure:

For exposure thresholds, the lower bound is always exclusive and the upper bound is always inclusive (10%-20% means greater than 10% and less than or equal to 20%).

Addresses to test

The following are some addresses that you can test the API with:

Each address above is on the SDN List and will by default return a Severe value for the risk property.

API reference

Entity risking

These endpoints allow you retrieve a risk assessment an address:

Retrieve risk assessment

ENDPOINT

GET /v2/entities/{address}

This endpoint retrieves the risk assessment for a specified address.

The following is an example cURL request to view the risk assessment for the address 0x0038AC785dfB6C82b2c9A7B3B6854e08a10cb9f1:

curl -X GET 'https://api.chainalysis.com/api/risk/v2/entities/0x0038AC785dfB6C82b2c9A7B3B6854e08a10cb9f1' \
--header 'Token: {YOUR_API_TOKEN}' \
--header 'Content-Type: application/json' \

Path parameters

Parameter Type Required Description
address String Yes The address that you want to retrieve a risk assessment for.

Response schema

The following is an example JSON response body when retrieving the risk assessment of a clean private wallet (0x0038AC785dfB6C82b2c9A7B3B6854e08a10cb9f1):

{
    "address": "0x0038AC785dfB6C82b2c9A7B3B6854e08a10cb9f1",
    "risk": "Low",
    "riskReason": null,
    "cluster": null,
    "addressType": "PRIVATE_WALLET",
    "addressIdentifications": [],
    "exposures": [
        {
            "category": "exchange",
            "value": 424895.68594
        },
        {
            "category": "fee",
            "value": 1108.16272
        },
        {
            "category": "unnamed service",
            "value": 3612152.81483
        }
    ],
    "triggers": [],
    "status": "COMPLETE"
}

The following is an example JSON response body when retrieving the risk assessment of a risky private wallet (0x2337bBCD5766Bf2A9462D493E9A459b60b41B7f2):

{
    "address": "0x2337bBCD5766Bf2A9462D493E9A459b60b41B7f2",
    "risk": "Severe",
    "cluster": null,
    "riskReason": "> 55% indirect exposure to Sanctioned Jurisdiction",
    "addressType": "PRIVATE_WALLET",
    "addressIdentifications": [],
    "exposures": [
        {
            "category": "exchange",
            "value": 18912691.08382
        },
        {
            "category": "fee",
            "value": 74901.03290
        },
        {
            "category": "no kyc exchange",
            "value": 37457.26330
        },
        {
            "category": "other",
            "value": 72.82114
        },
        {
            "category": "sanctioned jurisdiction",
            "value": 29927285.77654
        },
        {
            "category": "scam",
            "value": 774.35881
        }
    ],
    "triggers": [
        {
            "category": "sanctioned jurisdiction",
            "percentage": 50.641326,
            "message": "> 50% exposure to sanctioned jurisdiction",
            "ruleTriggered": {
                "risk": "Severe",
                "minThreshold": 0.0,
                "maxThreshold": 1.0,
                "exposureType": "direct",
                "direction": "both_directions"
            }
        },
        {
            "category": "scam",
            "percentage": 0.001310,
            "message": "> 0% exposure to scam",
            "ruleTriggered": {
                "risk": "High",
                "minThreshold": 0.0,
                "maxThreshold": 1.0,
                "exposureType": "direct",
                "direction": "both_directions"
            }
        }
    ],
    "status": "COMPLETE"
}

The following is an example JSON response body when retrieving the risk assessment for an address with an OFAC sanctions designation (0x53b6936513e738f44FB50d2b9476730C0Ab3Bfc1):

{
    "address": "0x53b6936513e738f44FB50d2b9476730C0Ab3Bfc1",
    "risk": "Severe",
    "riskReason": "Identified as Sanctioned Entity",
    "addressType": "PRIVATE_WALLET",
    "cluster": {
        "name": "OFAC SDN Lazarus Group 2022-04-22",
        "category": "sanctioned entity"
    },
    "addressIdentifications": [
        {
            "name": "SANCTIONED ENTITY: OFAC SDN Lazarus Group 2022-04-22 53b6936513e738f44fb50d2b9476730c0ab3bfc1",
            "address": "53b6936513e738f44fb50d2b9476730c0ab3bfc1",
            "category": "sanctioned entity",
            "description": "This specific address 0x53b6936513e738f44FB50d2b9476730C0Ab3Bfc1​​​​ has been identified as belonging to Lazarus Group.\n\nLAZARUS GROUP (a.k.a. \"APPLEWORM\"; a.k.a. \"APT-C-26\"; a.k.a. \"GROUP 77\"; a.k.a. \"GUARDIANS OF PEACE\"; a.k.a. \"HIDDEN COBRA\"; a.k.a. \"OFFICE 91\"; a.k.a. \"RED DOT\"; a.k.a. \"TEMP.HERMIT\"; a.k.a. \"THE NEW ROMANTIC CYBER ARMY TEAM\"; a.k.a. \"WHOIS HACKING TEAM\"; a.k.a. \"ZINC\"), Potonggang District, Pyongyang, Korea, North; Digital Currency Address - ETH 0x098B716B8Aaf21512996dC57EB0615e2383E2f96; Secondary sanctions risk: North Korea Sanctions Regulations, sections 510.201 and 510.210; Transactions Prohibited For Persons Owned or Controlled By U.S. Financial Institutions: North Korea Sanctions Regulations section 510.214 [DPRK3]. -to- LAZARUS GROUP (a.k.a. \"APPLEWORM\"; a.k.a. \"APT-C-26\"; a.k.a. \"GROUP 77\"; a.k.a. \"GUARDIANS OF PEACE\"; a.k.a. \"HIDDEN COBRA\"; a.k.a. \"OFFICE 91\"; a.k.a. \"RED DOT\"; a.k.a. \"TEMP.HERMIT\"; a.k.a. \"THE NEW ROMANTIC CYBER ARMY TEAM\"; a.k.a. \"WHOIS HACKING TEAM\"; a.k.a. \"ZINC\"), Potonggang District, Pyongyang, Korea, North; Digital Currency Address - ETH 0x098B716B8Aaf21512996dC57EB0615e2383E2f96; alt. Digital Currency Address - ETH 0xa0e1c89Ef1a489c9C7dE96311eD5Ce5D32c20E4B; alt. Digital Currency Address - ETH 0x3Cffd56B47B7b41c56258D9C7731ABaDc360E073; alt. Digital Currency Address - ETH 0x53b6936513e738f44FB50d2b9476730C0Ab3Bfc1; Secondary sanctions risk: North Korea Sanctions Regulations, sections 510.201 and 510.210; Transactions Prohibited For Persons Owned or Controlled By U.S. Financial Institutions: North Korea Sanctions Regulations section 510.214 [DPRK3]. \n\nhttps://home.treasury.gov/policy-issues/financial-sanctions/recent-actions/202204222",
            "url": "https://home.treasury.gov/policy-issues/financial-sanctions/recent-actions/202204222",
            "createdAt": 1650844800000
        },
        {
            "name": "OTHER: Blocked by Tether 53b6936513e738f44fb50d2b9476730c0ab3bfc1",
            "address": "53b6936513e738f44fb50d2b9476730c0ab3bfc1",
            "category": "other",
            "description": "On 2023-12-09 17:06:23 Tether executed a blocking action on address 0x53b6936513e738f44fb50d2b9476730c0ab3bfc1 via transaction hash 0x825b48bfc004eacdb55fafe1abec47bebb51aa4bdd53720d607d795b558ff995.",
            "createdAt": 1720396800000
        }
    ],
    "exposures": [
        {
            "category": "fee",
            "value": 35.95914
        },
        {
            "category": "sanctioned entity",
            "value": 152638682.86834
        }
    ],
    "triggers": [
        {
            "category": "sanctioned entity",
            "percentage": 51.537210,
            "message": "> 51% exposure to sanctioned entity",
            "ruleTriggered": {
                "risk": "Severe",
                "minThreshold": 0.0,
                "maxThreshold": 1.0,
                "exposureType": "direct",
                "direction": "both_directions"
            }
        }
    ],
    "status": "COMPLETE"
}

The following is an example JSON response body when retrieving the risk assessment of an address owned by an exchange that has an address-level identification of scam (32PUt3ijeewVN2jjoYJqP9ReDfjhqHW3EL):

{
    "address": "32PUt3ijeewVN2jjoYJqP9ReDfjhqHW3EL",
    "risk": "High",
    "riskReason": "Identified as Scam",
    "addressType": "PRIVATE_WALLET",
    "cluster": {
        "name": "Coinbase.com",
        "category": "exchange"
    },
    "addressIdentifications": [
        {
            "name": "SCAM: Alpha-Cash.com 32PUt3ijeewVN2jjoYJqP9ReDfjhqHW3EL",
            "address": "32PUt3ijeewVN2jjoYJqP9ReDfjhqHW3EL",
            "category": "scam",
            "description": "This specific address 32PUt3ijeewVN2jjoYJqP9ReDfjhqHW3EL within the cluster has been identified as Alpha-Cash.com.",
            "createdAt": 1591315200000
        }
    ],
    "exposures": [],
    "triggers": [],
    "status": "COMPLETE"
}

The following is an example JSON response body when retrieving the risk assessment of a liquidity pool (0x512011c2573e0EcBd66be051b9A1C0fd097F2092):

{
    "address": "0x512011c2573e0EcBd66be051b9A1C0fd097F2092",
    "risk": "Low",
    "riskReason": null,
    "addressType": "LIQUIDITY_POOL",
    "cluster": {
        "name": "Uniswap V3: WETH 0xc02aaa - CMB 0xc6db55 (0.3%)",
        "category": "decentralized exchange"
    },
    "addressIdentifications": [],
    "exposures": [
        {
            "category": "decentralized exchange",
            "value": 8902121.21723
        }
    ],
    "triggers": [],
    "status": "COMPLETE",
    "poolMetadata": {
        "fees": 0.3,
        "tokens": [
            "WETH",
            "CMB"
        ]
    }
}

The following is an example JSON response body when you have indirect exposure enabled:

{
    "address": "0x2337bBCD5766Bf2A9462D493E9A459b60b41B7f2",
    "risk": "Severe",
    "riskReason": "> 50% Indirect Exposure To Sanctioned Jurisdiction",
    "cluster": null,
    "addressIdentifications": [],
    "exposures": [
        {
            "category": "sanctioned jurisdiction",
            "value": 3660.77658,
            "exposureType": "direct",
            "direction": "both_directions"
        },
        {
            "category": "sanctioned jurisdiction",
            "value": 5000.35881,
            "exposureType": "indirect",
            "direction": "both_directions"
        }
    ],
    "triggers": [
        {
            "category": "sanctioned jurisdiction",
            "percentage": 50.641326,
            "message": "> 50% indirect exposure to sanctioned jurisdiction",
            "ruleTriggered": {
                "risk": "Severe",
                "minThreshold": 0.0,
                "maxThreshold": 1.0,
                "exposureType": "direct",
                "direction": "both_directions"
            }
        }
    ],
    "status": "COMPLETE"
}

A successful request will return the following JSON response.

Property Type Description
address String The address that you are assessing the risk of.
risk String The risk assessment of the address. Values can be Severe, High, Medium, or Low. The assessment is whichever is greater between the category or exposure assessments.
riskReason String or null A human-readable string that provides the rationale for the returned risk assessment.
cluster Object or null An object that contains any available cluster information for the provided address. If the object returns null, the address has not been clustered.
cluster.name String The name of the identified cluster.
cluster.category String The category of the identified cluster.
addressType String The entity type of the address, either PRIVATE_WALLET, LIQUIDITY_POOL, SERVICE_PROVIDER.
addressIdentifications Array An array that contains any available Chainalysis Address Identification information. These are used to identify individual addresses part of a larger cluster. If the array is empty, the address has no address-level identification.
addressIdentifications.name String The name designated to the Chainalysis Address Identification.
addressIdentifications.address String The address of the Chainalysis Address Identification.
addressIdentifications.category String The category of the Chainalysis Address Identification.
addressIdentifications.description String The OSINT from the Chainalysis Address Identification.
addressIdentifications.url String or null A URL that points to the original source for the Chainalysis Address Identification, typically that of a governing body.
addressIdentifications.createdAt Integer The time when the address was assigned a Chainalysis Address Identification, measured in milliseconds since the Unix epoch.
exposures Array or null An array that contains the address's current exposures.
exposures.category String The entity category the address has exposure to.
exposures.value Number Denotes the exposure to the corresponding category, denominated in USD. If indirect exposure is not enabled, it represents only direct exposure, and aggregates both sent and received directions.
exposures.exposureType String The exposure type, either direct or indirect. If you don’t have access to indirect exposure, this property will only return direct. This value aggregates sent and received directions (both directions).
exposures.direction String The exposure direction. The value will only be both_directions.
triggers Array or null An array containing information about any exposure rules the address triggered.
triggers.category String The entity category of the triggered exposure rule.
triggers.percentage Number The percentage of exposure the address has to the corresponding category.
triggers.message String A short, human-readable description of the trigger.
triggers.ruleTriggered Object or null An object containing details about the exposure rule the address triggered, such as thresholds of the triggered exposure rule, the riskiness assigned to the address when this rule is triggered, exposure direction, and exposure type.
triggers.ruleTriggered.risk String The riskiness assigned to the address when this rule is triggered.
triggers.ruleTriggered.minThreshold Number The lower bound of the triggered exposure rule. This threshold is always exclusive (e.g., >) and the number correlates to a percentage. For example, 10.0 means >10%.
triggers.ruleTriggered.maxThreshold Number The upper bound of the triggered exposure rule. This threshold is always inclusive (e.g., <=) and the number correlates to a percentage. For example, 20.0 means <=20%.
triggers.ruleTriggered.exposureType String The exposure type, either direct or indirect. If you don’t have access to indirect exposure, this property will only return direct. This value aggregates sent and received directions (both directions).
triggers.ruleTriggered.direction String The exposure direction. The value will only be both_directions.
status String A string that indicates the exposure check's status. Currently, the only possible value is COMPLETE. While there were previously other options (IN_PROGRESS and PENDING), improvements have made these statuses obsolete, and you should now only ever see the COMPLETE status.
poolMetadata Object An object that contains metadata about the liquidity pool. Note: This property only returns if the screened address is a liquidity pool.
poolMetadata.fees Number or null The fees associated with the pool. It is expressed in scientific notation, where 1.0E-4 is equivalent to 0.0001. This value is typically a small number, representing a percentage of the transaction.
poolMetadata.tokens Array An array that contains the symbols of the tokens traded in the pool. Each string in the array is a token symbol. For example, WETH and NIOX are token symbols.

Register address (legacy)

ENDPOINT

POST /v2/entities

This endpoint registers an address.

The following is an example cURL request to register the address 0x0038AC785dfB6C82b2c9A7B3B6854e08a10cb9f1:

curl -X POST 'https://api.chainalysis.com/api/risk/v2/entities' \
--header 'Token: {YOUR_API_TOKEN}' \
--header 'Content-Type: application/json' \
--data-raw '{
    "address": "0x0038AC785dfB6C82b2c9A7B3B6854e08a10cb9f1"
}'

Request body schema

Property Type Required Description
address String Yes The address that you want to register.

Response schema

The following is an example JSON response body for a successful registration of an address:

{
    "address": "0x0038AC785dfB6C82b2c9A7B3B6854e08a10cb9f1"
}

A successful request will return the following JSON response.

Property Type Description
address String An echoback of the address you registered.

Error handling

Entities Risking uses standard HTTP response codes to indicate the success or failure of an API request.

Response codes in the 2xx range indicate success. Response codes in the 4xx range indicate an error due to the information provided, such as a missing or incorrectly formatted parameter or request body property. Response codes in the 5xx range indicate an internal server error within Chainalysis.

Entities API codes and meaning

Code Meaning Description
200 Successful request The request was successful.
400 Bad request The request was unacceptable. This may refer to a missing or improperly formatted parameter or request body property, non-valid JSON, or the use of testnet blockchain data.
403 Forbidden Your API key is invalid. This may be because your API Key is expired or not sent correctly as the value of the Token HTTP header.
404 Not found This may be because you either requested a nonexistent endpoint or referenced a user that does not exist.
406 Not acceptable You requested a response format that the API cannot produce. We currently only support JSON output.
409 Conflict The request has a conflict.
429 Too many requests Too many requests hit the API too quickly. See Rate limits for more information.
500 Internal server error (Rare.) This indicates an error with Chainalysis's server.
503 Service unavailable error (Rare.) Chainalysis's server may be unavailable or not ready to handle the request.
504 Request timeout (Rare.) This indicates that our API gateway did not get a response from our application servers within the expected time.

Error response schema

The following is an example JSON response body from a 403 error:

{
    "message": "Missing Authentication Token"
}
Property Type Description
message String A human-readable string that provides further detail about the error.