Prerequisites
You need three things:
- Python 3.8 or newer.
- The
requestslibrary. - A free API Ninjas API key — issued instantly, no credit card. If you already have an account, it's on your profile page.
pip install requestsStep 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.
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.89The request on the wire and the full response:
{
"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:
from decimal import Decimal
price = Decimal(data['price']) # exact: Decimal('67234.89000000')
as_float = float(data['price']) # fine for display: 67234.89Use 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:
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:
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:
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 limitsOne 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):
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.