---
name: ffiec-call-reports-bulk-ingestion
description: "How to get FFIEC Call Reports Bulk Data data into a pandas DataFrame and Parquet: access, the request, the format, limits, quirks and terms."
---

# Load the latest FFIEC Call Report bulk file into Parquet

Source entry: https://signal-lab-jet.vercel.app/datasets/ffiec-call-reports-bulk
Provider: https://cdr.ffiec.gov/public/PWS/DownloadBulkData.aspx
Checked against the provider's documentation: 2026-11-01

## Access
- No account or key is required for the interactive bulk-download form.
- The example reproduces the form's ASP.NET postbacks and selects the latest single-period tab-delimited file.

## Request
```bash
curl 'https://cdr.ffiec.gov/public/PWS/DownloadBulkData.aspx'
```

## Format
ZIP archive containing a tab-delimited Call Report file for one reporting period; the checked file had 4,336 rows and 12 columns.

## Load into pandas and Parquet
Needs Python 3 with requests, pandas and pyarrow.
```python
"""Latest FFIEC single-period Call Report bulk file -> pandas -> Parquet."""
import html
import io
import re
import zipfile
import requests
import pandas as pd

URL = "https://cdr.ffiec.gov/public/PWS/DownloadBulkData.aspx"
HEADERS = {"User-Agent": "SignalLabCheck/1.0"}
session = requests.Session()

def hidden_fields(text):
    pairs = re.findall(
        r'<input[^>]+type="hidden"[^>]+name="([^"]+)"[^>]+value="([^"]*)"',
        text,
    )
    return {html.unescape(name): html.unescape(value) for name, value in pairs}

text = session.get(URL, headers=HEADERS, timeout=30).text
data = hidden_fields(text)
data.update({
    "__EVENTTARGET": "ctl00$MainContentHolder$ListBox1",
    "ctl00$MainContentHolder$ListBox1": "ReportingSeriesSinglePeriod",
})
text = session.post(URL, headers=HEADERS, data=data, timeout=30).text
period_block = re.search(r'<select[^>]+id="DatesDropDownList".*?</select>', text, re.S).group()
period_id, period_label = re.search(r'<option value="([^"]+)">([^<]+)', period_block).groups()
data = hidden_fields(text)
data.update({
    "__EVENTTARGET": "ctl00$MainContentHolder$DatesDropDownList",
    "ctl00$MainContentHolder$ListBox1": "ReportingSeriesSinglePeriod",
    "ctl00$MainContentHolder$DatesDropDownList": period_id,
})
text = session.post(URL, headers=HEADERS, data=data, timeout=30).text
data = hidden_fields(text)
data.update({
    "__EVENTTARGET": "ctl00$MainContentHolder$TSVRadioButton",
    "ctl00$MainContentHolder$ListBox1": "ReportingSeriesSinglePeriod",
    "ctl00$MainContentHolder$DatesDropDownList": period_id,
    "ctl00$MainContentHolder$FormatType": "TSVRadioButton",
})
text = session.post(URL, headers=HEADERS, data=data, timeout=30).text
data = hidden_fields(text)
data.update({
    "ctl00$MainContentHolder$ListBox1": "ReportingSeriesSinglePeriod",
    "ctl00$MainContentHolder$DatesDropDownList": period_id,
    "ctl00$MainContentHolder$FormatType": "TSVRadioButton",
    "ctl00$MainContentHolder$TabStrip1$Download_0": "Download",
})
r = session.post(URL, headers=HEADERS, data=data, timeout=120)
r.raise_for_status()
with zipfile.ZipFile(io.BytesIO(r.content)) as archive:
    filename = archive.namelist()[0]
    df = pd.read_csv(io.BytesIO(archive.read(filename)), sep="\t", low_memory=False)
df.to_parquet("ffiec_call_report_latest.parquet", index=False)
print(len(df), "rows", len(df.columns), "columns", filename)
```
Run by us on 2026-11-01 (python 3.13.5 | pandas 3.1.0 | pyarrow 26.0.0 | requests 2.34.2). Result: 4336 rows 12 columns FFIEC CDR Call Bulk POR 03312026.txt

## Limits
- Rate limit: Not stated.
- Single-period Call Report choices run from March 2001 through the latest available quarter on the checked page.
- The checked March 2026 ZIP was about 5.5 MB.

## Quirks
- The download page is an ASP.NET form; preserve hidden state fields across product, period, format and download postbacks.
- Product and period IDs are internal values, so discover the first current period option instead of hard-coding it.
- FFIEC says the XBRL option has received limited instance-validation testing.

## Terms and attribution
- The checked FFIEC legal notice does not assign a standard data license.
- FFIEC disclaims warranties and responsibility for accuracy, correctness and completeness.
- Terms page: https://cdr.ffiec.gov/public/LegalNotice.aspx

## Sources
- https://cdr.ffiec.gov/public/PWS/DownloadBulkData.aspx: "This page enables you to download bulk data in either Excel compatible or XBRL format."
- https://cdr.ffiec.gov/public/PWS/DownloadBulkData.aspx: "These products are for All Commercial Banks."
- https://cdr.ffiec.gov/public/PWS/DownloadBulkData.aspx: "Note that the XBRL download option has received only limited instance validation testing."
- https://cdr.ffiec.gov/public/LegalNotice.aspx: "the FFIEC makes no warranty, express or implied, nor assumes any legal liability or responsibility for the accuracy, correctness, or completeness of any information"

## Help improve this skill
Missing a source, or see something to improve? Call the MCP tool suggest_source or feedback (or POST /api/suggest or /api/feedback). Reviewed ideas: https://signal-lab-jet.vercel.app/agent-suggestions

Information for educational purposes only. Free tiers, limits and licenses belong to the providers and may change; check the provider's own terms before using the data.
