DEV Community

Paarthurnax
Paarthurnax

Posted on

CoinGecko API Tutorial for Beginners: Build Your First Crypto Data Feed

If you've ever wanted to pull live crypto prices into a Python script — without paying for an expensive data subscription — the CoinGecko API is your best starting point. It's free, well-documented, and doesn't require an API key for basic usage. In this tutorial, we'll go from zero to a working crypto data feed in about 30 minutes.

Prerequisites

Before we start, make sure you have:

  • Python 3.8 or higher installed
  • Basic Python knowledge (lists, loops, print statements)
  • An internet connection

That's it. No account required. No credit card. Just Python.

Why CoinGecko?

There are several crypto data providers out there — CryptoCompare, Messari, Binance's own API — but CoinGecko stands out for beginners because:

  1. No API key needed for most endpoints (free tier is generous)
  2. Massive coverage — 10,000+ coins tracked
  3. Clean, consistent JSON responses that are easy to parse
  4. Rate limits are reasonable — 10-30 calls/minute on the free tier

The only downside: real-time tick data isn't available for free. But for market scanning, portfolio tracking, and learning, it's more than enough.

Step 1: Your First API Request

Let's start simple. Open a Python file and fetch the current BTC price:

import urllib.request
import json

def get_price(coin_id: str, vs_currency: str = "usd") -> float:
    """Fetch the current price of a coin from CoinGecko."""
    url = (
        f"https://api.coingecko.com/api/v3/simple/price"
        f"?ids={coin_id}&vs_currencies={vs_currency}"
    )

    with urllib.request.urlopen(url, timeout=10) as response:
        data = json.loads(response.read().decode("utf-8"))

    return data[coin_id][vs_currency]

# Test it
btc_price = get_price("bitcoin")
eth_price = get_price("ethereum")

print(f"BTC: ${btc_price:,.2f}")
print(f"ETH: ${eth_price:,.2f}")
Enter fullscreen mode Exit fullscreen mode

Run it and you should see something like:

BTC: $67,423.00
ETH: $3,241.50
Enter fullscreen mode Exit fullscreen mode

Step 2: Fetching Multiple Coins at Once

Instead of making one request per coin (which wastes your rate limit), batch them:

def get_prices(coin_ids: list, vs_currency: str = "usd") -> dict:
    """Fetch prices for multiple coins in a single request."""
    ids_param = ",".join(coin_ids)
    url = (
        f"https://api.coingecko.com/api/v3/simple/price"
        f"?ids={ids_param}&vs_currencies={vs_currency}"
        f"&include_24hr_change=true&include_market_cap=true"
    )

    with urllib.request.urlopen(url, timeout=15) as response:
        return json.loads(response.read().decode("utf-8"))

# Your watchlist
WATCHLIST = ["bitcoin", "ethereum", "solana", "chainlink", "cardano"]

prices = get_prices(WATCHLIST)

print(f"\n{'Coin':<12} {'Price':>12} {'24h Change':>12}")
print("-" * 40)
for coin_id, data in prices.items():
    price = data.get("usd", 0)
    change = data.get("usd_24h_change", 0)
    arrow = "" if change > 0 else ""
    print(f"{coin_id:<12} ${price:>11,.2f} {arrow}{abs(change):>9.2f}%")
Enter fullscreen mode Exit fullscreen mode

Output:

Coin             Price   24h Change
----------------------------------------
bitcoin      $67,423.00       ↑2.34%
ethereum      $3,241.50       ↑1.87%
solana          $147.20       ↓0.45%
chainlink        $13.87       ↑4.12%
cardano           $0.42       ↓1.23%
Enter fullscreen mode Exit fullscreen mode

Step 3: Building a Live Data Feed

Now let's make it continuously poll for price updates:

import time
import os
from datetime import datetime

def clear_screen():
    os.system("cls" if os.name == "nt" else "clear")

def run_feed(watchlist: list, interval: int = 60):
    """
    Live crypto price feed that refreshes every `interval` seconds.
    Press Ctrl+C to stop.
    """
    print(f"Starting crypto feed for: {', '.join(watchlist)}")
    print(f"Refreshing every {interval} seconds. Press Ctrl+C to stop.\n")

    while True:
        try:
            prices = get_prices(watchlist)
            clear_screen()

            now = datetime.now().strftime("%H:%M:%S")
            print(f"Crypto Prices — Last updated: {now}")
            print("=" * 50)
            print(f"{'Coin':<12} {'Price':>12} {'24h':>10} {'Mkt Cap':>16}")
            print("-" * 50)

            for coin_id, data in prices.items():
                price = data.get("usd", 0)
                change = data.get("usd_24h_change", 0)
                mcap = data.get("usd_market_cap", 0)
                arrow = "+" if change >= 0 else ""
                mcap_str = f"${mcap/1e9:.1f}B" if mcap > 1e9 else f"${mcap/1e6:.1f}M"

                print(
                    f"{coin_id:<12} "
                    f"${price:>11,.2f} "
                    f"{arrow}{change:>8.2f}% "
                    f"{mcap_str:>16}"
                )

            print("=" * 50)
            time.sleep(interval)

        except KeyboardInterrupt:
            print("\nFeed stopped.")
            break
        except Exception as e:
            print(f"Error: {e}. Retrying in {interval}s...")
            time.sleep(interval)

# Run it
WATCHLIST = ["bitcoin", "ethereum", "solana", "chainlink", "cardano"]
run_feed(WATCHLIST, interval=60)
Enter fullscreen mode Exit fullscreen mode

Step 4: Working with Historical Data

Want to analyze trends or backtest a strategy? CoinGecko provides OHLCV (Open, High, Low, Close, Volume) data:

def get_ohlcv(coin_id: str, vs_currency: str = "usd", days: int = 30) -> list:
    """
    Fetch OHLCV data for a coin.

    Args:
        coin_id: CoinGecko coin ID (e.g., "bitcoin")
        vs_currency: Quote currency (e.g., "usd")
        days: Number of days of history (1, 7, 14, 30, 90, 180, 365)

    Returns:
        List of [timestamp, open, high, low, close] lists
    """
    url = (
        f"https://api.coingecko.com/api/v3/coins/{coin_id}/ohlc"
        f"?vs_currency={vs_currency}&days={days}"
    )

    with urllib.request.urlopen(url, timeout=15) as response:
        data = json.loads(response.read().decode("utf-8"))

    return data

# Fetch 30 days of BTC OHLCV
ohlcv = get_ohlcv("bitcoin", days=30)

print(f"Fetched {len(ohlcv)} candles")
print("\nLast 5 candles:")
print(f"{'Date':<20} {'Open':>10} {'High':>10} {'Low':>10} {'Close':>10}")
print("-" * 62)

for candle in ohlcv[-5:]:
    ts, open_, high, low, close = candle
    date = datetime.fromtimestamp(ts/1000).strftime("%Y-%m-%d %H:%M")
    print(f"{date:<20} ${open_:>9,.0f} ${high:>9,.0f} ${low:>9,.0f} ${close:>9,.0f}")
Enter fullscreen mode Exit fullscreen mode

Step 5: Smart Rate Limit Handling

CoinGecko's free tier allows about 10-30 requests per minute. Here's a simple rate limiter:

import time
from collections import deque

class RateLimiter:
    """Simple token bucket rate limiter."""

    def __init__(self, calls_per_minute: int = 10):
        self.calls_per_minute = calls_per_minute
        self.min_interval = 60.0 / calls_per_minute
        self.call_times = deque()

    def wait_if_needed(self):
        """Block until it's safe to make another API call."""
        now = time.time()

        # Remove calls older than 1 minute
        while self.call_times and now - self.call_times[0] > 60:
            self.call_times.popleft()

        # If at limit, wait
        if len(self.call_times) >= self.calls_per_minute:
            sleep_time = 60 - (now - self.call_times[0])
            if sleep_time > 0:
                time.sleep(sleep_time)

        self.call_times.append(time.time())

# Usage
limiter = RateLimiter(calls_per_minute=8)  # Stay under the limit

for coin in ["bitcoin", "ethereum", "solana"]:
    limiter.wait_if_needed()
    price = get_price(coin)
    print(f"{coin}: ${price:,.2f}")
Enter fullscreen mode Exit fullscreen mode

Step 6: Saving Data to CSV

Once you have data flowing, save it for later analysis:

import csv
from pathlib import Path

def save_to_csv(data: dict, filepath: str = "crypto_prices.csv"):
    """Append current price data to a CSV file."""
    path = Path(filepath)
    file_exists = path.exists()

    now = datetime.now().isoformat()

    with open(filepath, "a", newline="", encoding="utf-8") as f:
        fieldnames = ["timestamp", "coin", "price_usd", "change_24h", "market_cap_usd"]
        writer = csv.DictWriter(f, fieldnames=fieldnames)

        if not file_exists:
            writer.writeheader()

        for coin_id, coin_data in data.items():
            writer.writerow({
                "timestamp": now,
                "coin": coin_id,
                "price_usd": coin_data.get("usd", 0),
                "change_24h": coin_data.get("usd_24h_change", 0),
                "market_cap_usd": coin_data.get("usd_market_cap", 0),
            })

    print(f"Saved {len(data)} coins to {filepath}")

# Use it
prices = get_prices(["bitcoin", "ethereum", "solana"])
save_to_csv(prices)
Enter fullscreen mode Exit fullscreen mode

Step 7: Next Steps — Automate with OpenClaw

You now have a working crypto data feed. Here's where it gets interesting: you can turn this into a fully automated analysis agent using OpenClaw.

OpenClaw lets you run this kind of script as a local AI agent that:

  • Monitors markets 24/7 without you being at the keyboard
  • Detects patterns and sends you alerts
  • Paper-trades automatically to test strategies safely
  • Runs entirely on your own machine — no cloud, no subscription fees

The complete setup guide is available here: OpenClaw Home AI Agent Guide

Key Takeaways

  • CoinGecko API is free for most use cases — no account needed
  • Batch your requests — use comma-separated IDs to fetch multiple coins in one call
  • Respect rate limits — 10 requests/minute is safe on the free tier
  • OHLCV data is available for backtesting strategies
  • Save to CSV to build your own historical dataset
  • Automate it — run as a scheduled task or continuous loop for passive monitoring

The full code from this tutorial is available on request. Happy building!

Top comments (0)