# CFPB Complaints Feed: Bank & Fintech Complaint Spikes (`moment-data/cfpb-company-complaints-feed`) Actor

New consumer complaints against banks, lenders, credit bureaus, fintechs and debt collectors from the official CFPB Consumer Complaint Database, plus per-company counts vs prior window, product/issue mix and spike alerts. Filter by company, product, issue, state. No API key.

- **URL**: https://apify.com/moment-data/cfpb-company-complaints-feed.md
- **Developed by:** [Luke Miller](https://apify.com/moment-data) (community)
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## CFPB Complaints Feed: Bank & Fintech Complaint Spikes (official, no key)

Track **new consumer complaints against banks, credit card issuers, lenders, mortgage servicers, credit bureaus, fintechs, payment apps and debt collectors** straight from the **official CFPB Consumer Complaint Database** (U.S. Consumer Financial Protection Bureau, public domain). The database adds roughly **25,000-30,000 complaints a day** across 4,000+ companies.

Two modes:

- **`complaints`** (default): one clean record per complaint (company, product / sub-product, issue / sub-issue, state, ZIP3, channel, company response, timely flag, tags), filterable by company, product, issue and state.
- **`companySummary`**: one row per company with **complaints in the window vs the prior window, growth %, a spike flag**, rank, product / issue / state mix, timely-response rate and response breakdown. Find the companies whose complaints are surging this month.

### Who it's for

- **Fintech, bank and lender competitive intelligence:** watch competitors' complaint volume and what customers complain about (fees, fraud, repossession, payment trouble, account closures).
- **Compliance, risk and vendor management teams:** monitor your own company, partners, sponsor banks, servicers and collection agencies; spot spikes before regulators do.
- **Plaintiff law firms and consumer advocates:** emerging issues by company, product and state (e.g. repossession complaints against an auto lender jumping 100%).
- **Investors and analysts:** complaint growth as an alternative-data signal for listed lenders, card issuers and fintechs.
- **Sales teams selling to financial institutions:** complaint-management, collections-compliance, fraud and CX vendors can target companies with rising complaints.
- **Journalists, researchers, data teams and AI agents:** clean JSON with stable IDs and links.

### Why this Actor

- **Company-level analytics, not just a dump:** window vs prior window, growth %, `spike` flag with a noise floor (`minComplaints`), rank, share of all complaints, top products / sub-products / issues / sub-issues / states, timely-response rate, company responses, servicemember and older-American counts.
- **Lag-aware:** CFPB publishes a complaint only after the company responds or after 15 days, so the newest two weeks always look low. Company summaries end `lagDays` (default 14) before the latest data, so growth numbers compare like with like; complaint feeds widen the window automatically when it is thin.
- **Friendly filters:** type `Capital One`, `Wells Fargo`, `Chime`, `Credit card`, `Repossession`; names are resolved to CFPB's exact company / product / issue names (see `OUTPUT.resolution`).
- **Schedules that don't miss late arrivals:** `sinceLastRun` re-checks the last 45 days and delivers only complaints you have not received yet, so complaints CFPB publishes weeks after receipt are still caught.
- **Privacy first:** ZIP codes are cut to 3 digits (`980XX`), no consumer names exist in the data, narratives are off by default.
- **Official, keyless, fast:** the CFPB public API, no login; the default run returns 30 complaints in about 2 seconds at 512 MB.

### Quick start

1. Click **Start** with `{}`: the 30 newest published complaints.
2. Capital One and Wells Fargo credit card complaints in Texas and California: `{"companies": ["Capital One", "Wells Fargo"], "products": ["Credit card"], "states": ["TX", "CA"], "daysBack": 30, "maxItems": 200}`
3. Debt-collection complaints about debts not owed: `{"products": ["Debt collection"], "issues": ["Attempts to collect debt not owed"], "maxItems": 500}`
4. Top 50 companies by complaints, last 30 published days vs the 30 before: `{"mode": "companySummary", "maxItems": 50}`
5. Companies with complaint spikes (>= 50% growth, >= 20 complaints), fastest-growing first: `{"mode": "companySummary", "onlySpikes": true, "sortBy": "growth", "maxItems": 50}`
6. Weekly comparison for your watch list: `{"mode": "companySummary", "companies": ["Chime", "Block", "PayPal", "SoFi"], "windowDays": 7}`
7. Auto-lender spikes in vehicle loans: `{"mode": "companySummary", "products": ["Vehicle loan or lease"], "onlySpikes": true, "spikeThresholdPct": 40}`

#### Schedule tips

Daily feed of new complaints for a watch list (Apify **Schedule**, e.g. daily 14:00 UTC, after CFPB's daily refresh):

```json
{ "sinceLastRun": true, "stateKey": "watchlist-daily", "companies": ["Capital One", "Synchrony", "Discover"], "maxItems": 2000 }
```

Weekly spike alerts (each spiking company is delivered once per window):

```json
{ "mode": "companySummary", "sinceLastRun": true, "stateKey": "spikes-weekly", "spikeThresholdPct": 50, "minComplaints": 25, "maxItems": 100 }
```

Use one `stateKey` per schedule. Connect runs to Slack, email, Google Sheets, Airtable, HubSpot, Make, Zapier, n8n or webhooks with Apify integrations.

### Input

| Field | Meaning |
|---|---|
| `mode` | `complaints` (default) or `companySummary` |
| `companies` | Company names (partial, case-insensitive; each input matches up to 10 CFPB names) |
| `products` | Products or sub-products (`Credit card`, `Mortgage`, `Debt collection`, `Store credit card`...) |
| `issues` | Issues or sub-issues (`Incorrect information on your report`, `Repossession`, `Fraud or scam`...) |
| `states` | Consumer mailing-address state codes (`TX`, `CA`, `PR`...) |
| `tags` | `servicemember`, `olderAmerican` |
| `daysBack` | complaints mode window, default 7 days (auto-widened when short unless `autoExtend: false`) |
| `maxItems` | Cap per run (also caps your spend), default 30 |
| `includeNarratives` | Add `narrative` (CFPB-scrubbed consumer text) if the API supplies it; default off |
| `windowDays`, `lagDays`, `windowEnd` | companySummary window (default 30 days ending 14 days before the latest data) |
| `spikeThresholdPct`, `minComplaints` | Spike rule (default >= 50% growth and >= 20 complaints) |
| `onlySpikes`, `sortBy` | Only spiking rows; sort by `complaints`, `growth` or `change` |
| `sinceLastRun`, `stateKey` | Opt-in delta mode for schedules |

### Output

**Complaint records** (`recordType: "complaint"`): `complaintId`, `dateReceived`, `dateSentToCompany`, `daysToSendToCompany`, `company`, `product`, `subProduct`, `issue`, `subIssue`, `state`, `zip3`, `submittedVia`, `companyResponse`, `companyPublicResponse`, `responseInProgress`, `timelyResponse`, `consumerDisputed` (CFPB stopped collecting this in 2017; null for recent data), `tags`, `servicemember`, `olderAmerican`, `cfpbUrl`, `firstSeenAt`, and `narrative` only when `includeNarratives` is on.

```json
{
  "recordType": "complaint",
  "complaintId": "31385786",
  "dateReceived": "2026-10-30",
  "dateSentToCompany": "2026-10-30",
  "daysToSendToCompany": 0,
  "company": "Experian Information Solutions Inc.",
  "product": "Credit reporting or other personal consumer reports",
  "subProduct": "Credit reporting",
  "issue": "Incorrect information on your report",
  "subIssue": "Information belongs to someone else",
  "state": "WA",
  "zip3": "980XX",
  "submittedVia": "Web",
  "companyResponse": "In progress",
  "companyPublicResponse": null,
  "responseInProgress": true,
  "timelyResponse": true,
  "consumerDisputed": null,
  "tags": [],
  "servicemember": false,
  "olderAmerican": false,
  "cfpbUrl": "https://www.consumerfinance.gov/data-research/consumer-complaints/search/detail/31385786",
  "firstSeenAt": "2026-10-31T07:08:38.730Z"
}
```

**Company summary rows** (`recordType: "companySummary"`): `company`, `windowStart`, `windowEnd`, `windowDays`, `complaints`, `priorWindowStart`, `priorWindowEnd`, `priorComplaints`, `change`, `growthPct` (null when the prior window had 0), `newInWindow`, `spike`, `spikeThresholdPct`, `minComplaintsForSpike`, `complaintsPerDay`, `rankInWindow`, `shareOfAllComplaints`, `topProducts`, `topSubProducts`, `topIssues`, `topSubIssues`, `topStates` (each `[{name, complaints, share}]`), `submittedVia`, `companyResponses`, `timelyResponseRate`, `servicememberComplaints`, `olderAmericanComplaints`, `latestDateReceivedInData`, `cfpbSearchUrl`, `generatedAt`.
Real example (abridged): CREDIT ACCEPTANCE CORPORATION, 2026-09-17 to 2026-10-16: 391 complaints vs 194 (+101.5%, `spike: true`), 60% vehicle loan or lease, top issues *Managing the loan or lease* and *Repossession*, top state MI. Full examples: `sample-output.json`.

Every run also writes a summary (window, resolved filters, matching counts, latest date in data, why the run stopped) to the `OUTPUT` record. The dataset has *Complaints* and *Company summaries* table views.

### Data source, timing and fair use

- **CFPB Consumer Complaint Database** public search API (`consumerfinance.gov/data-research/consumer-complaints/search/api/v1/`), free, no key, public domain (CC0). Requests are sequential or 3 at a time, with a declared User-Agent and retries.
- CFPB refreshes the database daily. A complaint is published after the company responds or after 15 days, whichever comes first, so recent days fill in over about two weeks (credit bureaus respond almost immediately, so they dominate the newest days).
- **Complaints are not verified by the CFPB** and are not evidence of wrongdoing; volume partly reflects company size. Use `shareOfAllComplaints` and growth rather than raw counts when comparing companies.
- Narratives: the CFPB publishes scrubbed narratives only when consumers opt in; the public search API currently does not return narrative text, so `narrative` is usually null.
- Not affiliated with or endorsed by the CFPB.
- Related feeds from moment-data: [Federal Contract Awards Feed](https://apify.com/moment-data/federal-contract-awards-feed), [US Product Recalls Feed](https://apify.com/moment-data/product-recalls-feed), [SEC EDGAR Filings Feed](https://apify.com/moment-data/sec-edgar-filings-feed).

### Pricing

Pay per event: a small fee per run plus a fee per complaint or company row delivered. `maxItems` caps your spend, and runs stop cleanly at your maximum charge limit. See the Pricing tab.

### FAQ

**Why are the last few days so dominated by credit bureaus?** Publication lag: most other companies' complaints appear about 15 days after receipt. Use `daysBack` 30+ or `sinceLastRun` for complete coverage, and `companySummary` (which skips the lag by default) for trends.
**How do I find a company's exact CFPB name?** Type part of it; the run log and `OUTPUT.resolution` show what it matched.
**Can I get history?** Up to 365 days per run in complaints mode (newest first, up to 10,000 complaints scanned per run); `windowEnd` lets companySummary look at any past period.
**Is there personal data?** No names or contact details exist in the data; ZIP codes are truncated to 3 digits.

# Actor input Schema

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

complaints (default): one record per complaint, newest first. companySummary: one row per company with complaint counts in the window vs the prior window of the same length, product / issue / state mix, response stats and a spike flag.

## `companies` (type: `array`):

Company names, matched to the names CFPB uses (case-insensitive, partial names allowed, corporate suffixes ignored): e.g. Capital One, Wells Fargo, Chime, Block, Affirm, Navient. Each input can match up to 10 CFPB company names (see the run log and OUTPUT.resolution). Empty = all companies.

## `products` (type: `array`):

CFPB products or sub-products, e.g. Credit card, Mortgage, Debt collection, Checking or savings account, Student loan, Vehicle loan or lease, Money transfer, virtual currency, or money service, Store credit card. Empty = all.

## `issues` (type: `array`):

CFPB issues or sub-issues, e.g. Incorrect information on your report, Attempts to collect debt not owed, Trouble during payment process, Fraud or scam. Empty = all.

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

2-letter state codes of the consumer's mailing address (TX, CA, FL, PR...). Empty = all.

## `tags` (type: `array`):

Optional: servicemember and/or olderAmerican to keep only complaints CFPB tagged that way.

## `daysBack` (type: `integer`):

Window of days received, ending today (UTC). If it holds fewer than Max items complaints, the window is widened step by step (14, 30, 60, 120, 240, 365 days) so a run always returns data despite CFPB's publication lag. sinceLastRun always rescans at least 45 days to catch late-published complaints.

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

Cap on delivered complaints or company rows (also caps your spend). Default is small so a first run is quick and cheap.

## `includeNarratives` (type: `boolean`):

Adds a narrative field with CFPB's scrubbed consumer narrative when the API supplies one. Note: the public search API currently omits narrative text, so the field is usually null.

## `windowDays` (type: `integer`):

Length of the current window; the prior window is the same number of days immediately before it.

## `lagDays` (type: `integer`):

The current window ends this many days before the latest date received in the data, because CFPB publishes most complaints after the company responds or after 15 days. Lower values are fresher but undercount recent days.

## `windowEnd` (type: `string`):

YYYY-MM-DD. Overrides the automatic window end (latest date minus lagDays).

## `spikeThresholdPct` (type: `integer`):

A company is flagged spike: true when complaints grew by at least this percentage vs the prior window (or it had none before) and it has at least Min complaints.

## `minComplaints` (type: `integer`):

Ignore spikes at companies with fewer complaints than this in the current window (filters out noise like 1 -> 3).

## `onlySpikes` (type: `boolean`):

Deliver only rows with spike: true.

## `sortBy` (type: `string`):

Order of company rows; rows beyond Max items are dropped.

## `sinceLastRun` (type: `boolean`):

Opt-in. complaints mode: deliver only complaints not delivered before for this State key (rescans 45+ days to catch late-published ones; the first run delivers up to Max items and records the rest as seen). companySummary: deliver only spiking companies not already alerted in the last window. Default off = stateless.

## `stateKey` (type: `string`):

Name of the saved history for sinceLastRun. Use one key per schedule.

## `autoExtend` (type: `boolean`):

Turn off to get exactly the Days back window.

## Actor input object example

```json
{
  "mode": "complaints",
  "daysBack": 7,
  "maxItems": 30,
  "includeNarratives": false,
  "windowDays": 30,
  "lagDays": 14,
  "spikeThresholdPct": 50,
  "minComplaints": 20,
  "onlySpikes": false,
  "sortBy": "complaints",
  "sinceLastRun": false,
  "stateKey": "default",
  "autoExtend": true
}
```

# Actor output Schema

## `complaints` (type: `string`):

complaints mode: one record per complaint.

## `companies` (type: `string`):

companySummary mode: one row per company.

## `summary` (type: `string`):

Window, resolved filters, counts, why the run stopped.

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("moment-data/cfpb-company-complaints-feed").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("moment-data/cfpb-company-complaints-feed").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 '{}' |
apify call moment-data/cfpb-company-complaints-feed --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,moment-data/cfpb-company-complaints-feed"
        }
    }
}
```

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/WsbTiZyHk7OCjDN47/builds/hw35XIX3I5N0W2avr/openapi.json
