CFPB Complaint Search — By Company, Product & State avatar

CFPB Complaint Search — By Company, Product & State

Pricing

from $2.00 / 1,000 complaint fetcheds

Go to Apify Store
CFPB Complaint Search — By Company, Product & State

CFPB Complaint Search — By Company, Product & State

Search the CFPB consumer complaint database with 5M+ complaints. Filter by company, product, state, date range, and keyword. Extract complaint details, company responses, and consumer narratives. Free US government data, no API key required.

Pricing

from $2.00 / 1,000 complaint fetcheds

Rating

0.0

(0)

Developer

Ryan Clinton

Ryan Clinton

Maintained by Community

Actor stats

0

Bookmarked

10

Total users

4

Monthly active users

4 days ago

Last modified

Share

CFPB Consumer Complaint Search

Search and extract consumer complaint data from the Consumer Financial Protection Bureau (CFPB) database. Access over 5 million complaints filed against financial companies in the United States since 2011, with filtering by keyword, company, product type, state, and date range. Two output modes: records for individual complaints, aggregation for top-N leaderboards (most-complained-about companies, top issues, geographic distribution).

The CFPB complaint database is the largest publicly available source of consumer grievances related to financial products and services in the US, maintained by a federal government agency. Essential for compliance screening, AML due diligence, KYC risk assessment, and regulatory monitoring. This actor connects to the official CFPB public API and transforms raw Elasticsearch-style responses into clean, structured JSON records -- ready for analysis, compliance workflows, or integration into data pipelines.

Whether you are a compliance officer tracking complaints against a specific bank, a data journalist investigating patterns in consumer harm, or a fintech company benchmarking competitor reputation, this actor gives you programmatic access to CFPB data without managing API pagination, rate limiting, or data normalization yourself.


  • No API key required -- The CFPB API is a free US government data source. No authentication, no signup, no usage limits.
  • Clean structured output -- Raw CFPB responses use nested Elasticsearch formatting with inconsistent field names. This actor normalizes every record into a flat, consistent JSON schema.
  • Two output modes -- Records mode returns one row per complaint. Aggregation mode returns top-N count buckets so you can answer "which companies received the most complaints in 2024?" in one call instead of paginating through millions of records.
  • Up to 10,000 records per run -- Bumped from the previous 500-row cap. Auto-pagination handles the entire matching result set within Elasticsearch's 10,000-row single-query limit.
  • Cloud scheduling -- Run searches on a recurring schedule using Apify's built-in scheduler to monitor new complaints daily, weekly, or at any interval.
  • No infrastructure needed -- Runs entirely on Apify's cloud. No servers, no Docker setup, no dependencies to install.
  • Direct complaint links -- Every record-mode result includes a generated URL linking directly to the complaint detail page on the CFPB website.

Key features

  • Search by keyword across complaint narratives and all indexed fields
  • Filter by company name (exact match -- e.g., "Bank of America", "Equifax")
  • Filter by financial product type: credit reporting, debt collection, mortgages, credit cards, student loans, and 5 more categories
  • Filter by US state using standard two-letter codes (CA, NY, TX, etc.)
  • Filter by date range to isolate complaints within a specific time window
  • Sort results by newest first, oldest first, most relevant, or least relevant
  • Retrieve up to 10,000 complaints per run with built-in pagination (100 per page)
  • Aggregation mode — group complaints by company, product, issue, sub-issue, state, response type, submission channel, tags, or timely-response flag. Returns top-N count buckets with rank, count, and share of total.
  • Auto-pagination flag — fetch every matching complaint up to the 10,000 cap in one run
  • Consumer narratives included when the consumer opted in to public disclosure
  • Direct CFPB URL generated for each complaint record
  • 200ms delay between API pages to respect the government server

How to use

Apify Console

  1. Go to the CFPB Consumer Complaint Search actor page on Apify.
  2. Click Start to open the input configuration.
  3. Enter a search term, company name, or select a product type. You can combine multiple filters.
  4. Optionally set a date range and state to narrow results.
  5. Choose your sort order and maximum number of results.
  6. Click Start to run the actor.
  7. When finished, download results from the Dataset tab in JSON, CSV, Excel, or other formats.

Python

from apify_client import ApifyClient
client = ApifyClient("YOUR_API_TOKEN")
run = client.actor("ryanclinton/cfpb-consumer-complaints").call(run_input={
"searchTerm": "unauthorized charges",
"company": "Wells Fargo",
"product": "Checking or savings account",
"state": "CA",
"dateFrom": "2024-01-01",
"dateTo": "2024-12-31",
"sortBy": "created_date_desc",
"maxResults": 100,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(f"{item['complaintId']} | {item['company']} | {item['issue']}")

JavaScript

import { ApifyClient } from "apify-client";
const client = new ApifyClient({ token: "YOUR_API_TOKEN" });
const run = await client.actor("ryanclinton/cfpb-consumer-complaints").call({
searchTerm: "identity theft",
company: "EQUIFAX, INC.",
sortBy: "created_date_desc",
maxResults: 50,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(`Found ${items.length} complaints`);
items.forEach((item) => console.log(`${item.complaintId}: ${item.issue}`));

Input parameters

ParameterTypeRequiredDefaultDescription
searchTermStringNo--Keyword search across complaint narratives and fields (e.g., "credit report", "late fee", "identity theft")
companyStringNo--Filter by company name (e.g., "Bank of America", "Wells Fargo", "Equifax")
productSelectNoAnyFinancial product type: credit reporting, debt collection, mortgage, credit card, checking/savings, student loan, vehicle loan, money transfer, payday loan, personal loan
stateStringNo--US state code, automatically uppercased (e.g., "CA", "NY", "TX")
dateFromStringNo--Start date for complaints received (YYYY-MM-DD format)
dateToStringNo--End date for complaints received (YYYY-MM-DD format)
sortBySelectNocreated_date_descSort order: Newest first, Oldest first, Most relevant, Least relevant. Records mode only.
maxResultsIntegerNo50Maximum complaints to return (1--10000). In aggregation mode, caps how many buckets are emitted.
outputModeSelectNorecordsrecords (one row per complaint) or aggregation (top-N count buckets)
aggregateBySelectNocompanyWhen outputMode=aggregation: company, product, sub_product, issue, sub_issue, state, company_response, submitted_via, tags, or timely
autoPaginateBooleanNofalseWhen true and total matching > maxResults, fetch every matching complaint up to the 10,000 single-query cap. Records mode only.

Example input — records mode (JSON)

{
"outputMode": "records",
"searchTerm": "credit report",
"company": "EQUIFAX, INC.",
"product": "Credit reporting, credit repair services, or other personal consumer reports",
"state": "FL",
"dateFrom": "2024-06-01",
"dateTo": "2024-12-31",
"sortBy": "created_date_desc",
"maxResults": 100
}

Example input — aggregation mode (top companies in 2024)

{
"outputMode": "aggregation",
"aggregateBy": "company",
"dateFrom": "2024-01-01",
"dateTo": "2024-12-31",
"maxResults": 25
}

Tips: Combine multiple filters for precise results. Use date ranges for trend analysis. When using a keyword search in records mode, try sorting by "Most relevant first" for best matches. For "top N" leaderboard questions over millions of complaints, use aggregation mode — one HTTP call instead of thousands. If no filters are set, the actor returns the most recent complaints (records mode) or the global top buckets (aggregation mode).


Output

Every row carries a kind discriminator: "record" for individual complaints, "aggregation" for count buckets. Filter kind === "aggregation" downstream to isolate leaderboard rows.

Example output — records mode (JSON)

{
"kind": "record",
"complaintId": "8234561",
"dateReceived": "2024-11-15",
"dateSentToCompany": "2024-11-15",
"product": "Credit reporting, credit repair services, or other personal consumer reports",
"subProduct": "Credit reporting",
"issue": "Incorrect information on your report",
"subIssue": "Information belongs to someone else",
"company": "EQUIFAX, INC.",
"companyResponse": "Closed with explanation",
"companyPublicResponse": "Company has responded to the consumer and the CFPB and chooses not to provide a public response",
"state": "FL",
"zipCode": "331XX",
"narrative": "I discovered several accounts on my Equifax credit report that do not belong to me. I have filed disputes multiple times but the inaccurate information remains.",
"consumerDisputed": "N/A",
"timely": "Yes",
"submittedVia": "Web",
"cfpbUrl": "https://www.consumerfinance.gov/data-research/consumer-complaints/search/detail/8234561",
"extractedAt": "2025-06-10T14:32:08.123Z"
}

Example output — aggregation mode (JSON)

Top companies by complaint count for 2024 (aggregateBy: "company", dateFrom: "2024-01-01", dateTo: "2024-12-31"):

[
{ "kind": "aggregation", "aggregateBy": "company", "rank": 1, "term": "TRANSUNION INTERMEDIATE HOLDINGS, INC.", "count": 790668, "share": 0.2891, "totalMatching": 2734293, "queryFilters": { "searchTerm": null, "company": null, "product": null, "state": null, "dateFrom": "2024-01-01", "dateTo": "2024-12-31" }, "extractedAt": "2026-05-08T10:00:00.000Z" },
{ "kind": "aggregation", "aggregateBy": "company", "rank": 2, "term": "EXPERIAN INFORMATION SOLUTIONS INC.", "count": 754851, "share": 0.2761, "totalMatching": 2734293, "queryFilters": { "searchTerm": null, "company": null, "product": null, "state": null, "dateFrom": "2024-01-01", "dateTo": "2024-12-31" }, "extractedAt": "2026-05-08T10:00:00.000Z" },
{ "kind": "aggregation", "aggregateBy": "company", "rank": 3, "term": "EQUIFAX, INC.", "count": 752722, "share": 0.2753, "totalMatching": 2734293, "queryFilters": { "searchTerm": null, "company": null, "product": null, "state": null, "dateFrom": "2024-01-01", "dateTo": "2024-12-31" }, "extractedAt": "2026-05-08T10:00:00.000Z" }
]

Output fields — records mode

FieldTypeDescription
kindStringAlways "record" in records mode
complaintIdStringUnique CFPB complaint identifier
dateReceivedStringDate the CFPB received the complaint (YYYY-MM-DD)
dateSentToCompanyStringDate the complaint was forwarded to the company
productStringFinancial product or service category
subProductStringMore specific product subcategory
issueStringPrimary issue described in the complaint
subIssueStringMore specific issue detail
companyStringName of the company the complaint is against
companyResponseStringHow the company responded (e.g., "Closed with explanation", "Closed with monetary relief")
companyPublicResponseStringThe company's optional public-facing response text
stateStringTwo-letter US state code where the consumer is located
zipCodeStringConsumer's ZIP code (may be partially redacted)
narrativeString/nullConsumer's written description of the complaint, or null if not provided or consent not given
consumerDisputedStringWhether the consumer disputed the company's response
timelyStringWhether the company responded in a timely manner ("Yes" or "No")
submittedViaStringSubmission channel (Web, Phone, Referral, Postal mail, Fax, Email)
cfpbUrlStringDirect link to the complaint on the CFPB website
extractedAtStringISO 8601 timestamp of when the data was extracted

Output fields — aggregation mode

FieldTypeDescription
kindStringAlways "aggregation" in aggregation mode
aggregateByStringField used for grouping (e.g., "company", "product", "state")
rankInteger1-based rank within the result set (1 = largest count)
termStringThe bucket label (e.g., "EQUIFAX, INC.", "Mortgage", "CA")
countIntegerNumber of complaints in this bucket
shareNumbercount / totalMatching — fraction of all matching complaints in this bucket (0..1)
totalMatchingIntegerTotal complaints matching the query filters across all buckets
queryFiltersObjectEcho of the filters that produced this aggregation, for traceability
extractedAtStringISO 8601 timestamp of when the aggregation was computed

Use cases

  • Most-complained-about leaderboards (aggregation mode) -- "Top 25 companies by complaint count in 2024", "Top 10 issues for credit cards in CA", "State-by-state complaint distribution for mortgages". One call. No raw-record paging.
  • Compliance monitoring -- Track complaints filed against your own institution or competitors on a daily or weekly schedule to catch emerging issues early.
  • Due diligence -- Before partnering with, acquiring, or investing in a financial company, review their complaint history for red flags.
  • Investigative journalism -- Analyze complaint trends by product type, geography, or time period to uncover systemic consumer harm patterns.
  • Legal research -- Find complaints related to specific issues like identity theft, unauthorized charges, predatory lending, or discriminatory practices.
  • Market intelligence -- Identify where consumers are most dissatisfied to spot product improvement or market entry opportunities.
  • Regulatory risk assessment -- Monitor complaint volumes and company response patterns as leading indicators of potential regulatory action.
  • Academic research -- Build datasets for studying consumer finance behavior, complaint resolution effectiveness, or financial inclusion topics.
  • Brand reputation tracking -- Track how a company's complaint volume and resolution quality changes over time relative to industry peers.
  • Geographic analysis -- Compare complaint patterns across states to identify regional concentrations of specific financial product issues. Aggregation mode with aggregateBy: "state" returns the full distribution in one call.
  • Customer experience benchmarking -- Compare timeliness and resolution types across companies in the same product category. Use aggregateBy: "company_response" or aggregateBy: "timely" for cohort-level metrics.

API & integration

Python

from apify_client import ApifyClient
client = ApifyClient("YOUR_API_TOKEN")
run = client.actor("OuMDkYU3IROUS0AEj").call(run_input={
"company": "Bank of America",
"product": "Mortgage",
"dateFrom": "2024-01-01",
"maxResults": 200,
})
dataset = client.dataset(run["defaultDatasetId"])
for item in dataset.iterate_items():
print(f"{item['dateReceived']} - {item['issue']} ({item['companyResponse']})")

JavaScript

import { ApifyClient } from "apify-client";
const client = new ApifyClient({ token: "YOUR_API_TOKEN" });
const run = await client.actor("OuMDkYU3IROUS0AEj").call({
searchTerm: "late fee",
product: "Credit card or prepaid card",
state: "NY",
maxResults: 75,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(JSON.stringify(items, null, 2));

cURL

# Start the actor run
curl -X POST "https://api.apify.com/v2/acts/OuMDkYU3IROUS0AEj/runs?token=YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"searchTerm": "debt collection harassment",
"state": "TX",
"sortBy": "created_date_desc",
"maxResults": 50
}'
# Fetch results from the dataset (use defaultDatasetId from the run response)
curl "https://api.apify.com/v2/datasets/DATASET_ID/items?token=YOUR_API_TOKEN&format=json"

Platform integrations

  • Zapier -- Trigger workflows when new complaint data is collected. Push to Google Sheets, Slack, email, or CRMs.
  • Make (Integromat) -- Build multi-step automations combining CFPB data with other sources.
  • Google Sheets -- Export results directly to a spreadsheet for collaborative analysis.
  • Webhooks -- Receive HTTP callbacks when actor runs complete to trigger downstream processing.
  • Apify Dataset API -- Access results in JSON, CSV, XML, Excel, HTML, or RSS formats.

How it works

Records mode

  1. The actor reads your input configuration (search term, company, product, state, date range, sort order, max results, autoPaginate flag).
  2. It constructs a query URL for the CFPB Consumer Complaint API with pagination parameters (size=100, frm=0, no_aggs=true).
  3. The actor sends an HTTP GET request to the CFPB API endpoint.
  4. The Elasticsearch-style response (hits.hits) is parsed and each complaint record is transformed from the raw _source format into a clean flat JSON object.
  5. Transformed records are pushed to the Apify dataset.
  6. If more results are needed, the actor increments the offset and fetches the next page after a 200ms delay.
  7. When autoPaginate=true and the total matching count exceeds maxResults, the actor extends the run to fetch every matching record up to the 10,000 single-query cap.
  8. Steps 3--6 repeat until the requested count is collected or no more results are available.

Aggregation mode

  1. The actor reads your filters and the aggregateBy field selection.
  2. It constructs a single query URL with size=0&no_aggs=false&field=all.
  3. CFPB returns the bucket counts for every aggregatable field in one response.
  4. The actor extracts the buckets for the chosen aggregateBy field, ranks them by count (largest first), computes share = count / totalMatching, and emits one row per bucket up to maxResults.
  5. The result is a ready-to-graph leaderboard — no client-side counting required.
CFPB Consumer Complaint Search Pipeline
Input Config CFPB API Transform Apify Dataset
+------------+ +-----------------+ +------------------+ +---------------+
| outputMode | | records mode: | | hits -> flat JSON | | kind=record |
| aggregateBy|--->| size=100&no_aggs|--->| + cfpbUrl |--->| complaintId |
| searchTerm | | =true&frm=offset| | + extractedAt | | company |
| company | | | | | | issue,... |
| product | +-----------------+ +------------------+ +---------------+
| state |
| dateFrom | +-----------------+ +------------------+ +---------------+
| dateTo | | aggregation | | aggregations[X] | | kind=aggreg. |
| sortBy |--->| mode: |--->| .buckets -> |--->| rank, term, |
| maxResults | | size=0&no_aggs= | | rank+share+count | | count, share, |
| autoPagin. | | false&field=all | | | | totalMatching |
+------------+ +-----------------+ +------------------+ +---------------+

Performance & cost

ScenarioModeResultsApprox. Run TimeMemory
Quick lookuprecords253--5 seconds256 MB
Default runrecords505--10 seconds256 MB
Medium batchrecords20015--20 seconds256 MB
Large batchrecords1,00030--60 seconds256 MB
Full single-queryrecords10,0004--6 minutes256 MB
Top-25 leaderboardaggregation25 buckets2--4 seconds256 MB
Full distributionaggregationup to 10,000 buckets2--4 seconds256 MB

Pricing: $0.002 per row emitted (records or aggregation buckets), pay-per-event. A 25-bucket leaderboard run costs ~$0.05; a 10,000-record full-corpus pull costs ~$20. There are no external API costs — the CFPB database is a free US government resource.


Limitations

  • 10,000 records per run (records mode) -- The CFPB API enforces an Elasticsearch single-query limit of 10,000 hits. For full-corpus analysis beyond that, switch to aggregation mode (returns counts over the entire matching set, not capped at 10,000) or split records-mode queries by date range.
  • Aggregation mode is per-query -- Each aggregation call returns the buckets for one chosen field across all matching complaints. To group by multiple fields (e.g., company × product), run aggregation once per dimension and join the results downstream.
  • No ZIP code filtering -- The CFPB API does not support filtering by ZIP code directly. Filter by state, then post-process using the zipCode field in the output.
  • Narrative availability -- The narrative field is only populated when the consumer opted in to public disclosure. Many complaints will have null for this field.
  • 15-day publication delay -- Complaints typically appear in the CFPB database approximately 15 days after being sent to the company, to allow time for the company to respond.
  • Company name matching -- Company names must match the CFPB's canonical name format (e.g., "EQUIFAX, INC." not just "Equifax"). Partial matches may not return expected results.
  • No real-time data -- The database is updated daily by the CFPB, not in real time. There may be a short lag between updates.
  • US complaints only -- The CFPB database covers only complaints filed by US consumers against financial companies operating in the United States.

Responsible use

  • Public data only -- This actor accesses a publicly available US government database. All complaint records are published by the CFPB with consumer consent considerations already applied.
  • Respectful access -- The actor includes a 200ms delay between API pages and uses no_aggs=true to minimize server load on the government endpoint.
  • No personal identification -- While complaints include state and partial ZIP codes, they do not contain personally identifiable information about the consumers who filed them.
  • Fair interpretation -- A high volume of complaints does not necessarily indicate wrongdoing. Larger companies naturally receive more complaints. Always normalize by company size or customer base when drawing conclusions.
  • Comply with terms -- Users should review the CFPB data terms and ensure their use aligns with applicable regulations and ethical standards.

FAQ

Do I need a CFPB API key to use this actor? No. The CFPB consumer complaint database is a free, public US government resource. This actor accesses it without any authentication or API key.

How current is the complaint data? The CFPB updates its database daily. Complaints typically appear approximately 15 days after being sent to the company, giving the company time to respond before publication.

Can I get more than 10,000 results per run? The CFPB API enforces a 10,000-record cap on any single query (an Elasticsearch default). To go beyond, you have two options: (1) split records-mode runs by date range and combine the datasets, or (2) use aggregation mode, which returns count buckets computed over the entire matching set without the 10,000-record cap.

What's the difference between records mode and aggregation mode? Records mode returns one row per complaint (the full detail — company, issue, narrative, etc.). Aggregation mode returns top-N count buckets — e.g. "TransUnion: 790,668 complaints, 28.9% of all 2024 complaints." Use records when you need individual complaint details; use aggregation when you need leaderboards, distributions, or share-of-complaints metrics.

What does the autoPaginate flag do? By default the actor stops at maxResults. With autoPaginate=true, when the total matching count exceeds maxResults, the actor extends the run to fetch every matching complaint up to the 10,000 cap. Useful when you want "all matches for this query" without knowing the total in advance.

What does the narrative field contain? When consumers submit complaints, they can include a written description of what happened. If the consumer consents to public disclosure, this text appears in the narrative field. Otherwise it will be null.

Can I search for complaints from a specific ZIP code? The CFPB API does not support direct ZIP code filtering. Filter by state using the state parameter, then filter the output by zipCode in your post-processing.

How far back does the data go? The CFPB complaint database includes records from 2011 to the present, covering over 5 million complaints across all financial product categories.

What product categories are available? The actor supports 10 product filters: Credit reporting/repair, Debt collection, Mortgage, Credit card/prepaid card, Checking/savings account, Student loan, Vehicle loan/lease, Money transfer/virtual currency, Payday/title/personal loan, and Personal loan.

How are company names matched? The company parameter filters by the CFPB's canonical company name. For best results, use the official name as it appears in CFPB records (e.g., "EQUIFAX, INC." rather than "Equifax"). You can also try the searchTerm field for more flexible matching.

Can I schedule this actor to run automatically? Yes. Use Apify's built-in scheduler to run the actor on any cadence -- daily, weekly, or custom cron expressions. Combine with webhooks or integrations to get notified when new data is available.

What does the timely field mean? The timely field indicates whether the company responded to the complaint within the CFPB's expected timeframe (typically 15 days). A value of "Yes" means the response was on time.

Can I export results as CSV or Excel? Yes. Apify datasets support export in JSON, CSV, Excel (XLSX), XML, HTML, and RSS formats. Use the Dataset tab in the console or the Dataset API endpoint with a format parameter.

Is this actor suitable for large-scale research? For datasets up to 10,000 records, a single records-mode run is sufficient. For full-corpus research questions ("what's the complaint distribution across the 2.7 million 2024 complaints?"), use aggregation mode — one call returns counts across the entire matching set. For raw-record needs above 10,000, segment by date range and merge.


ActorDescription
FDIC Bank Data SearchLook up detailed information about FDIC-insured banks and financial institutions. Correlate complaint volumes with bank size, assets, or regulatory status.
SEC EDGAR Filing AnalyzerAnalyze SEC filings for publicly traded financial companies. Cross-reference CFPB complaint trends with financial disclosures and risk factors.
OFAC Sanctions SearchCheck whether companies or individuals appearing in complaints are on the OFAC sanctions list for enhanced due diligence.
SEC Insider TradingTrack insider trading activity at financial companies. Compare insider selling patterns with spikes in consumer complaints.
EDGAR Filing SearchSearch SEC EDGAR filings by company, form type, or date range. Build a complete regulatory picture alongside CFPB complaint data.
Congressional Stock Trade TrackerMonitor stock trades by members of Congress. Investigate whether legislative activity correlates with changes in complaint patterns for regulated industries.