Building a Crypto Trading Bot? Here Are 5 Free DeFi Data APIs That Actually Work
Let's be honest: most "free crypto APIs" articles are either outdated, filled with APIs that disappeared two years ago, or list services where "free" means "you get 3 requests per day."
I've spent the last year building and iterating on crypto trading tools, and I've tested dozens of APIs. These five are the ones I keep coming back to — they're actually free to start, they work reliably, and they return data you can use in a real trading bot.
If you're building a crypto trading bot API stack, this list will save you hours of trial and error.
What a Trading Bot Actually Needs
A DeFi trading bot typically needs: price feeds, yield/APY data, protocol metadata, TVL stats, and liquidity data. No single free API covers all of these perfectly, but the right combination gets you very close.
1. DeFi Data API (RapidAPI) — The Core Data Layer
This is the API I reach for first when building anything DeFi-related. It provides protocol data, yield information, chain statistics, and global DeFi metrics through a clean REST interface on RapidAPI.
For a trading bot, the key endpoints are /yields/top, /yields, /protocols/{slug}, /stats, and /chains.
Here's how to use it in a trading bot context:
import requests
import time
RAPIDAPI_KEY = "YOUR_RAPIDAPI_KEY"
BASE_URL = "https://defi-api-425658670453.europe-west1.run.app"
HEADERS = {
"X-RapidAPI-Key": RAPIDAPI_KEY,
"X-RapidAPI-Host": "defi-data-api"
}
def fetch_top_yields():
"""Fetch current top yield opportunities."""
response = requests.get(f"{BASE_URL}/yields/top", headers=HEADERS)
response.raise_for_status()
return response.json()
def fetch_protocol_details(slug):
"""Get detailed info about a specific protocol."""
response = requests.get(f"{BASE_URL}/protocols/{slug}", headers=HEADERS)
response.raise_for_status()
return response.json()
def find_safe_yields(min_tvl=10_000_000, max_apy=30):
"""
Find yield pools that meet safety criteria.
Filters for high TVL and reasonable APY to avoid risky pools.
"""
all_yields = requests.get(f"{BASE_URL}/yields", headers=HEADERS).json()
safe_pools = [
pool for pool in all_yields
if pool.get("tvlUsd", 0) >= min_tvl
and 0 < pool.get("apy", 0) <= max_apy
]
safe_pools.sort(key=lambda x: x.get("apy", 0), reverse=True)
return safe_pools
# Example: Find the best safe stablecoin yields
pools = find_safe_yields(min_tvl=5_000_000, max_apy=25)
stablecoin_keywords = ["USDC", "USDT", "DAI", "FRAX", "LUSD", "USDD"]
stable_pools = [
p for p in pools
if any(keyword in p.get("symbol", "").upper() for keyword in stablecoin_keywords)
]
print("🛡️ Safe Stablecoin Yield Opportunities:")
for pool in stable_pools[:10]:
print(f" {pool['symbol']}: {pool['apy']:.2f}% APY | ${pool['tvlUsd']:,.0f} TVL | {pool.get('chain')}")
This pattern — filtering yields by safety criteria — is the foundation of any yield-optimizing trading strategy. The DeFi data API free tier on RapidAPI handles this beautifully.
You can find it by searching "DeFi Data API" on RapidAPI.
2. CoinGecko API — Price Feeds
Every trading bot needs price data, and CoinGecko's free API is the most accessible source. It covers 10,000+ tokens with price, volume, and market cap data.
import requests
def get_prices(token_ids):
"""Fetch current prices for a list of tokens."""
response = requests.get(
"https://api.coingecko.com/api/v3/simple/price",
params={
"ids": ",".join(token_ids),
"vs_currencies": "usd",
"include_24hr_change": "true",
"include_24hr_vol": "true"
}
)
return response.json()
# Usage
prices = get_prices(["ethereum", "uniswap", "aave", "chainlink"])
for token, data in prices.items():
price = data["usd"]
change_24h = data.get("usd_24h_change", 0)
print(f"{token}: ${price:,.2f} ({change_24h:+.2f}%)")
Tip for trading bots: CoinGecko's free tier allows 10-30 requests per minute. For more frequent polling, cache responses and only update every 30-60 seconds.
3. DeFiLlama API — TVL and Protocol Tracking
DeFiLlama remains essential for TVL data. For a trading bot, tracking TVL changes is a valuable signal — capital flowing into a protocol often precedes yield changes.
import requests
def get_protocol_tvl(protocol_slug):
"""Fetch current TVL for a protocol."""
response = requests.get(f"https://api.llama.fi/tvl/{protocol_slug}")
return response.json()
def get_tvl_history(protocol_slug):
"""Fetch historical TVL for backtesting."""
response = requests.get(f"https://api.llama.fi/protocol/{protocol_slug}")
data = response.json()
return data.get("tvl", [])
# Usage: Track TVL changes for top protocols
protocols = ["aave", "uniswap", "lido", "curve", "makerdao"]
for slug in protocols:
tvl = get_protocol_tvl(slug)
print(f"{slug}: ${tvl:,.0f} TVL")
For a blockchain API trading strategy, TVL changes are one of the strongest leading indicators of yield shifts.
4. The Graph — On-Chain Data
When your trading bot needs real-time on-chain data (liquidity pool states, lending rates, vault performance), The Graph is the way to go. Each major protocol has its own subgraph with GraphQL access.
import requests
def get_uniswap_top_pools():
"""Fetch top Uniswap V3 pools by TVL."""
query = """
{
pools(orderBy: totalValueLockedUSD, orderDirection: desc, first: 10) {
id
token0 { symbol }
token1 { symbol }
feeTier
totalValueLockedUSD
volumeUSD
}
}
"""
response = requests.post(
"https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v3",
json={"query": query}
)
return response.json()["data"]["pools"]
pools = get_uniswap_top_pools()
for pool in pools:
pair = f"{pool['token0']['symbol']}/{pool['token1']['symbol']}"
tvl = float(pool["totalValueLockedUSD"])
fee = int(pool["feeTier"]) / 10000
print(f"{pair} ({fee}% fee): ${tvl:,.0f} TVL")
This is especially valuable for arbitrage bots that need to monitor liquidity across DEX pools in real time.
5. 1inch API — Swap Execution
When your bot is ready to actually execute trades, the 1inch API provides swap quotes and transaction data across multiple DEXs. It aggregates liquidity to find the best execution price.
import requests
def get_swap_quote(chain_id, from_token, to_token, amount):
"""Get the best swap quote across DEXs."""
response = requests.get(
f"https://api.1inch.dev/swap/v6.0/{chain_id}/quote",
params={
"src": from_token,
"dst": to_token,
"amount": amount
},
headers={"Authorization": "Bearer YOUR_1INCH_KEY"}
)
return response.json()
# Quote: Swap 1 ETH to USDC on Ethereum (chain_id = 1)
ETH = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"
USDC = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
quote = get_swap_quote(1, ETH, USDC, "1000000000000000000")
dst_amount = int(quote["dstAmount"]) / 1e6
print(f"1 ETH → {dst_amount:.2f} USDC")
print(f"Estimated gas: {quote.get('gas', 0)}")
How to Combine These APIs Into a Working Bot
Here's a practical data provider class for a yield-optimizing bot using the DeFi Data API as the core:
import requests
RAPIDAPI_KEY = "YOUR_RAPIDAPI_KEY"
DEFI_BASE = "https://defi-api-425658670453.europe-west1.run.app"
DEFI_HEADERS = {
"X-RapidAPI-Key": RAPIDAPI_KEY,
"X-RapidAPI-Host": "defi-data-api"
}
class DeFiDataProvider:
"""Centralized data provider using the DeFi Data API."""
def __init__(self):
self.session = requests.Session()
self.session.headers.update(DEFI_HEADERS)
def get_top_yield_opportunities(self, chain=None, min_tvl=1_000_000):
"""Find best yield opportunities, optionally filtered by chain."""
response = self.session.get(f"{DEFI_BASE}/yields/top")
pools = response.json()
filtered = [
p for p in pools
if p.get("tvlUsd", 0) >= min_tvl
and (chain is None or p.get("chain") == chain)
]
return sorted(filtered, key=lambda x: x.get("apy", 0), reverse=True)
def get_protocol_overview(self, slug):
"""Get full protocol metadata."""
response = self.session.get(f"{DEFI_BASE}/protocols/{slug}")
return response.json()
def get_chain_rankings(self):
"""Get chains ranked by TVL."""
response = self.session.get(f"{DEFI_BASE}/chains")
chains = response.json()
return sorted(chains, key=lambda x: x.get("tvl", 0), reverse=True)
# Scan for cross-chain yield discrepancies
provider = DeFiDataProvider()
pools = provider.get_top_yield_opportunities(min_tvl=5_000_000)
# Group by token symbol to find yield spreads across chains
from collections import defaultdict
by_symbol = defaultdict(list)
for pool in pools:
by_symbol[pool.get("symbol", "").upper()].append(pool)
for symbol, pool_list in list(by_symbol.items())[:5]:
apys = [p.get("apy", 0) for p in pool_list if p.get("apy", 0) > 0]
if len(apys) >= 2:
spread = max(apys) - min(apys)
if spread > 2.0:
print(f"📊 {symbol}: {spread:.2f}% spread across chains")
for p in pool_list:
print(f" {p.get('chain')}: {p.get('apy', 0):.2f}% on {p.get('protocol')}")
This pattern scans for yield discrepancies — when the same token earns different yields on different chains, there may be an opportunity to move capital for better returns.
Key Takeaways
Building a crypto trading bot with free APIs is absolutely doable in 2026. Here's the stack I recommend:
- DeFi Data API — Core data layer for yields, protocols, chains, and stats
- CoinGecko — Price feeds and market context
- DeFiLlama — TVL tracking and historical data
- The Graph — Real-time on-chain data
- 1inch — Swap execution when you're ready to trade
The DeFi Data API on RapidAPI is particularly well-suited as your primary data source. Its /yields/top endpoint gives you a ranked list of the best yield opportunities in a single call, and the protocol and chain endpoints provide all the context you need to make informed decisions.
Pro tip on rate limiting: When combining multiple free APIs, cache responses locally and space out your requests. A simple time.sleep() between calls goes a long way toward staying within free tier limits.
You can explore the DeFi Data API on RapidAPI — just search for "DeFi Data API." The free tier is perfect for building and testing your bot before you scale up.
Got questions about building DeFi trading bots? Drop a comment below — I'm happy to share more from my experience. Happy trading! 🤖📊
Follow me for more articles on crypto trading automation, DeFi development, and API deep-dives.
Top comments (0)