NewConnect Claude, Gemini, ChatGPT, and other AI agents to API Ninjas via our MCP server

How to Get Cryptocurrency Prices in Python

Crypto Price APIUpdated August 28, 2026
Create a free API key and it will be pre-filled into every code sample on this page. No credit card required.
Getting a cryptocurrency price in Python takes one GET request to the Crypto Price API with a trading-pair symbol like BTCUSDT. This guide walks through the request, the one quirk in the response (prices are strings), and the loop patterns for tracking several coins at once.

Prerequisites

You need three things:

  • Python 3.8 or newer.
  • The requests library.
  • A free API Ninjas API key — issued instantly, no credit card. If you already have an account, it's on your profile page.
shell
pip install requests

Step 1: Fetch your first price

The endpoint is /v1/cryptoprice and takes one parameter: symbol, the trading pair written without a separator — BTCUSDT for Bitcoin quoted in Tether, ETHBTC for Ether priced in Bitcoin.

crypto.py
import requests response = requests.get( 'https://api.api-ninjas.com/v1/cryptoprice', params={'symbol': 'BTCUSDT'}, headers={'X-Api-Key': 'YOUR_API_KEY'}, timeout=10, ) response.raise_for_status() data = response.json() print(f"BTC: ${float(data['price']):,.2f}") # BTC: $67,234.89

The request on the wire and the full response:

api.api-ninjas.com
GET/v1/cryptoprice?symbol=BTCUSDT
200 OKapplication/json
{ "symbol": "BTCUSDT", "price": "67234.89000000", "timestamp": 1717603200 }

Step 2: Read the response

Three fields: the symbol you asked for, the price, and a Unix timestamp of the quote. The one thing that trips people up is that price is a string — the API preserves the full exchange precision rather than rounding it through a float. Cast it deliberately:

precision.py
from decimal import Decimal price = Decimal(data['price']) # exact: Decimal('67234.89000000') as_float = float(data['price']) # fine for display: 67234.89

Use float() for display and charts; use Decimal anywhere the numbers feed accounting, so a satoshi never disappears to floating-point rounding.

Step 3: Harden the client

Two changes make the quick version production-ready: the key moves to an environment variable so it never lands in git, and a shared Session reuses the TLS connection so repeated calls stay fast:

crypto_client.py
import os import requests API_URL = 'https://api.api-ninjas.com/v1/cryptoprice' session = requests.Session() session.headers['X-Api-Key'] = os.environ.get('API_NINJAS_KEY', 'YOUR_API_KEY') def get_crypto_price(symbol: str) -> dict: """Return the latest ticker for one trading pair, e.g. BTCUSDT.""" response = session.get(API_URL, params={'symbol': symbol}, timeout=10) response.raise_for_status() return response.json() btc = get_crypto_price('BTCUSDT') print(f"BTC/USDT: ${float(btc['price']):,.2f}")

Run export API_NINJAS_KEY=your_key once and the script never needs editing. get_crypto_price() is the building block for the next step.

Step 4: Track multiple pairs

A portfolio view is a loop over symbols:

portfolio.py
symbols = ['BTCUSDT', 'ETHUSDT', 'SOLUSDT', 'DOGEUSDT', 'XRPUSDT'] for symbol in symbols: data = get_crypto_price(symbol) print(f"{symbol:10} ${float(data['price']):>12,.4f}")

For a simple live ticker, poll on a fixed interval:

ticker.py
import time while True: data = get_crypto_price('BTCUSDT') print(f"BTC: ${float(data['price']):,.2f}") time.sleep(60) # one poll per minute keeps you well inside rate limits

One request a minute is far inside the rate limits and plenty fresh for a dashboard. If you need tick-by-tick data, that's WebSocket territory — polling HTTP faster buys you 429s, not better data.

Step 5: Handle errors

Three failures cover almost everything: a malformed symbol (400), a missing key (401), and an over-eager polling loop (429):

errors.py
from requests.exceptions import HTTPError, RequestException try: data = get_crypto_price('BTCUSDT') except HTTPError as error: status = error.response.status_code if status == 400: print('Invalid symbol — check the trading-pair format (e.g. BTCUSDT)') elif status == 401: print('Missing or invalid API key') elif status == 429: print('Rate limit exceeded — slow the polling loop down') else: print(f'HTTP {status}: {error.response.text}') except RequestException as error: print(f'Network error: {error}')

Where to go from here

The Crypto Symbols API lists every supported trading pair, the Bitcoin API adds Bitcoin-specific stats, and for fiat pairs the Exchange Rate API uses the same request pattern. The complete script is below.

crypto_prices.py

The complete script from this guide: session reuse, ticker lookup, and a command-line symbol list.

Frequently asked questions

What symbol format does the API use?

Trading pairs without a separator — BTCUSDT for Bitcoin/Tether, ETHBTC for Ether/Bitcoin. The Crypto Symbols API lists every supported pair.

How frequently are crypto prices updated?

The API returns the most recent ticker price from major exchanges, updated continuously. The timestamp field tells you exactly when the quote was taken.

Why is the price returned as a string?

To preserve full precision. Cast to float for display, or use Decimal for financial calculations where rounding errors matter.

Can I get historical crypto prices?

This endpoint returns current prices. For Bitcoin specifically, the Bitcoin API provides additional data; for OHLCV candle history, use a dedicated exchange feed.

How often should I poll?

Once a minute is plenty for a price display and stays well inside free-tier rate limits. For sub-second trading data you want an exchange WebSocket, not HTTP polling.