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

How to Get Stock Price in Python

Stock 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 stock price in Python takes one GET request to the Stock Price API — no SDK, no OAuth, just the requests library and an API key. This guide walks through it in six steps: make the first request, understand the response, harden the code for real use, track a whole watchlist, pull price history, and handle failures. At the end you can download the finished script.

Prerequisites

You need three things:

  • Python 3.8 or newer.
  • Two libraries: requests for HTTP and pandas for the watchlist step.
  • A free API Ninjas API key. Signing up takes a minute and needs no credit card; if you already have an account, the key is on your profile page.
shell
pip install requests pandas

The API authenticates every request with an X-Api-Key header — you'll see it in each example below.

Step 1: Make your first request

The endpoint is /v1/stockprice and it takes a single query parameter, ticker. Request a quote for Apple:

stock.py
import requests response = requests.get( 'https://api.api-ninjas.com/v1/stockprice', params={'ticker': 'AAPL'}, headers={'X-Api-Key': 'YOUR_API_KEY'}, timeout=10, ) response.raise_for_status() quote = response.json() print(f"{quote['ticker']}: ${quote['price']}") # AAPL: $192.42

Here is the same request on the wire, with the full JSON the API returns:

api.api-ninjas.com
GET/v1/stockprice?ticker=AAPL
200 OKapplication/json
{ "ticker": "AAPL", "name": "Apple Inc.", "price": 192.42, "exchange": "NASDAQ", "updated": 1706302801, "currency": "USD", "volume": 44594000 }

The same endpoint also quotes market indexes — pass ^DJI as the ticker and you get the Dow Jones Industrial Average. That's a complete, working integration. The next step is understanding what came back.

Step 2: Read the response

The response is a flat JSON object. Four fields arrive on every plan:

FieldTypeMeaning
tickerstringThe symbol you requested, echoed back.
pricenumberThe latest price, in the listing exchange's currency.
updatednumberUnix timestamp of when the quote was taken.
volumenumberShares traded in the current session.

Three more — name, exchange, and currency — appear on premium plans, which is why the sample response above shows seven fields.

Pay attention to updated. Free keys return quotes delayed up to 15 minutes, while premium keys return live prices; the timestamp tells you exactly what you got. Code that reads the timestamp instead of assuming freshness behaves correctly on both plans.

Step 3: Harden the client

The Step 1 code is fine for a one-off script, but it has three weaknesses you'll hit as soon as it runs regularly. The API key is hard-coded, so it eventually gets committed to git. Each call opens a fresh TLS connection, which is slow across many tickers. And the first 429 Too Many Requests crashes the run. The fix for all three fits in twenty lines:

stock_client.py
import os import time import requests API_URL = 'https://api.api-ninjas.com/v1/stockprice' session = requests.Session() session.headers['X-Api-Key'] = os.environ.get('API_NINJAS_KEY', 'YOUR_API_KEY') def get_quote(ticker: str, retries: int = 3) -> dict: """Return the latest quote for one ticker, retrying rate limits.""" for attempt in range(retries): response = session.get(API_URL, params={'ticker': ticker}, timeout=10) if response.status_code == 429: time.sleep(int(response.headers.get('Retry-After', 2 ** attempt))) continue response.raise_for_status() return response.json() raise RuntimeError(f'Still rate-limited after {retries} attempts: {ticker}') print(get_quote('AAPL')['price'])

Three changes, one per weakness. The key now comes from an environment variable — run export API_NINJAS_KEY=your_key once and the code never contains a secret. A shared requests.Session reuses the same connection for every call. And when the API answers 429, the client waits — using the server's Retry-After header if present, otherwise backing off 1, 2, then 4 seconds — and tries again.

The get_quote() function is the foundation for everything that follows.

Step 4: Track a watchlist

With get_quote() defined, fetching a whole watchlist is a list comprehension. Loading the results into a pandas DataFrame gives you sorting, math, and CSV export for free:

watchlist.py
import pandas as pd watchlist = ['AAPL', 'MSFT', 'GOOGL', 'AMZN', 'NVDA'] df = pd.DataFrame([get_quote(t) for t in watchlist]) df['updated'] = pd.to_datetime(df['updated'], unit='s', utc=True) print(df[['ticker', 'price', 'updated']].to_string(index=False)) df.to_csv('watchlist.csv', index=False)
output
ticker price updated AAPL 192.42 2024-01-26 21:00:01+00:00 MSFT 404.87 2024-01-26 21:00:01+00:00 GOOGL 153.79 2024-01-26 21:00:02+00:00 AMZN 159.12 2024-01-26 21:00:02+00:00 NVDA 610.31 2024-01-26 21:00:03+00:00

Schedule this with cron and append to the CSV instead of overwriting, and you are building your own price history — one row per ticker per run, ready for charting or analysis.

Step 5: Pull historical prices

Everything so far returns the latest quote. For charts and backtesting you want candles, and those come from a companion endpoint, /v1/stockpricehistorical. It uses the same API key and takes the same ticker parameter, plus two optional ones: period for the candle interval (1m up to 1d; the default is 1h) and start/end Unix timestamps to bound the range.

historical.py
candles = session.get( 'https://api.api-ninjas.com/v1/stockpricehistorical', params={'ticker': 'AAPL', 'period': '1d'}, timeout=10, ).json() candles.sort(key=lambda c: c['time']) # API returns newest first latest = candles[-1] print(f"close={latest['close']} high={latest['high']} volume={latest['volume']}")

Each candle contains open, high, low, close, volume, and time. The API returns candles newest-first, so sort by time — as the example does — before feeding them to a chart.

Step 6: Handle errors and rate limits

The client from Step 3 already retries rate limits. The remaining failures are worth handling explicitly, because each one means something different:

StatusCauseWhat to do
400Unknown or malformed tickerValidate input and show a clear message.
401Missing or invalid API keyCheck the X-Api-Key header and its value.
429Rate limit exceededBack off and retry; cache quotes to reduce calls.
5xxTransient server errorRetry with backoff; alert only if it persists.

In code, that means catching two exception types — HTTPError for API-level failures and RequestException for network problems:

errors.py
from requests.exceptions import HTTPError, RequestException try: quote = get_quote('AAPL') except HTTPError as error: status = error.response.status_code if status == 400: print('Bad request — check the ticker symbol') elif status == 401: print('Missing or invalid API key') else: print(f'HTTP {status}: {error.response.text}') except RequestException as error: print(f'Network error: {error}')

Resist the blanket except Exception. Market data that fails silently is how wrong prices end up in databases — let unexpected errors crash loudly.

Where to go from here

You now have a hardened quote client, a watchlist exporter, and historical data. The download below bundles it into one runnable script. When you're ready to build further, the same API key covers the rest of the equity workflow: the Earnings Calendar API tells you which of your tickers report this week, the Stock News API adds headlines, and the Market Cap API adds company size.

stock_prices.py

The complete script from this guide: session reuse, rate-limit retries, CSV export, and a command-line ticker list.

Frequently asked questions

Is the stock price real-time or delayed?

Free keys return quotes delayed up to 15 minutes; premium plans get live prices. Every response includes an updated Unix timestamp, so you can always see exactly how fresh a quote is.

Which exchanges and tickers are supported?

Companies on every major exchange worldwide, plus market indexes like ^DJI for the Dow Jones. The /v1/stockpricelist endpoint returns the full list of available tickers.

How do I get historical stock prices in Python?

Call /v1/stockpricehistorical with the same API key. It returns OHLCV candles at intervals from 1 minute to 1 day, with optional start and end Unix timestamps to bound the range. Step 5 of this guide shows the code.

Why are name, exchange, and currency missing from my response?

Those three fields are premium-plan fields. Free responses always include ticker, price, updated, and volume, which is enough for most price trackers.

What happens if I request an invalid ticker?

The API returns a 400 status code with an error message in the body. Call response.raise_for_status() and catch HTTPError so a typo surfaces as a clear message instead of a confusing KeyError later.

How often should I poll for new prices?

Match your polling rate to your data plan. With 15-minute-delayed quotes there is nothing to gain from polling every second — cache each ticker, reuse one Session, and back off when you hit a 429.