Alchemy API & Python: Build Crypto Trading Tools Fast
Learn how to use the Alchemy API with Python to query blockchain data, track wallet activity, and build real-time crypto trading tools from scratch.
Learn how to use the Alchemy API with Python to query blockchain data, track wallet activity, and build real-time crypto trading tools from scratch.
If you've tried scraping on-chain data yourself, you already know the pain — running your own node costs time and money, public RPC endpoints rate-limit you into oblivion, and half the data you need is buried three JSON levels deep. Alchemy solves all of that. It's a managed blockchain infrastructure provider that gives developers fast, reliable access to Ethereum, Polygon, Arbitrum, and other chains through a clean API — no node maintenance required. Pair it with Python and you've got a serious toolkit for building trading bots, portfolio trackers, alert systems, and DeFi analytics dashboards.
Alchemy sits between your code and the blockchain. Instead of syncing a full Ethereum node (which takes days and hundreds of gigabytes), you point your Web3 library at an Alchemy endpoint and get instant access to real-time and historical chain data. For traders and quant developers, this opens up some genuinely powerful use cases: tracking large wallet movements before a price move, monitoring smart contract events on Uniswap or Aave, checking token balances across chains, and subscribing to mempool transactions to catch large pending swaps before they confirm.
Unlike generic public nodes, Alchemy's Enhanced APIs go beyond standard JSON-RPC. They add endpoints like `alchemy_getTokenBalances`, `alchemy_getAssetTransfers`, and `alchemy_getNFTsForOwner` — things that would otherwise require complex event log filtering and multiple calls. The free tier gives you 300 million compute units per month, which is more than enough to get started and build a working prototype.
Start by creating a free account at alchemy.com, creating an app for the Ethereum mainnet, and copying your API key. Then install the dependencies — `web3.py` is the standard Python library for Ethereum interaction, and `requests` handles direct HTTP calls to Alchemy's Enhanced APIs.
pip install web3 requests python-dotenv
Store your API key in a `.env` file — never hardcode credentials in scripts you might push to GitHub.
import os
from web3 import Web3
from dotenv import load_dotenv
load_dotenv()
ALCHEMY_API_KEY = os.getenv("ALCHEMY_API_KEY")
ALCHEMY_URL = f"https://eth-mainnet.g.alchemy.com/v2/{ALCHEMY_API_KEY}"
# Connect via Web3
w3 = Web3(Web3.HTTPProvider(ALCHEMY_URL))
if w3.is_connected():
print(f"Connected. Latest block: {w3.eth.block_number}")
else:
raise ConnectionError("Failed to connect to Alchemy endpoint")
Always use environment variables for API keys. A leaked Alchemy key can be abused by others and consume your compute units. Add `.env` to your `.gitignore` immediately.
One of the most practical things you can do with Alchemy's Enhanced API is check all ERC-20 token holdings for any wallet address in a single request. If you're watching whale wallets — addresses known to move markets on Binance or Coinbase-listed tokens — this is how you see their current positions without manually checking each token contract.
import requests
import os
from dotenv import load_dotenv
load_dotenv()
ALCHEMY_API_KEY = os.getenv("ALCHEMY_API_KEY")
BASE_URL = f"https://eth-mainnet.g.alchemy.com/v2/{ALCHEMY_API_KEY}"
def get_token_balances(wallet_address: str) -> list:
"""Fetch all ERC-20 token balances for a wallet."""
payload = {
"jsonrpc": "2.0",
"method": "alchemy_getTokenBalances",
"params": [wallet_address, "erc20"],
"id": 1
}
try:
response = requests.post(BASE_URL, json=payload, timeout=10)
response.raise_for_status()
data = response.json()
balances = data.get("result", {}).get("tokenBalances", [])
# Filter out zero balances
return [
b for b in balances
if b["tokenBalance"] != "0x0000000000000000000000000000000000000000000000000000000000000000"
]
except requests.RequestException as e:
print(f"Request failed: {e}")
return []
except KeyError as e:
print(f"Unexpected response format: {e}")
return []
# Example: check a known whale wallet
wallet = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045" # vitalik.eth
balances = get_token_balances(wallet)
print(f"Found {len(balances)} token positions")
for token in balances[:5]:
print(f"Contract: {token['contractAddress']} | Balance (hex): {token['tokenBalance']}")
To track transfer history — useful for spotting accumulation patterns before tokens pump on exchanges like Bybit or OKX — use the `alchemy_getAssetTransfers` endpoint. This lets you retrieve both incoming and outgoing transfers for any address across a block range.
def get_asset_transfers(wallet_address: str, from_block: str = "0x0") -> list:
"""Get ERC-20 token transfer history for a wallet."""
payload = {
"jsonrpc": "2.0",
"method": "alchemy_getAssetTransfers",
"params": [{
"fromBlock": from_block,
"toBlock": "latest",
"toAddress": wallet_address,
"category": ["erc20"],
"withMetadata": True,
"excludeZeroValue": True,
"maxCount": "0x32" # 50 results
}],
"id": 1
}
try:
response = requests.post(BASE_URL, json=payload, timeout=15)
response.raise_for_status()
transfers = response.json().get("result", {}).get("transfers", [])
return transfers
except requests.RequestException as e:
print(f"Transfer fetch failed: {e}")
return []
transfers = get_asset_transfers(wallet)
for tx in transfers[:3]:
print(f"{tx['metadata']['blockTimestamp']} | {tx['asset']} | {tx['value']} | from {tx['from']}")
HTTP polling is fine for historical data, but for real-time signals you want WebSockets. Alchemy supports persistent WebSocket connections that push new data to your script the moment it happens — new blocks, pending transactions, specific contract events. This is how serious algo traders get sub-second reaction times before prices update on platforms like Binance or Bitget.
import asyncio
import json
import websockets
import os
from dotenv import load_dotenv
load_dotenv()
ALCHEMY_WS_URL = f"wss://eth-mainnet.g.alchemy.com/v2/{os.getenv('ALCHEMY_API_KEY')}"
# Uniswap V3 Swap event topic
SWAP_TOPIC = "0xc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67"
UNISWAP_V3_POOL = "0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640" # USDC/ETH 0.05%
async def monitor_swaps():
async with websockets.connect(ALCHEMY_WS_URL) as ws:
subscribe_msg = {
"jsonrpc": "2.0",
"method": "eth_subscribe",
"params": [
"logs",
{
"address": UNISWAP_V3_POOL,
"topics": [SWAP_TOPIC]
}
],
"id": 1
}
await ws.send(json.dumps(subscribe_msg))
ack = await ws.recv()
print(f"Subscribed: {ack}")
print("Listening for Uniswap USDC/ETH swaps...")
while True:
try:
msg = await asyncio.wait_for(ws.recv(), timeout=60)
data = json.loads(msg)
if "params" in data:
log = data["params"]["result"]
print(f"Block {int(log['blockNumber'], 16)} | Tx: {log['transactionHash']}")
except asyncio.TimeoutError:
print("No swap in last 60s — still connected")
except websockets.ConnectionClosed:
print("WebSocket closed, reconnect needed")
break
asyncio.run(monitor_swaps())
WebSocket connections can drop unexpectedly. In production, always wrap your listener in a reconnection loop with exponential backoff. Losing a connection silently is worse than crashing loudly.
On-chain data alone doesn't tell you when to buy or sell — but combined with price signals, it becomes genuinely powerful context. The pattern that works well: use Alchemy to detect a trigger (whale accumulation, large DEX swap, smart money wallet movement), then cross-reference with a signals platform like VoiceOfChain to see if the price action is already confirming the move. When both on-chain and price signals align, conviction goes up.
A practical example: you're monitoring a set of known smart money wallets. Alchemy detects that three of them bought LINK in the last two hours. You check VoiceOfChain and see a bullish signal already firing on the LINK/USDT pair. That's two independent data sources pointing the same direction — a much stronger setup than either one alone. You then look at order book depth on KuCoin or Gate.io to time the entry.
| Endpoint | Use Case | Type |
|---|---|---|
| alchemy_getTokenBalances | Wallet position snapshot | Enhanced API |
| alchemy_getAssetTransfers | Accumulation / distribution tracking | Enhanced API |
| eth_subscribe (logs) | Real-time contract events | WebSocket |
| eth_subscribe (newPendingTransactions) | Mempool monitoring | WebSocket |
| alchemy_getNFTsForOwner | NFT whale tracking | Enhanced API |
| eth_getBlockByNumber | Block-level data fetching | Standard RPC |
Alchemy plus Python is one of the cleanest stacks available for crypto developers who want real blockchain data without the infrastructure headache. You can query wallet positions, track token flows, subscribe to live contract events, and build alert systems that react faster than most traders can manually monitor — all within a few hundred lines of Python.
The real edge comes from combining what Alchemy sees on-chain with what's happening at the price level. A whale accumulating quietly on-chain while volume is still low on Binance or OKX is a very different signal than the same whale buying into a pump already in progress. On-chain data gives you the why; price data gives you the when. Stack both, keep your code clean, and you'll have a setup most retail traders simply don't have access to.