IMPORTANT! API Key system is not yet implemented. You do NOT need to provide an API key to use the API at this time. Please keep an eye out on https://t.me/honeypotis_news for updates.
Honeypot Checks
Honeypot checks is the core part of Honeypot.is, the very reason that this project exists. On this page we'll dive into the IsHoneypot endpoint and it's detailed response.
Check a token
This endpoint allows you to retrieve Honeypot details for a token. Please continue reading below for explanation of the response. The sample response includes fake data to showcase potential responses.
Required attributes
- Name
address
- Type
- address
- Description
The address of the token you want to check. Also supports the pair/pool address.
Optional attributes
- Name
chainID
- Type
- integer
- Description
The chain you want to check the token on. If not specified, it will try to find the most suitable chain based on liquidity.
- Name
pair
- Type
- address
- Description
The pair address you want to check with. If not specified, it will try to find the most suitable pair based on liquidity..
- Name
simulateLiquidity
- Type
- bool
- Description
If set to true, the endpoint will try to simulate liquidity for the token IF no pair exists. If there is a pair for the token, it will use the pair instead of simulating. To force simulate liquidity, look at
forceSimulateLiquidity
.NOTE: Requires
chainID
.
- Name
forceSimulateLiquidity
- Type
- bool
- Description
If set to true, the endpoint will try to simulate liquidity for the token. This is useful when you want to check a token that is not yet listed on any DEX.
NOTE: Requires
chainID
.
Request
curl -G https://api.honeypot.is/v2/IsHoneypot \
-H "X-API-KEY: {APIKEY}" \
-d address=0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
Response
{
"token": {
"name": "USD Coin",
"symbol": "USDC",
"decimals": 6,
"address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"totalHolders": 1755847
},
"withToken": {
"name": "Ether",
"symbol": "ETH",
"decimals": 18,
"address": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
"totalHolders": 671397
},
"summary": {
"risk": "very_low",
"riskLevel": 0,
},
"simulationSuccess": true,
// "simulationError": "Insufficient liquidity for this trade."
"honeypotResult": {
"isHoneypot": false
// "honeypotReason": "PancakeSwap: TRANSFER_FROM_FAILED"
},
"simulationResult": {
// USDC doesn't actually have maxBuy and maxSell, but this is just an example.
"maxBuy": {
"token": 500000,
"tokenWei": "500000000000000",
"withToken": 9.62705611028878,
"withTokenWei": "9627056110288779597"
},
"maxSell": {
"token": 500000,
"tokenWei": "500000000000000",
"withToken": 9.62705611028878,
"withTokenWei": "9627056110288779597"
},
"buyTax": 0,
"sellTax": 0,
"transferTax": 0,
"buyGas": "154591",
"sellGas": "107886"
},
"holderAnalysis": {
// NOTE: This is NOT the number of holders for the token.
// This is only how many holders we are analyzing.
// Look at the "token" section for the actual number of holders.
"holders": "2",
"successful": "2",
"failed": "0",
"siphoned": "0",
"averageTax": 0,
"averageGas": 134250.5,
"highestTax": 0,
"highTaxWallets": "0",
"taxDistribution": [
{
"tax": 0,
"count": 2
}
]
},
"flags": [],
"contractCode": {
"openSource": true,
"rootOpenSource": true,
"isProxy": true,
"hasProxyCalls": true
},
"chain": {
"id": "1",
"name": "Ethereum",
"shortName": "ETH",
"currency": "ETH"
},
"router": "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D",
"pair": {
"pair": {
"name": "Uniswap V2: USDC-WETH",
"address": "0xB4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc",
"token0": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"token1": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
// Type will be either "UniswapV2" or "UniswapV3", even on Pancakeswap.
"type": "UniswapV2",
},
"chainId": "1",
"reserves0": "37345754334572",
"reserves1": "18943616626757258383905",
"liquidity": 74766200.17781314, // USD Value.
"router": "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D",
"createdAtTimestamp": "1620250931",
"creationTxHash": "0x125e0b641d4a4b08806bf52c0c6757648c9963bcda8681e4f996f09e00d4c2cc"
},
"pairAddress": "0xB4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc"
}
Summary
The summary
object contains a brief summary of the results, it is an easy way to quickly parse the response. Most of the summary is derived from other data in the response. The summary
object is guaranteed to be present. riskLevel
is not present if risk
is unknown
.
flags
is an array (may be empty/not present) of flags. List of flags and their descriptions can be found in Summary Flags section. Flags can be warnings or purely informational.
The risk
field is the risk level of the token. It is always present.
The risk will be one of: unknown
, very_low
, low
, medium
, high
, very_high
, honeypot
.
NOTE: The summary is still new. If you see any inconsistencies or have suggestions, please let us know. We will be expanding what risk level is influenced by.
It is recommended to use riskLevel
field instead of the risk
field for programmatic use, as we may expand amount of risks in the future.
- Name
unknown
- Type
- Description
The risk level of the token is unknown.
riskLevel
is not present.
- Name
very_low
- Type
- Description
The token is very low risk. Only whitelisted tokens can get this rating, such as WETH, USDC, USDT etc...
riskLevel
is 0.
- Name
low
- Type
- Description
The token is low risk. Honeypot didn't find anything suspicious about the token.
riskLevel
is between 1 and 19 (inclusive).NOTE: In the future, additional requirements may be added, such as liquidity burned/locked, or a certain amount of time since launch.
- Name
medium
- Type
- Description
The token is medium risk. There's some potential issues. Caution is advised.
riskLevel
is between 20 and 59 (inclusive).
- Name
high
- Type
- Description
The token is high risk. There are some issues that need to be considered. Caution is advised.
riskLevel
is between 60 and 79 (inclusive).
- Name
very_high
- Type
- Description
The token is very high risk. It is likely a honeypot, but not certain yet.
riskLevel
is between 80 and 89 (inclusive).
- Name
honeypot
- Type
- Description
The token is almost certainly a honeypot.
riskLevel
is between 90 and 100 (inclusive).
Summaries
"summary": {
"risk": "honeypot",
"riskLevel": 100,
"flags": [
{
"flag": "high_fail_rate",
"description": "Transfers between normal wallets are blockedA very high amount of users can not sell their tokens.",
"severity": "critical",
"severityIndex": 20
},
{
"flag": "CLOSED_SOURCE",
"description": "The source code is not available, allowing for hidden functionality.",
"severity": "high",
"severityIndex": 16
}
]
}
Simulation Success
The simulationSuccess
object is a bool that indicates whether the simulation was successful. If it is false, the simulationError
object will contain the error message.
If this is true, the honeypotResult
and simulationResult
objects will be present. However honeypotResult
can still be present if the simulation was not successful, if there's enough data to determine the honeypot status of the token from other sources such as holder analysis.
Response
{
// ...
"simulationSuccess": true,
// ...
}
Honeypot Result
The honeypotResult
object contains the honeypot status of the token. This field is not guaranteed to be present, for example in cases where we were unable to check the status of the token. if honeypotResult.isHoneypot
is true, the honeypotResult.honeypotReason
object will contain the reason why it is a honeypot.
Response
{
// ...
"honeypotResult": {
"isHoneypot": true,
"honeypotReason": "Insufficient liquidity"
},
// ...
}
Simulation Result
The simulationResult
object contains the simulation result of the token. This field is not guaranteed to be present, for example if the token is a honeypot or the simulation failed.
The maxBuy
and maxSell
objects are not guaranteed to be present. They will only be present if we detected them. If the token has unlimited max buy or sell, the fields will not be present.
The token
and tokenWei
refer to the token that is being scanned/tested.
The withToken
and withTokenWei
refer to the other token in the pair that is being used to buy the token.
The token
and withToken
are converted based on the decimals
of the token. The tokenWei
and withTokenWei
are the raw values.
Response
{
"simulationResult": {
"maxBuy": {
"token": 500000,
"tokenWei": "500000000000000",
"withToken": 9.62705611028878,
"withTokenWei": "9627056110288779597"
},
"maxSell": {
"token": 500000,
"tokenWei": "500000000000000",
"withToken": 9.62705611028878,
"withTokenWei": "9627056110288779597"
},
"buyTax": 0,
"sellTax": 0,
"transferTax": 0,
"buyGas": "154591",
"sellGas": "107886"
},
}
Holder Analysis
The holderAnalysis
object contains the analysis of the holders of the token. This field is not guaranteed to be present.
The holders
field is the amount of holders that we have analyzed, and NOT the number of actual holders for the token.
The successful
field is the amount of holders that can sell their holdings.
The failed
field is the amount of holders that cannot sell their holdings.
The siphoned
field is the amount of holders that have been siphoned - their tokens have been transferred without their consent. In some very rare cases, legit transfers are marked as siphoned - we are working on reducing the false positives.
The averageTax
field is the average tax that the holders have to pay when they sell their holdings.
The averageGas
field is the average gas that the holders have to pay when they sell their holdings.
The highestTax
field is the highest tax that a holder would have to pay.
The highTaxWallets
field is the amount of wallets that have to pay >=50% tax.
The taxDistribution
field is an array of objects that contains the tax percentage, rounded to a whole number, and how many wallets have to pay that percentage.
Response
"holderAnalysis": {
"holders": "2", // This is NOT the number of holders for the token.
"successful": "2",
"failed": "0",
"siphoned": "0",
"averageTax": 0,
"averageGas": 134250.5,
"highestTax": 0,
"highTaxWallets": "0",
"taxDistribution": [
{
"tax": 0,
"count": 2
}
]
},
Flags
The flags
is an array of string objects, it contains warnings about the token that we have picked up.
It's recommended to use the summary
/flags
instead. This object is deprecated, but will still be present for backwards compatibility.
Response
{
"flags": ["TRANSFER_BLOCKED", "EXTREMELY_HIGH_TAXES"],
}
Contract Code
The contractCode
object contains information about the contract code of the token. Not guaranteed to be present.
Currently, it only contains information if it's open source and if it's a proxy contract.
Note, the results from here are cached and may be outdated. Look at Contract Verification
endpoints if you want more up-to-date information.
- Name
openSource
- Type
- Description
If the contract is open source. Unlike other detectors, it's not enough for the token itself to be open source. It requires every single contract called during the buy/sell process to be open source.
- Name
rootOpenSource
- Type
- Description
If the root contract is open source. This is the token contract that is being scanned.
- Name
isProxy
- Type
- Description
If the contract is a proxy contract - essentially if a
delegatecall
is executed from the token contract.
- Name
hasProxyCalls
- Type
- Description
If the contract has proxy calls. This differs from
isProxy
as this is set to true if there is ANYdelegatecall
in the execution path, not just from the contract.Example 1: TOKEN ->
DELEGATECALL
CONTRACT A =hasProxyCalls
is true,isProxy
is true.Example 2: TOKEN ->
CALL
CONTRACT A ->DELEGATECALL
CONTRACT B =hasProxyCalls
is true,isProxy
is false.
Response
{
// ...
"contractCode": {
"openSource": true,
"rootOpenSource": true,
"isProxy": true,
"hasProxyCalls": true
},
// ...
}