Forex API for Python: Live, Historical, and Pandas Examples

< Back to Guides

This guide uses the official forexrateapi Python package. It covers authentication, current rates, historical dates, pandas ingestion, OHLC data, and the error shape returned by the API.

Get a free API key before running the examples.

Install the official Python SDK

Install the package and pandas:

python -m pip install forexrateapi pandas

The SDK source and package documentation are also available in the ForexRateAPI Python repository.

Authenticate the client

Pass your API key when creating the client. The SDK attaches it to each request.

import os

from forexrateapi.client import Client

api_key = os.environ["FOREXRATEAPI_KEY"]
client = Client(api_key)

Set the environment variable before running your script:

export FOREXRATEAPI_KEY="YOUR_API_KEY"

Use Client(api_key, server="eu") if your application should call the European API server. Do not commit API keys to source control.

Get current exchange rates

fetchLive accepts a base currency and a list of target currencies. USD is the default base.

payload = client.fetchLive(
    base="USD",
    currencies=["EUR", "GBP", "JPY"],
)

if not payload.get("success"):
    raise RuntimeError(payload.get("error", {}).get("info", "Forex API request failed"))

rates = payload["rates"]
print(f"1 USD = {rates['EUR']} EUR")
print(f"1 USD = {rates['GBP']} GBP")
print(f"1 USD = {rates['JPY']} JPY")

Refresh frequency depends on your subscription plan. See plans and quotas.

Get rates for a historical date

Pass a date in YYYY-MM-DD format to fetchHistorical.

from datetime import date, timedelta

historical_date = (date.today() - timedelta(days=2)).isoformat()

payload = client.fetchHistorical(
    date=historical_date,
    base="USD",
    currencies=["EUR", "GBP", "JPY"],
)

if not payload.get("success"):
    raise RuntimeError(payload.get("error", {}).get("info", "Historical request failed"))

print(payload["base"])
print(payload["rates"])

For endpoint availability, date ranges, hourly data, and OHLC limits, see the historical Forex data API page.

Load a historical timeframe into pandas

The timeframe response stores rates under date keys. Convert that mapping directly into a DataFrame:

import pandas as pd
from datetime import date, timedelta

end_date = date.today() - timedelta(days=1)
start_date = end_date - timedelta(days=4)

payload = client.timeframe(
    start_date=start_date.isoformat(),
    end_date=end_date.isoformat(),
    base="USD",
    currencies=["EUR"],
)

if not payload.get("success"):
    raise RuntimeError(payload.get("error", {}).get("info", "Timeframe request failed"))

frame = pd.DataFrame.from_dict(payload["rates"], orient="index")
frame.index = pd.to_datetime(frame.index)
frame.index.name = "date"
frame = frame.sort_index()

print(frame.head())
print(frame.dtypes)

The resulting frame has one row per date and one numeric column per requested currency. The example works with a free key. Free plans support recent ranges up to 5 days and one quote currency; paid plans support multiple quote currencies and ranges up to 365 days.

Get hourly rates

The hourly endpoint accepts one quote currency per request:

from datetime import date, timedelta

hourly_date = (date.today() - timedelta(days=1)).isoformat()

payload = client.hourly(
    base="USD",
    currency="EUR",
    start_date=hourly_date,
    end_date=hourly_date,
)

if not payload.get("success"):
    raise RuntimeError(payload.get("error", {}).get("info", "Hourly request failed"))

hourly_frame = pd.DataFrame(
    {
        "timestamp": point["timestamp"],
        "EUR": point["rates"]["EUR"],
    }
    for point in payload["rates"]
)
hourly_frame["timestamp"] = pd.to_datetime(
    hourly_frame["timestamp"],
    unit="s",
    utc=True,
)

print(hourly_frame.head())

Free plans can query up to 2 days within the latest 2 days. Paid plans can query stored hourly history from June 19, 2025 in windows up to 7 days. Future dates and multiple quote currencies are not accepted.

Get OHLC data

Use ohlc for one base/quote pair and date:

from datetime import date, timedelta

ohlc_date = (date.today() - timedelta(days=1)).isoformat()

payload = client.ohlc(
    base="EUR",
    currency="USD",
    date=ohlc_date,
)

if not payload.get("success"):
    raise RuntimeError(payload.get("error", {}).get("info", "OHLC request failed"))

candle = payload["rate"]
print(candle["open"], candle["high"], candle["low"], candle["close"])

OHLC values use a 00:00–23:59:59 GMT trading day. The previous day becomes available at 00:05 GMT. Free plans can query the latest 5 days; older stored OHLC dates require a paid plan.

Handle API errors

The SDK returns the decoded JSON response. API errors use success: false with an error object, so check the response before reading rates or rate.

def require_success(payload):
    if payload.get("success"):
        return payload

    error = payload.get("error", {})
    code = error.get("code", "unknown")
    message = error.get("info", "Forex API request failed")
    raise RuntimeError(f"ForexRateAPI error {code}: {message}")


payload = require_success(
    client.fetchLive(base="USD", currencies=["EUR"])
)

Common errors include a missing or invalid API key, invalid currency codes or dates, exhausted quota, and endpoint-specific range limits. Review the complete API errors reference.

Network exceptions raised by the underlying requests library should be handled separately when your application needs retries or custom timeout behavior.

Next steps