Context

IEX Cloud retired all of its products on August 31 2024 (source), leaving thousands of applications without a data backend. Alpha Vantage is one of the most popular replacements thanks to its generous free tier and familiar JSON responses. This hands‑on tutorial walks you through every step required to port an IEX‑based Python project to Alpha Vantage.

Prerequisites

  • Python 3.9 or newer (for the | dict merge operator).
  • pip (or Poetry) for installing packages.
  • An Alpha Vantage API key. Create a free account at https://www.alphavantage.co and store the key in an environment variable called ALPHA_VANTAGE_KEY.
  • The following Python libraries: pandas ≥ 2.2, requests ≥ 2.31, python‑dotenv, and tqdm.

Quick install command:

pip install pandas requests python-dotenv tqdm

Alpha Vantage free tier limits (April 2025): 25 API calls per day and 5 calls per minute. Plan to implement caching or upgrade if you need more.

Alpha Vantage 101

Alpha Vantage use REST‑style paths. You can call https://www.alphavantage.co/query with URL parameters.

Basic pattern:

https://www.alphavantage.co/query?function=&symbol=&apikey=

If you were using IEX Cloud endpoints, here are the closest Alpha Vantage functions:

  • Real‑time quote → GLOBAL_QUOTE
  • Daily prices (adjusted) → TIME_SERIES_DAILY_ADJUSTED
  • Intraday prices (1‑minute) → TIME_SERIES_INTRADAY plus interval=1min (full history is paid)
  • Company profile → OVERVIEW
  • Earnings calendar → EARNINGS_CALENDAR

Alpha Vantage wraps its payloads inside keys like "Global Quote" or "Time Series (Daily)". We will flatten those.

Drop‑In Adapter Class

The class below exposes a minimal IEX‑like interface so you can keep the rest of your code unchanged.

from __future__ import annotations
import os, requests
from typing import Dict

BASE_URL = "https://www.alphavantage.co/query"
API_KEY = os.getenv("ALPHA_VANTAGE_KEY")

class AlphaAdapter:
    """Tiny wrapper that mimics common IEX Cloud calls."""

    def __init__(self, api_key: str | None = None):
        self.api_key = api_key or API_KEY
        self.calls_today = 0

    def _request(self, **params) -> Dict:
        if self.calls_today >= 25:
            raise RuntimeError("Free‑tier daily quota exhausted.")
        params["apikey"] = self.api_key
        resp = requests.get(BASE_URL, params=params, timeout=15)
        resp.raise_for_status()
        self.calls_today += 1
        return resp.json()

    def quote(self, symbol: str) -> Dict:
        raw = self._request(function="GLOBAL_QUOTE", symbol=symbol)
        return self._flatten(raw["Global Quote"])

    def daily_prices(self, symbol: str, outputsize: str = "compact") -> Dict[str, Dict]:
        raw = self._request(function="TIME_SERIES_DAILY_ADJUSTED",
                            symbol=symbol, outputsize=outputsize)
        return raw["Time Series (Daily)"]

    @staticmethod
    def _flatten(d: Dict[str, str]) -> Dict[str, str]:
        # Convert keys like "01. symbol" → "symbol"
        return {k.split(". ")[-1]: v for k, v in d.items()}

Example usage:

client = AlphaAdapter()
quote = client.quote("AAPL")
print("Apple latest price:", quote["price"])

Breaking Differences and Mitigations

  • Symbol directory: IEX offered /ref-data/symbols. Alpha Vantage publishes a nightly CSV called LISTING_STATUS instead.
  • Numeric types: IEX returned JSON numbers; Alpha Vantage returns strings. Always cast to float or int.
  • Corporate actions: IEX had a dedicated endpoint. Alpha Vantage embeds split and dividend data in TIME_SERIES_* responses and in EARNINGS_CALENDAR.

Sanity‑Check Your Migration

  • Pick historical dates before 31 August 2024 for which you still have IEX data.
  • Pull the same range from Alpha Vantage.
  • Compare the two datasets. For a quick numeric diff:
import pandas as pd, numpy as np
iex = pd.read_parquet("AAPL_iex.parquet")
av  = pd.read_parquet("AAPL_alpha.parquet")
print(np.abs(iex["close"] - av["close"]).describe())

Wrap‑Up

Migrating boils down to translating IEX endpoint paths into Alpha Vantage function parameters and respecting tighter rate limits. With the AlphaAdapter class above your existing code can stay almost unchanged.

Happy porting!