A stable and reliable Python SDK for Dexscreener.com API with HTTP support:
- Single Query - Traditional one-time API calls
- Real-time Updates - Live price updates with configurable intervals
- ✅ Complete official API coverage
- ✅ Stable HTTP-based streaming
- ✅ Automatic rate limiting
- ✅ Browser impersonation for anti-bot bypass (using curl_cffi)
- ✅ Type-safe with Pydantic models
- ✅ Async/sync support
- ✅ Simple, focused interface
use uv (Recommended)
uv add dexscreenor pip
pip install dexscreenfrom dexscreen import DexscreenerClient
# Default client with 10-second timeout
client = DexscreenerClient()
# Custom timeout client
client = DexscreenerClient(client_kwargs={"timeout": 30})
# Get a specific pair by token address
pairs = client.get_pairs_by_token_address("solana", "JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN")
if pairs:
pair = pairs[0] # Get the first pair
print(f"{pair.base_token.symbol}: ${pair.price_usd}")
# Search for tokens
results = client.search_pairs("PEPE")
for pair in results[:5]:
print(f"{pair.base_token.symbol} on {pair.chain_id}: ${pair.price_usd}")
# Get token information
profiles = client.get_latest_token_profiles()
boosted = client.get_latest_boosted_tokens()import asyncio
from dexscreen import DexscreenerClient
async def handle_price_update(pair):
print(f"{pair.base_token.symbol}: ${pair.price_usd} ({pair.price_change.h24:+.2f}%)")
async def main():
client = DexscreenerClient()
# Subscribe to pair updates (default interval: 0.2 seconds)
await client.subscribe_pairs(
chain_id="solana",
pair_addresses=["JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN"],
callback=handle_price_update,
interval=0.2 # Poll 5 times per second (300/min)
)
# Let it run for 30 seconds
await asyncio.sleep(30)
await client.close_streams()
asyncio.run(main())from dexscreen import DexscreenerClient, FilterPresets
# Default filtering - only receive updates when data changes
await client.subscribe_pairs(
chain_id="solana",
pair_addresses=["JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN"],
callback=handle_price_update,
filter=True, # Default value
interval=0.2
)
# No filtering - receive all polling results
await client.subscribe_pairs(
chain_id="ethereum",
pair_addresses=["0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640"],
callback=handle_price_update,
filter=False, # Get all updates even if data hasn't changed
interval=1.0
)
# Advanced filtering - only significant price changes (1%)
await client.subscribe_pairs(
chain_id="ethereum",
pair_addresses=["0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640"],
callback=handle_price_update,
filter=FilterPresets.significant_price_changes(0.01)
)
# Rate limited updates - max 1 update per second
await client.subscribe_pairs(
chain_id="ethereum",
pair_addresses=["0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640"],
callback=handle_price_update,
filter=FilterPresets.rate_limited(1.0)
)from dexscreen import DexscreenerClient
async def monitor_arbitrage():
client = DexscreenerClient()
# Monitor same token on different chains
pairs = [
("ethereum", "0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640"), # USDC/WETH
("bsc", "0x7213a321F1855CF1779f42c0CD85d3D95291D34C"), # USDC/BUSD
("polygon", "0x45dDa9cb7c25131DF268515131f647d726f50608"), # USDC/WETH
]
prices = {}
async def track_price(pair):
key = f"{pair.chain_id}:{pair.base_token.symbol}"
prices[key] = float(pair.price_usd)
# Check for arbitrage opportunity
if len(prices) > 1:
min_price = min(prices.values())
max_price = max(prices.values())
spread = ((max_price - min_price) / min_price) * 100
if spread > 0.5: # 0.5% spread
print(f"ARBITRAGE: {spread:.2f}% spread detected!")
# Subscribe to all pairs
for chain, address in pairs:
await client.subscribe_pairs(
chain_id=chain,
pair_addresses=[address],
callback=track_price,
interval=0.5
)
await asyncio.sleep(60) # Monitor for 1 minuteasync def find_trending_tokens():
client = DexscreenerClient()
# Search for tokens
results = await client.search_pairs_async("SOL")
# Filter high volume pairs (>$1M daily volume)
high_volume = [
p for p in results
if p.volume.h24 and p.volume.h24 > 1_000_000
]
# Sort by volume
high_volume.sort(key=lambda x: x.volume.h24, reverse=True)
# Monitor top 5
for pair in high_volume[:5]:
print(f"{pair.base_token.symbol}: Vol ${pair.volume.h24/1e6:.2f}M")
await client.subscribe_pairs(
chain_id=pair.chain_id,
pair_addresses=[pair.pair_address],
callback=handle_price_update,
interval=2.0
)📖 Full Documentation - Complete API reference, guides, and examples.
client = DexscreenerClient(impersonate="chrome136")get_pairs_by_token_address(chain_id, token_address)- Get pairs for a tokensearch_pairs(query)- Search pairssubscribe_pairs(chain_id, pair_addresses, callback)- Real-time pair updatessubscribe_tokens(chain_id, token_addresses, callback)- Monitor all pairs of tokens
TokenPair- Main pair data modelTokenInfo- Token profile informationOrderInfo- Order information
The SDK automatically handles rate limiting:
- 60 requests/minute for token profile endpoints
- 300 requests/minute for pair data endpoints
The SDK provides flexible timeout configuration for different use cases:
# Default timeout is 10 seconds
client = DexscreenerClient()# Set custom timeout during initialization
client = DexscreenerClient(client_kwargs={"timeout": 30})
# Different timeouts for different scenarios
fast_client = DexscreenerClient(client_kwargs={"timeout": 5}) # Quick responses
stable_client = DexscreenerClient(client_kwargs={"timeout": 60}) # Stable connections# Update timeout at runtime
await client._client_300rpm.update_config({"timeout": 15})
# Multiple config updates including timeout
await client._client_300rpm.update_config({
"timeout": 25,
"impersonate": "chrome136"
})| Use Case | Timeout (seconds) | Description |
|---|---|---|
| Quick Trading | 5-10 | Fast response for time-sensitive operations |
| General Use | 10-15 | Default balanced setting |
| Stable Monitoring | 20-30 | Reliable for long-running subscriptions |
| Poor Networks | 30-60 | Handle unstable connections |
The SDK uses curl_cffi for browser impersonation to bypass anti-bot protection:
# Use different browser versions
client = DexscreenerClient(impersonate="chrome134")
client = DexscreenerClient(impersonate="safari180")
# Combine browser impersonation with custom timeout
client = DexscreenerClient(
impersonate="chrome136",
client_kwargs={"timeout": 20}
)Contributions are welcome! Please feel free to submit a Pull Request.
MIT License - see LICENSE file for details