Call.Report
GitHub
GitHub

ffiec-data-connect (Python)

Quickstart

Your first FFIEC data call in under two minutes — fetch a bank's full Call Report facsimile as a pandas DataFrame.

By the end of this page you’ll have pulled one institution’s full Call Report for a quarter and loaded it into a DataFrame.

Prerequisites

  • Installed ffiec-data-connect 3.0.0 or later (pip install ffiec-data-connect).
  • A JWT token from the FFIEC portal, loaded into FFIEC_USERNAME and FFIEC_BEARER_TOKEN environment variables.

First call

import os
from ffiec_data_connect import OAuth2Credentials, collect_reporting_periods, collect_data

creds = OAuth2Credentials(
    username=os.environ["FFIEC_USERNAME"],
    bearer_token=os.environ["FFIEC_BEARER_TOKEN"],
)

# 1. What periods are available?
periods = collect_reporting_periods(creds, series="call", output_type="list")
print(periods[-5:])
# e.g. ['9/30/2025', '12/31/2025', '3/31/2026', ...]

# 2. Pull one bank's Call Report for the most recent period.
#    RSSD 480228 is JPMorgan Chase Bank, N.A.
data = collect_data(
    creds,
    rssd_id="480228",
    reporting_period=periods[-1],
    series="call",
    output_type="pandas",
    force_null_types="pandas",  # keep integers as integers
)

print(data.shape)
print(data.head())

What you got back

A DataFrame with one row per MDRM line item in the facsimile. The columns are:

ColumnMeaning
mdrmLine-item identifier (e.g. RCON2170 = total assets).
rssdReporting institution’s RSSD.
quarterReporting period (string in the original MM/DD/YYYY format by default).
data_typeint, float, bool, or str — which typed column holds the value.
int_dataInteger value, if data_type == "int".
float_dataFloat value, if data_type == "float".
bool_dataBoolean value, if data_type == "bool".
str_dataString value, if data_type == "str".

Each row contains exactly one non-null typed value, indicated by data_type.

Looking up a specific line item

Total assets is MDRM RCON2170:

total_assets_row = data.loc[data["mdrm"] == "RCON2170"].iloc[0]
print(f"Total assets: ${total_assets_row['int_data']:,} thousand")

USD values in the XBRL facsimile are reported in thousands and stored as integers by the library (divided by 1000 during XBRL processing).

A second bank

# RSSD 37 is Cambridge Trust Company — a small community bank, useful for
# comparing against a money-center bank.
small_bank = collect_data(
    creds,
    rssd_id="37",
    reporting_period=periods[-1],
    series="call",
    output_type="pandas",
    force_null_types="pandas",
)

Prefer a notebook? The upstream ffiec_data_connect_rest_demo.ipynb walks through the same calls end-to-end.

navigate · open · Esc close