FDIC Bank Branch Openings, Closings & Market Exit Rollup avatar

FDIC Bank Branch Openings, Closings & Market Exit Rollup

Pricing

from $8.25 / 1,000 results

Go to Apify Store
FDIC Bank Branch Openings, Closings & Market Exit Rollup

FDIC Bank Branch Openings, Closings & Market Exit Rollup

Net FDIC branch churn by bank, county and quarter: openings, closings, purchases, acquisitions, divestitures and relocations, with metro area and branch-desert flags, plus the verified standing branch count today from FDIC's own branch list, so a market exit is confirmed rather than inferred.

Pricing

from $8.25 / 1,000 results

Rating

0.0

(0)

Developer

Kyle Maloney

Kyle Maloney

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

Share

FDIC Bank Branch Network Churn & Market Exit Rollup

Every branch a US bank opened, closed, bought, sold, inherited in a merger or relocated, rolled into a bank x county x quarter table — with net change, the verified standing branch count today, confirmed market entry and exit, metro/micropolitan classification, and a branch-desert signal for counties that have been thinning for several quarters running.

Source: the FDIC public API (api.fdic.gov) — /banks/history, /banks/locations and /banks/institutions. No key, no scraping, no login. FDIC refreshes the data daily; the actor refuses to run against a stale index.


Who this is for

Branch strategy and network planning. You need to know where the incumbent footprint is shrinking before you commit a lease. Filter to is_branch_desert_signal = true and sort by county_offices_current to find counties where deposits are stranded but the competition has left. net_change_incl_relocations is the honest county figure — a bank that "closed" a branch and opened one two miles away across the county line did not remove a branch from the market.

CRA and fair-banking analysts. Branch closures in low- and moderate-income counties are an examination topic. county_fips joins straight to Census, HMDA and FFIEC data; is_market_exit_confirmed tells you which banks genuinely left a county rather than merely posting a bookkeeping event. cbsa_type splits metropolitan from micropolitan and rural.

Commercial real estate. Bank branches are prime retail corners on long leases. A confirmed market exit is a pipeline of second-generation retail space with parking, a drive-through and a vault. is_market_exit_confirmed = true plus closed >= 1 is the shortlist.

Fintech and de-novo market entry. is_market_entry_confirmed shows which charters are actively building in a market and which are harvesting it. county_bank_count against county_offices_current shows concentration, and holding_company_name collapses subsidiaries up to the parent so three brands owned by one company do not read as three competitors.

Bank M&A and competitive intelligence. acquired_in_merger and purchased show inorganic growth by county; successor_cert and inst_active follow a charter through its absorption; and in events mode acquirer_name / seller_name name both sides of a branch transfer.


What makes the numbers trustworthy

The office-count correction (read this before using offices_end)

FDIC's branch-event stream is not a closed ledger, so a running balance over it is not a standing office count. When a charter is absorbed the acquirer books a "Branch Acquired in Merger" event for each branch — but the disappearing charter books nothing. Change code 713 is 202,213 of the 366,989 branch events in the dataset (55%), so that omission dominates:

Re-measured live on 2026-07-28 (FDIC index locations_20260724090007) by running this actor:

Net-event balanceFDIC standing branches, same seriesSeries reconciling
Texas14,8165,982overstated 148%2,285 of 5,804 (39.4%)
Vermont353205overstated 72%87 of 188 (46.3%)

The right-hand branch count is the matched-series figure — the standing branches that sit in a bank x county series the event stream also covers, which is the only apples-to-apples denominator for a replay. Do not read it as the size of the state. Texas as a whole is 6,414 offices on /banks/locations (347 main + 6,067 branches); Vermont is 219 (12 main + 207 branches).

Concretely: Chittenden Trust Company (CERT 14149) ceased to exist on 2009-01-01, and its net-event balance still reads 32 offices in Vermont.

This actor therefore ships both numbers and tells you which is which:

  • offices_start / offices_end — the cumulative net-event balance, unchanged from v1.0 so existing pipelines keep working. office_balance_basis records how it was built.
  • offices_current — the authoritative standing branch count for that bank in that county today, straight from FDIC's own branch list, excluding the main office. This is the number to act on.
  • reconciles_to_locations / reconciliation_delta — the gap between the two, on every row.
  • is_market_exit_confirmed — asserted only when the bank's last event quarter in the county coincides with zero standing branches there today. is_market_exit alone can fire on a bookkeeping artefact.

Relocations are counted, on both endpoints

Change code 520 is the only relocation code in the entire FDIC dataset (verified by an exhaustive sweep of codes 0-999) and it is 100% branch-level. A single 520 row carries both the origin and the destination county. Because the natural state filter is the destination, a branch relocating out of your state is invisible unless the origin field is queried too — this actor queries both. In Texas 101 relocations crossed a county line and 9 crossed a state line; those are real branch losses for the origin county that a destination-only query never sees. Relocations never touch net_change (they are neither an opening nor a closing); they land in relocated_in, relocated_out, relocated_within_county and net_change_incl_relocations.

The branch state, not the charter state

FDIC publishes both PSTALP (where the bank is chartered) and OFF_PSTALP (where the branch physically is). For Texas branch closings they differ 4,592 vs 2,412, and 19.7% of the charter-state rows sit outside Texas — a real Wells Fargo row is chartered in SD with a branch in TN. This actor uses the branch state everywhere geography matters, and asserts it at runtime.

Nothing is silently discarded

3.09% of FDIC's national branch-event stream (6.3% in Vermont) carries no CERT. Those rows used to be dropped on the floor. They are the per-branch legs of a purchase, and they cannot be folded into a bank's balance without double-counting — FDIC publishes a CERT-bearing row for the same branch on the same day. So they are surfaced instead: reported in events mode with cert: null and cert_attributed: false, resolved to acquirer_name and seller_name, and counted on every row as county_events_unattributed.

Five live assertions, checked on every run

An offline test cannot see a silently degraded upstream, because the fixture was shaped from the degraded data. These run against the real response and fail the run rather than bill you for a confident wrong answer:

  1. The filter FDIC echoes back must exactly equal the filter that was sent. (FDIC has silently dropped an unparseable filter and returned the entire 583,491-row national dataset.)
  2. Every returned record must actually be in the requested states and change codes — a data-level check that does not take FDIC's word for it.
  3. A one-state query reporting national-scale row counts is refused.
  4. The FDIC search index must have been rebuilt within 45 days.
  5. The reconciliation between the event replay and the standing branch list must stay inside its measured band. A rate of zero means the join key broke and every offices_current would be wrong.

And a gate that does not run says so on the row. Every one of the five can legitimately skip — FDIC serving a response with no index metadata, a page with no records, a 51-state sweep, reconcileWithLocations turned off, a state too small for the reconciliation rate to mean anything. A skip is not a bug; a silent skip is, because a check that quietly no-ops is not a check. So each gate stamps gate_<name>_status (ok / skipped / not_run) on every row, alongside drift_gates_ok, drift_gates_skipped and drift_gates_skipped_reason, and logs a DRIFT GATE SKIPPED warning naming the reason. If none of the five could run, the actor fails and emits nothing — rows nothing verified are not worth billing for.

Per-source honesty

/banks/history is required — if it cannot answer the run fails and nothing is emitted or billed. The other three sources are enrichment: if one is down the run continues, every field derived from it is null (never false, never 0), and the row says so in locations_status, institutions_status, relocations_status and source_notes. offices_current: 0 means FDIC lists no branch. offices_current: null means we did not check.


Example input

{
"mode": "churn",
"states": ["TX"],
"sinceDate": "2024-01-01",
"maxResults": 500
}

A branch-desert sweep across a whole region:

{
"mode": "county",
"states": ["MS", "AL", "AR"],
"quarters": 12,
"thinningQuarters": 3,
"maxResults": 2000
}

Every branch event and relocation in two counties, with acquirer attribution:

{
"mode": "events",
"states": ["TX"],
"counties": ["HARRIS", "DALLAS"],
"sinceDate": "2023-01-01",
"maxResults": 5000
}

Input fields

FieldTypeNotes
statesarrayTwo-letter USPS codes, max 10 per run. Filters on the branch state. Defaults to ["TX"], so a bare {} is a valid Texas run rather than an error; an explicitly empty list is rejected.
modestringchurn (bank x county x quarter, the default), county, bank, or events.
sinceDate / untilDatestringYYYY-MM-DD. Bounds the output window; the full history is still replayed behind it.
quartersintegerAlternative to sinceDate — the N most recent quarters.
countiesarrayOptional county-name filter, e.g. ["HARRIS","DALLAS"].
thinningQuartersintegerConsecutive negative county quarters required for is_branch_desert_signal. Default 3.
maxResultsintegerRow cap, and the thing you are billed for. Default 500, the same as the prefill. Raise it deliberately — a full-state sweep runs to tens of thousands of rows.
replayFullHistorybooleanDefault true. Off = a faster window-only run with a window-relative balance.
reconcileWithLocationsbooleanDefault true. Off = offices_current, MSA and reconciliation fields come back null, and gate_reconciliation_status reads skipped.
includeRelocationsbooleanDefault true. Off = relocation fields come back null.

On states and required: states deliberately carries a default and is deliberately not in the schema's required list. Apify applies a property default before it validates required, so listing it there could never actually fire — a bare {} silently became a Texas run while the schema advertised a 400. Two honest options existed: drop the default so the guard bites, or drop the guard. The default stays, because a well-formed Texas answer is a legitimate result and Apify's automated quality checks re-run this actor on a {}-shaped input every few days and expect it to succeed. A genuinely empty "states": [] is still rejected loudly at runtime, before anything is fetched or billed.


Output fields (churn mode)

FieldTypeMeaning
period, period_start, period_endstringCalendar quarter and its bounds.
state, county, county_fipsstringBranch geography. county_fips is the 5-digit Census FIPS.
cbsa_code, cbsa_name, cbsa_type, is_metromixedMetro / micropolitan area for the county. cbsa_type is metropolitan, micropolitan or none.
cert, inst_namemixedFDIC certificate number and institution name.
inst_active, inst_end_date, successor_certmixedCharter status. inst_active: false with a successor_cert means the bank was absorbed.
inst_total_officesintegerThe institution's nationwide office count.
holding_company_rssd, holding_company_namestringTop holding company (Federal Reserve RSSD).
opened, purchased, acquired_in_mergerintegerInbound events (FDIC codes 711, 712, 713).
closed, sold, divestedintegerOutbound events (721, 722, 724).
inbound_total, outbound_total, net_changeintegerExact event arithmetic. net_change is the headline metric.
offices_start, offices_endintegerCumulative net-event balance — see the correction above.
office_balance_basisstringHow that balance was built.
offices_currentintegerVerified standing branches today, excluding the main office.
offices_current_incl_main, offices_current_asofmixedInclusive count and the FDIC snapshot date.
reconciles_to_locations, reconciliation_deltamixedBalance vs the standing list.
is_market_entry, is_market_exitbooleanBalance-based flags, kept from v1.0.
is_market_entry_confirmed, is_market_exit_confirmedbooleanCross-checked against the standing branch list. Use these.
is_first_event_quarter, is_final_event_quarterbooleanPosition of this quarter in the bank's activity in this county.
office_count_estimatedbooleanThe balance was clamped at zero. net_change is still exact.
relocated_in, relocated_out, relocated_within_countyintegerChange-code-520 moves, both endpoints.
net_change_incl_relocationsintegerThe true county-level change.
churn_rate_pctnumberQuarter events as a share of the bank's standing branches in the county.
county_total_net, county_bank_countintegerCounty-wide net change and active banks that quarter.
county_offices_current, county_net_change_rate_pct, county_churn_eventsmixedSize and intensity of the county banking market.
county_events_unattributedintegerEvents FDIC published without a CERT.
county_consecutive_negative_quarters, county_is_thinning, is_branch_desert_signalmixedThinning streak and the desert flag.
history_status, locations_status, institutions_status, relocations_statusstringok / partial / unavailable / skipped per source.
gate_filter_echo_statusstringDid the "FDIC echoed back exactly the filter we sent" gate run? ok / skipped / not_run.
gate_record_postcondition_statusstringDid the "every record really is in the requested states and change codes" gate run?
gate_national_scale_statusstringDid the national-scale row-count band run? Skips on an unscoped or 51-state query.
gate_index_freshness_statusstringDid the index-age check run? Skips when FDIC serves no meta.index.createTimestamp.
gate_reconciliation_statusstringDid the replay-vs-standing-branches reconciliation run? Skips when /banks/locations was not consulted or the state is too small.
drift_gates_ok, drift_gates_skippedintegerHow many of the five gates ran, and how many did not.
drift_gates_skipped_reasonstringNamed reason per skipped gate. Null when all five ran.
source_notesstringPopulated only when a source degraded. Null on a healthy run.
data_asof_history, data_asof_locationsstringVintage of each upstream snapshot.
source_url, retrieved_atstringThe exact FDIC query and the fetch timestamp.

county mode aggregates the same quarter across all banks and adds market_entries, market_exits, county_banks_with_offices and county_banks_current. bank mode gives one row per bank per quarter across the whole requested geography, with counties_touched, county_market_exits_confirmed and the bank's offices_current. events mode is the raw typed stream — one row per branch event and per relocation, with transnum, org_role_code, acq_uninum / out_uninum and the resolved acquirer_cert / acquirer_name / seller_cert / seller_name.


Use as an MCP tool

This actor is available to AI agents through mcp.apify.com. Every input and output field carries a description, so an agent can pick and chain it without extra prompting. Typical agent question: "Which Mississippi counties have lost bank branches for three straight quarters, and which banks have fully exited them?" — one call with mode: "county", then filter on is_branch_desert_signal.

Pricing

$15 per 1,000 results, billed on the automatic result event — you pay for rows, not for compute. Graduated discounts apply on paid Apify plans (Bronze 20% through Diamond 70%). Use maxResults to cap a large sweep. A run that fails a source-integrity assertion emits zero rows and bills nothing.

  • FDIC Bank Structure Change & M&A Delta Monitor — the institution-level companion. All 41 FDIC change codes decoded, acquirer/target linkage, and a delta feed of new mergers, failures and charter changes.
  • FDIC Deposit Market Share & HHI Rollup — Summary of Deposits by county and MSA with market share and Herfindahl concentration. Join on county_fips to see whether a branch exit actually moved deposits.
  • FDIC & NCUA Bank Health Rollup — capital, asset quality and earnings for the same certificates. Join on cert to see whether a bank is retrenching from strength or from stress.

FAQ

Why is offices_end bigger than offices_current? Because FDIC records no outbound branch event when a charter is absorbed, so the acquired bank's balance never returns to zero. offices_current is the verified figure and reconciliation_delta is the gap. This is a property of the source, documented rather than hidden.

Why did my run fail with "did not honour the filter"? A source-integrity assertion tripped: FDIC returned something other than what was asked for. The run is failed deliberately so you are not billed for a national dataset when you asked for one state. Re-run; if it persists, FDIC's API has changed.

Zero rows — is that a bug? Only if the run is red. A green run with zero rows means FDIC honoured a well-formed query and genuinely has no branch events for that state and window. A broken query fails loudly instead.

How far back does the data go? The branch-event stream reaches back to 1970. Branches established before that have no opening event, which is one reason the event balance is a lower bound and offices_current is not.

Can I get branch-level addresses and coordinates? events mode gives branch names, numbers, UNINUMs and cities. Street addresses and latitude and longitude for the standing network live in FDIC /banks/locations and can be surfaced on request.

Is the data licensed? FDIC data is US federal government work product and in the public domain. Attribution to the FDIC is good practice.