# FDIC Bank Financials Scraper - Call Report Data by State (`groundplanes/fdic-bank-financials-screener`) Actor

Scrape FDIC-insured banks by quarterly Call Report financials (assets, deposits, net income, ROA, Tier 1 leverage, noncurrent loans, CRE concentration, Texas ratio), branches, and failed banks.

- **URL**: https://apify.com/groundplanes/fdic-bank-financials-screener.md
- **Developed by:** [Groundplane Labs](https://apify.com/groundplanes) (community)
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.10 / 1,000 bank records

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## FDIC Bank Financials Scraper - Call Report Data by State

Scrape FDIC-insured commercial banks and savings institutions by their latest quarterly **Call Report** financials (`FINANCIALS`), brick-and-mortar branch locations (`BRANCHES`), or historical FDIC bank failures (`FAILURES`) directly from the official FDIC BankFind Suite API (`https://api.fdic.gov/banks/`).

> **Disclaimers:**
>
> - **Not Investment or Credit Advice:** The data and financial ratios returned by this Actor are provided strictly for informational, research, and analytical purposes and do not constitute investment, financial, legal, or credit advice.
> - **Non-Affiliation:** This Actor is an independent tool and is not affiliated with or endorsed by the Federal Deposit Insurance Corporation (FDIC).

***

### What it does

- **Automatic Latest Call Report Quarter Discovery:** When `reportDate` is left blank in `FINANCIALS` mode, the Actor queries `/banks/financials?limit=1&sort_by=REPDTE&sort_order=DESC` on startup to automatically resolve the newest published Call Report quarter (e.g. `20260630`).
- **Whole-Dollar Normalization:** FDIC Call Report monetary fields (`ASSET`, `DEP`, `NETINC`, `LNRECONS`, `LNREMULT`, `LNRENRES`, `COST`) are published by the FDIC in **thousands of dollars**; this Actor multiplies all monetary figures by **1,000** so every USD output field (`totalAssetsUsd`, `totalDepositsUsd`, `netIncomeUsd`, `creLoansUsd`, `estimatedLossUsd`) is reported in whole US dollars.
- **Call Report Credit & CRE Ratios:**
  - `creLoansUsd`: Sum of Construction & Land Development (`LNRECONS`), Multifamily 5+ Residential (`LNREMULT`), and Nonfarm Nonresidential (`LNRENRES`) real estate loans × `1,000`. The Nonfarm Nonresidential component (`LNRENRES`) includes owner-occupied properties.
  - `creToEquityPlusAllowancePct`: `(LNRECONS + LNREMULT + LNRENRES) / (EQ + LNATRES) * 100`. This ratio is CRE loans as a percentage of total equity capital (`EQ`) plus the Allowance for Loan and Lease Losses (`LNATRES`). It uses a total equity plus allowance basis, not total risk-based capital, and the CRE total includes owner-occupied nonfarm nonresidential loans, so it is not the interagency non-owner-occupied CRE concentration measure and should not be compared directly to the 300% supervisory concentration threshold. Left `null` if underlying fields are unreported.
  - `texasRatioPct`: `(NAASSET + P9ASSET + ORE) / ((EQ - INTAN) + LNATRES) * 100` (Nonaccrual Assets `NAASSET` + Loans 90+ Days Past Due `P9ASSET` + Other Real Estate Owned `ORE` divided by Tangible Equity `EQ - INTAN` plus Loan Loss Allowance `LNATRES`). Left `null` if underlying fields are unreported.
- **Three Operational Modes:**
  - `FINANCIALS`: Balance sheet, income statement, credit quality, CRE concentration, Texas ratio, branch count, and website by state and asset threshold.
  - `BRANCHES`: Brick-and-mortar branch locations (`locations` endpoint) with street address, coordinates, and established date.
  - `FAILURES`: Historical FDIC bank failures (`failures` endpoint) with failure date, acquiring institution, estimated Deposit Insurance Fund (DIF) loss, `resolutionType` (`RESTYPE`), and `insuranceFund` (`SAVR`). By default only `FAILURE` events are returned; set `includeAssistanceTransactions` to `true` to also return `ASSISTANCE` (open-bank assistance) transactions. Legitimate pre-1943 failures were published without a certificate number, so `cert` is `null` for those rows.

***

### Who it's for

- **Commercial Real Estate (CRE) & Debt Brokers:** Identify regional and community banks by asset size, CRE loan portfolio size (`creLoansUsd`), and CRE concentration on a total equity plus allowance basis (`creToEquityPlusAllowancePct`).
- **Institutional Treasury & Risk Teams:** Monitor counterparty bank health (`tier1LeveragePct`, `noncurrentLoansPct`, `texasRatioPct`, `roaPct`) across quarterly Call Reports.
- **M\&A, Fintech & Banking Analysts:** Screen active banks, branch footprints, and historical FDIC resolutions by state.

***

### Input

All parameters have working defaults/prefills that return results in under 2 minutes.

| Field | Type | Default / Prefill | Description |
|---|---|---|---|
| `mode` | `string` | `"FINANCIALS"` | `FINANCIALS` (Call Report financials & ratios), `BRANCHES` (branch locations), or `FAILURES` (FDIC failed banks list). |
| `states` | `array<string>` | `["AZ"]` | Two-letter US state or territory postal codes (e.g. `["AZ"]`, `["AZ", "NV", "UT"]`). Leave empty for all states. |
| `reportDate` | `string` | `""` (latest quarter) | Call Report quarter-end date in `YYYYMMDD` format (e.g. `"20260630"`, `"20260331"`). Leave blank to automatically use the latest published quarter. |
| `minTotalAssetsUsd` | `integer` | `0` | Minimum bank total assets in whole USD (`FINANCIALS` mode only). |
| `maxItems` | `integer` | `200` | Maximum number of records to return. |
| `includeAssistanceTransactions` | `boolean` | `false` | `FAILURES` mode only. When `false` (default), only failures are returned, matching the Failed Banks List. When `true`, assistance transactions are also returned and can be identified by `resolutionType: "ASSISTANCE"`. |

#### Example input JSON

```json
{
  "mode": "FINANCIALS",
  "states": ["AZ"],
  "reportDate": "",
  "minTotalAssetsUsd": 0,
  "maxItems": 200,
  "includeAssistanceTransactions": false
}
```

#### Example run options (with default $50 max charge protection)

When invoking via the Apify API or CLI, set a default maximum charge of **$50** (`"maxTotalChargeUsd": 50`):

```json
{
  "maxTotalChargeUsd": 50
}
```

The Actor checks `calculate_max_event_charge_count_within_limit("apify-default-dataset-item")` before every dataset push and stops cleanly when your spending limit is reached.

***

### Output

Results are saved to the default dataset.

- **Deduplication keys:** `cert + reportDate` (`FINANCIALS`), `uninumber` (`BRANCHES`), `ID` (`FAILURES`, with `FIN` as a fallback). Deduping failures on `ID` keeps separate resolution events that share one certificate number.
- **Sorting:** `reportDate` desc then `totalAssetsUsd` desc (`FINANCIALS`); `established` desc (`BRANCHES`); `failDate` desc (`FAILURES`).

#### Output fields

| Field | Mode(s) | Type | Description |
|---|---|---|---|
| `cert` | All | `integer \| string \| null` | FDIC Certificate Number. `null` for legitimate pre-1943 `FAILURES` records published without a certificate number. |
| `bankName` | All | `string \| null` | Institution legal name. |
| `city` | All | `string \| null` | Headquarters or branch city. |
| `state` | All | `string \| null` | Two-letter state code. |
| `reportDate` | `FINANCIALS` | `string \| null` | Call Report date in `YYYY-MM-DD` format. |
| `totalAssetsUsd` | `FINANCIALS` | `number \| null` | Total assets in whole USD (`ASSET * 1,000`). |
| `totalDepositsUsd` | `FINANCIALS` | `number \| null` | Total deposits in whole USD (`DEP * 1,000`). |
| `netIncomeUsd` | `FINANCIALS` | `number \| null` | Year-to-date net income in whole USD (`NETINC * 1,000`). |
| `roaPct` | `FINANCIALS` | `number \| null` | Return on Assets (`ROA`) percentage. |
| `tier1LeveragePct` | `FINANCIALS` | `number \| null` | Tier 1 Leverage Capital ratio (`RBC1AAJ`) percentage. |
| `noncurrentLoansPct` | `FINANCIALS` | `number \| null` | Noncurrent loans to total loans (`NCLNLSR`) percentage. |
| `creLoansUsd` | `FINANCIALS` | `number \| null` | Total CRE loans in whole USD (`(LNRECONS + LNREMULT + LNRENRES) * 1,000`). `null` if any component is unreported; a missing component is never treated as zero. |
| `creToEquityPlusAllowancePct` | `FINANCIALS` | `number \| null` | CRE loans as % of total equity capital plus allowance for loan and lease losses (`(LNRECONS + LNREMULT + LNRENRES) / (EQ + LNATRES) * 100`). Includes owner-occupied nonfarm nonresidential loans; not the interagency non-owner-occupied CRE concentration measure. |
| `texasRatioPct` | `FINANCIALS` | `number \| null` | Texas Ratio % (`(NAASSET + P9ASSET + ORE) / ((EQ - INTAN) + LNATRES) * 100`). |
| `branchCount` | `FINANCIALS` | `integer \| null` | Total domestic + foreign offices (`OFFDOM + OFFFOR`). |
| `website` | `FINANCIALS` | `string \| null` | Institution primary website URL. Enrichment from the FDIC institutions endpoint: if that call fails, rows still ship with `website` as `null` and the run ends `PARTIAL` with the reason `website enrichment unavailable`. |
| `branchName` | `BRANCHES` | `string \| null` | Branch office name (`OFFNAME`). |
| `address` | `BRANCHES` | `string \| null` | Branch street address (`ADDRESS`). |
| `zip` | `BRANCHES` | `string \| null` | Branch ZIP code (`ZIP`). |
| `established` | `BRANCHES` | `string \| null` | Branch established date (`YYYY-MM-DD`). |
| `latitude` | `BRANCHES` | `number \| null` | Branch WGS84 latitude. |
| `longitude` | `BRANCHES` | `number \| null` | Branch WGS84 longitude. |
| `uninumber` | `BRANCHES` | `string \| null` | FDIC unique branch identifier (`UNINUM`). |
| `failDate` | `FAILURES` | `string \| null` | Bank failure date (`YYYY-MM-DD`). |
| `acquirer` | `FAILURES` | `string \| null` | Acquiring institution name (`BIDNAME`). The FDIC sentinel value `0` (no acquirer) is returned as `null`. |
| `estimatedLossUsd` | `FAILURES` | `number \| null` | Estimated DIF loss in whole USD (`COST * 1,000`). |
| `resolutionType` | `FAILURES` | `string \| null` | Resolution type (`RESTYPE`), for example `FAILURE` or `ASSISTANCE`. |
| `insuranceFund` | `FAILURES` | `string \| null` | Insurance fund (`SAVR`), for example `DIF`, `FDIC`, or `FSLIC`. |

#### Sample output row (synthetic example)

```json
{
  "cert": 99999,
  "bankName": "EXAMPLE SOUTHWEST COMMERCIAL BANK",
  "city": "PHOENIX",
  "state": "AZ",
  "reportDate": "2026-06-30",
  "totalAssetsUsd": 2450000000.0,
  "totalDepositsUsd": 2080000000.0,
  "netIncomeUsd": 18400000.0,
  "roaPct": 1.12,
  "tier1LeveragePct": 10.45,
  "noncurrentLoansPct": 0.74,
  "creLoansUsd": 612000000.0,
  "creToEquityPlusAllowancePct": 218.57,
  "texasRatioPct": 5.82,
  "branchCount": 11,
  "website": "https://www.examplebank.com"
}
```

***

### How pricing works

Pay per result: $3.00 per 1,000 results ($0.003 per row). You only pay for rows returned.

***

### Data source and terms

- **Official Source:** Federal Deposit Insurance Corporation (FDIC), [BankFind Suite API (`https://api.fdic.gov/banks/docs/`)](https://api.fdic.gov/banks/docs/)
- **Update Cadence:** Call Report financial data (`financials`) is updated quarterly following FFIEC Call Report processing (~60 days after quarter-end); branch (`locations`) and failed bank (`failures`) endpoints are updated weekly/as events occur.
- **Terms of Use:** FDIC BankFind Suite data is U.S. Government public domain data published under [FDIC Open Data / Privacy & Website Policies](https://www.fdic.gov/about/privacy-program).

***

### Limits and FAQ

- **How are `creToEquityPlusAllowancePct` and `texasRatioPct` calculated?**
  Both ratios are computed from official FDIC Call Report fields requested from `/banks/financials` (`LNRECONS`, `LNREMULT`, `LNRENRES`, `EQ`, `INTAN`, `LNATRES`, `NAASSET`, `P9ASSET`, `ORE`). `creToEquityPlusAllowancePct` divides the CRE total (which includes owner-occupied nonfarm nonresidential loans in `LNRENRES`) by total equity plus the allowance for loan and lease losses (`EQ + LNATRES`); it is not calculated on total risk-based capital and does not exclude owner-occupied CRE, so it is not the interagency CRE concentration measure. If any required component is missing for an institution, the ratio is returned as `null` rather than approximated.
- **What happens if my filters match nothing?**
  The run succeeds with a `Complete: 0 rows matched your filters` status message that names the filters used and suggests which ones to widen (add states, clear `reportDate`, or lower `minTotalAssetsUsd`). Zero matches from a healthy source is a valid result, not an error.
- **What does a `PARTIAL:` status mean?**
  Some rows could not be delivered, and the status message says why: for example a source page failed after retries, rows failed validation and were skipped, or your max charge limit was reached. If the cause is on the source side, the message also asks you to open an issue so we can fix it.

***

### Troubleshooting

- **Stale data:** Call Report financials are quarterly. If the newest quarter looks old, the FDIC has not published a newer one yet; the Actor always resolves the latest published `REPDTE` when `reportDate` is blank.
- **Zero matches:** widen the filters named in the `Complete: 0 rows` status message.
- **Caps:** a `PARTIAL:` status naming the max charge limit or `maxItems` means your own limits stopped the run; raise them to get more rows.
- **PARTIAL runs:** report them on this actor's Issues tab (no email), with the full status message from your run.

Found a problem or need a field? Open an issue on the Issues tab; we respond quickly.

#### Canary input

A tiny input that returns at least 1 row in under 30 seconds when the source is healthy:

```json
{
  "mode": "FINANCIALS",
  "states": ["AZ"],
  "reportDate": "",
  "minTotalAssetsUsd": 0,
  "maxItems": 5
}
```

***

### Changelog

#### v0.1.3 (2026-11-01)

- Grok Red Team fix round: FAILURES mode is now keyed and validated on `ID` (with `FIN` as fallback), requiring `bankName` and `failDate` and allowing `cert` to be `null`, so legitimate pre-1943 failures no longer fail states like NJ or force a false PARTIAL on all-states runs; failures are deduped on `ID` instead of `CERT`, keeping second resolution events for the same certificate. FAILURES rows now carry `resolutionType` and `insuranceFund`, and the new `includeAssistanceTransactions` input (default `false`) keeps assistance transactions out of the default Failed Banks List output. The CRE field is renamed to `creToEquityPlusAllowancePct` and documented as a total equity plus allowance ratio that includes owner-occupied nonfarm nonresidential loans. A failed website enrichment call now ends the run `PARTIAL` with the reason `website enrichment unavailable`. Retries are 6 tries with jittered backoff from 2 to 32 seconds (capped at 120 seconds, honoring Retry-After). The `BIDNAME` sentinel `0` is returned as a `null` acquirer. Title and description now use Scraper / Scrape wording, the FINANCIALS maxItems status says largest first, and pricing states the per-1,000 figure.

#### v0.1.2 (2026-10-31)

- Red Team fix round: BRANCHES rows are now validated per row (a branch row missing its cert or bank name is skipped and counted, like the other modes, instead of being pushed with a null cert); the skipped-rows PARTIAL reason names the missing field per mode; BRANCHES and FAILURES requests now name their field set explicitly instead of relying on the FDIC default set; retries honor Retry-After (seconds or HTTP-date) with jitter. The `website` field is an enrichment from the FDIC institutions endpoint: if that lookup is unavailable, `website` is null (this behavior was superseded in v0.1.3, where the run ends PARTIAL with the reason `website enrichment unavailable`).

#### v0.1.1 (2026-10-31)

- Status contract fixed: runs now end `Complete:` or `PARTIAL:` with honest scanned, matched, and skipped counts; zero matches is a successful `Complete: 0 rows` run instead of a failure; a charge-limit stop is a `PARTIAL:` with no Issues call-to-action, and the verbatim Issues call-to-action is appended only when a PARTIAL reason is caused by the source.
- Added a core-column sentinel (a missing or renamed FDIC field fails the run loudly, naming the field), per-row validation with a 20% skip limit, and strict derived values: `creLoansUsd`, `creToEquityPlusAllowancePct`, `texasRatioPct`, and `branchCount` are now `null` when any component field is unreported, instead of treating the missing component as zero.
- BRANCHES mode now asks the API to sort by established date descending, so large states return the newest branches first; a source page that fails after the first page now yields a `PARTIAL:` run with the rows already collected instead of losing them.
- Categories set to BUSINESS only; default run options now include the $50 max charge; `reportDate` is validated as a real calendar date.

#### v0.1 (2026-10-31)

- Initial release supporting FDIC BankFind Suite `FINANCIALS`, `BRANCHES`, and `FAILURES` modes with automatic latest `REPDTE` resolution and Call Report CRE and Texas ratio calculations.

# Actor input Schema

## `maxItems` (type: `integer`):

Maximum number of records to return.

## `minTotalAssetsUsd` (type: `integer`):

Minimum bank total assets in whole US dollars (e.g. 500000000 for $500M). Set to 0 to return all banks.

## `mode` (type: `string`):

Select FINANCIALS (quarterly Call Report balance sheet, income, CRE concentration, and credit-quality ratios), BRANCHES (FDIC-insured brick-and-mortar branch locations), or FAILURES (FDIC failed bank list).

## `reportDate` (type: `string`):

Quarter-end Call Report date in YYYYMMDD format (e.g. "20260630", "20260331", "20251231"). Leave blank to automatically query the latest published quarter.

## `states` (type: `array`):

Two-letter US state or territory postal codes (e.g. \["AZ"] or \["AZ", "NV", "TX"]). Leave empty for all states.

## `includeAssistanceTransactions` (type: `boolean`):

FAILURES mode only. When false (default), only FAILURE resolution events are returned, matching the FDIC Failed Banks List. When true, ASSISTANCE (open-bank assistance) transactions are also returned; use the resolutionType field to tell them apart.

## Actor input object example

```json
{
  "maxItems": 200,
  "minTotalAssetsUsd": 0,
  "mode": "FINANCIALS",
  "reportDate": "",
  "states": [
    "AZ"
  ],
  "includeAssistanceTransactions": false
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "maxItems": 200,
    "minTotalAssetsUsd": 0,
    "mode": "FINANCIALS",
    "reportDate": "",
    "states": [
        "AZ"
    ],
    "includeAssistanceTransactions": false
};

// Run the Actor and wait for it to finish
const run = await client.actor("groundplanes/fdic-bank-financials-screener").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "maxItems": 200,
    "minTotalAssetsUsd": 0,
    "mode": "FINANCIALS",
    "reportDate": "",
    "states": ["AZ"],
    "includeAssistanceTransactions": False,
}

# Run the Actor and wait for it to finish
run = client.actor("groundplanes/fdic-bank-financials-screener").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "maxItems": 200,
  "minTotalAssetsUsd": 0,
  "mode": "FINANCIALS",
  "reportDate": "",
  "states": [
    "AZ"
  ],
  "includeAssistanceTransactions": false
}' |
apify call groundplanes/fdic-bank-financials-screener --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,groundplanes/fdic-bank-financials-screener"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/Djaofi7TDdaJWq67T/builds/yheNeRLkfKvLniqMB/openapi.json
