CFPB Complaint Intelligence — Vendor Risk & Screening avatar

CFPB Complaint Intelligence — Vendor Risk & Screening

Pricing

from $2.00 / 1,000 complaint fetcheds

Go to Apify Store
CFPB Complaint Intelligence — Vendor Risk & Screening

CFPB Complaint Intelligence — Vendor Risk & Screening

Turn 5M+ CFPB consumer complaints into decisions: screen companies pass / review / fail, score complaint-handling risk, monitor what changed since last run, benchmark cohorts, and build audit-ready due-diligence packs. Filter by company, product, state, and date. No API key.

Pricing

from $2.00 / 1,000 complaint fetcheds

Rating

0.0

(0)

Developer

Ryan Clinton

Ryan Clinton

Maintained by Community

Actor stats

0

Bookmarked

14

Total users

4

Monthly active users

6 days ago

Last modified

Categories

Share

CFPB Complaint Intelligence Platform

CFPB Complaint Intelligence Platform — screen vendors and defend every decision

Screen vendors, detect consumer risk, and defend your decisions — from 5M+ CFPB complaints

Most CFPB tools return complaints. This actor returns decisions you can defend.

  • Pass / Review / Fail vendor screening
  • Complaint Intelligence Score (0-100) + A-F grade
  • Decision evidence — exactly why each verdict landed, so you can defend every call
  • Executive summaries — paste-ready, no LLM
  • Monitoring alerts — what changed since your last run
  • Audit-ready due-diligence packs

Built for: vendor-risk teams · procurement · third-party-risk programs · compliance & AML · M&A due diligence · fintech competitive intelligence · journalists & researchers.

No API key, no LLM, no infrastructure — just deterministic, structured decisions.


Why not use the CFPB API directly?

The raw CFPB API gives you complaints:

{ "company": "ABC Bank", "issue": "Identity theft", "timely": "Yes" }

This actor gives you a decision:

{
"company": "ABC Bank",
"screeningResult": "review",
"complaintIntelligenceScore": 74,
"grade": "D",
"primaryArchetype": "Complaint Accelerator",
"decisionEvidence": {
"primaryDrivers": ["accelerating-complaints", "high-dispute-rate"],
"impactWeights": { "handling": 32, "severity": 18, "velocity": 8, "concentration": 16 }
},
"executiveSummary": { "headline": "Complaint risk increasing", "summary": "ABC Bank: Complaint Intelligence Score 74/100 (high risk, grade D), driven by accelerating-complaints and high-dispute-rate. 12% untimely and 19% disputed across 240 complaints." }
}

The CFPB API gives you data. This actor gives you risk signals you can act on — and the evidence to defend the call.


What decision are you trying to make?

Your questionUseYou get
Should I onboard this vendor?workflow: "vendor-screening"Pass/Review/Fail + Complaint Intelligence Score + decision evidence, per company
Has this vendor's risk changed?workflow: "vendor-monitoring"What changed since last run, risk events, complaint spikes
Deep due diligence on one company?workflow: "due-diligence"A board-ready pack: exec summary, score, evidence, trend, top issues
I need evidence for a review committeeworkflow: "audit-evidence"Due-diligence pack + the underlying complaint records as evidence
What's happening across an industry?workflow: "competitive-monitoring"Cohort leaderboard, cohort averages, market-level regulatory-risk signals

Pick a workflow and the actor configures the right mode for you. Power users can still drive outputMode directly (it always wins).


Vendor screening in 30 seconds

Input:

{
"workflow": "vendor-screening",
"companies": ["Company A", "Company B", "Company C"],
"maxResults": 200
}

Output (one companySummary row per company, ranked by risk):

[
{ "company": "Company A", "screeningResult": "pass", "complaintIntelligenceScore": 18, "grade": "B" },
{ "company": "Company B", "screeningResult": "review", "complaintIntelligenceScore": 52, "grade": "C" },
{ "company": "Company C", "screeningResult": "fail", "complaintIntelligenceScore": 81, "grade": "F" }
]

Plus a run summary naming the lowest-risk and highest-risk vendor, and riskEvent records for anything that spiked.


CFPB API vs this actor

CapabilityRaw CFPB APIThis actor
Complaint search & filtering
Aggregation / leaderboards
Complaint Intelligence Score + A-F grade
Pass / Review / Fail vendor screening
Decision evidence (why)
Cross-run monitoring + "what changed"
Cohort benchmarking + real product baseline
Market-level regulatory-risk signals
Executive summaries
Due-diligence + audit packs

Built on the official CFPB consumer complaint database — the largest public source of US consumer financial grievances (5M+ complaints since 2011). This actor handles pagination, rate limiting, and normalization for you, then layers the intelligence on top.


Defend every decision

Decision evidence is the difference between a score and a recommendation a compliance team can stand behind. Every screening verdict ships with the exact drivers and their weighted contribution:

{
"company": "ABC Bank",
"screeningResult": "fail",
"complaintIntelligenceScore": 81,
"grade": "F",
"recommendedAction": "escalate",
"decisionEvidence": {
"primaryDrivers": ["high-dispute-rate", "accelerating-complaints", "high-severity-mix"],
"impactWeights": { "handling": 38, "severity": 22, "concentration": 13, "velocity": 8 },
"topComponent": "handling"
}
}

When someone asks "why did you flag this vendor?", you have the answer in the record — no black box, no LLM, fully reproducible.


What changed since last run

Run with a watchlistName on a schedule and the actor tells you what moved, not just the current state:

{
"changes": [
{ "company": "Equifax", "change": "rank-up", "previousRank": 7, "currentRank": 2 },
{ "company": "Acme Lending", "change": "complaints-increased", "newComplaints": 31 }
],
"portfolio": { "portfolioRiskScore": 64, "newCriticalAlerts": 2, "portfolioTrend": "worsening" }
}

Plus riskEvent records for spikes, rapid deterioration, and market-level regulatory-risk themes.


Typical workflows

Vendor onboarding — screen 20 vendors in one run, identify the highest-risk supplier, generate an audit trail:

{ "workflow": "vendor-screening", "companies": ["Vendor A", "Vendor B", "..."] }

Quarterly vendor review — monitor a saved portfolio, detect deteriorating vendors, escalate complaint spikes:

{ "workflow": "vendor-monitoring", "portfolioName": "vendors", "watchlistName": "q-review" }

M&A due diligence — build a board-ready pack for a target with evidence and trend:

{ "workflow": "due-diligence", "company": "Acquisition Target Inc" }

Outputs designed for automation

Every decision is returned as stable, structured fields — no parsing, no prompt engineering, deterministic across runs:

{ "screeningResult": "pass", "recommendedAction": "monitor", "riskLevel": "low", "grade": "B" }

Branch on screeningResult, recommendedAction, riskLevel, or eventType directly in Zapier, Make, n8n, Dify, or an agent tool call. The enums are additive within a major version, so your rules don't break.


What you also get — vendor screening, decision evidence, change monitoring, audit-ready packs

Why use this Complaint Intelligence Platform?

Built on a CFPB consumer complaint search, but it returns decisions, not just rows:

  • No API key required -- The CFPB API is a free US government data source. No authentication, no signup, no usage limits.
  • Decisions, not data -- Every company comes back with a Complaint Intelligence Score, an A-F grade, a pass/review/fail screening verdict, decision evidence, and a plain-English executive summary.
  • Eleven output modes -- from raw records and leaderboards to monitoring, cohort benchmarking, due-diligence packs, audit packs, industry profiles, and time-series. One actor, the mode for the question you're asking.
  • Up to 10,000 records per run -- Auto-pagination handles the entire matching result set within the API's 10,000-row single-query limit; time-series and trend modes use exact per-period counts to sidestep the cap entirely.
  • Cloud scheduling -- Run on a recurring schedule with a watchlist to build company memory, detect deterioration, and surface what changed since the last run.
  • 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.

Data foundation (the table stakes)

The retrieval layer everything is built on — search by keyword, company, product, US state, and date range; sort by recency or relevance; up to 10,000 complaints per run with built-in pagination and auto-pagination; consumer narratives where disclosed; a direct CFPB URL per complaint; and a polite delay between API pages. The intelligence layer above (scoring, screening, monitoring, evidence) is what you actually run it for.


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
workflowSelectNo--Job-named entry point: vendor-screening / vendor-monitoring / due-diligence / audit-evidence / competitive-monitoring. Configures the right outputMode for you. An explicit outputMode always wins.
searchTermStringNo--Keyword search across complaint narratives and fields (e.g., "credit report", "late fee", "identity theft")
companyStringNo--Filter by a single company name (e.g., "Bank of America", "Wells Fargo", "Equifax")
companiesString[]No--Screen multiple companies in one run (records mode). One filtered query per company (maxResults applies per company), capped at 25. Overrides company when set.
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 / aggregation / compare / monitor / cohort / dueDiligence / auditPack (pack + evidence + records) / industryProfile / timeseries / trend / stateRisk
watchlistNameStringNo--Track companies across scheduled runs — each run reports newComplaintsSinceLastRun, a change flag, a persistent companyProfile (first seen / runs / all-time-high score / score history / trend) and rankChange.
portfolioNameStringNo--Save a reusable company list under a name (pass with companies to save; pass alone later to reload). Pair with watchlistName + a schedule for hands-off portfolio monitoring.
trendIntervalMonthsIntegerNo12 / 3timeseries: trailing months to chart (default 12). trend: current-period length in months (default 3); the previous equal window is compared.
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.
enableCompanySummaryBooleanNofalseAdds one company-risk-summary row per company in the result set plus a run summary, ranked by complaint-handling risk. Records mode only; not charged.
outputProfileSelectNostandardminimal (headline decision fields only), standard, or full. 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

Sample output — company risk leaderboard with intelligence score, grade, screening verdict and archetype

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
productCategoryStringProduct mapped to a stable category enum (credit-reporting, debt-collection, mortgage, credit-card, bank-account, student-loan, auto-loan, money-transfer, payday-loan, personal-loan, other)
responseTypeStringNormalized company response (closed-with-monetary-relief, closed-with-explanation, untimely, …)
reliefProvidedBooleanWhether the company provided monetary or non-monetary relief
timelyResponseBooleanWhether the company responded on time
hasNarrativeBooleanWhether the complaint carries a consumer narrative
severityFlagsString[]Stable flags: untimely-response, consumer-disputed, relief-provided, no-relief
dataCompletenessInteger0-100 share of key fields populated on this record
severityScoreInteger0-100 weighted severity of the complaint type (identity theft, foreclosure, fraud, harassment, …) — distinct from how the company handled it
severityClassStringcritical / high / moderate / low
severityFactorsString[]Which severity rules fired: identity-theft, fraud, foreclosure, repossession, debt-harassment, legal-action, …

Output fields — company summary (when enableCompanySummary is on)

One companySummary row per company in the result set, ranked by complaint-handling risk, plus one runSummary row. All scores are within-result-set signals. Complaint volume is heavily confounded by company size (large credit bureaus and banks naturally generate more complaints), so the risk score deliberately leans on response-quality rates and velocity, not raw count — and is never a cross-universe "this company is risky overall" rating.

FieldTypeDescription
kind / recordTypeString"companySummary"
companyStringCompany display name
companyKeyStringStable hash of the normalized name for cross-run joins
complaintCountIntegerComplaints for this company in the result set
complaintIntelligenceScoreIntegerSignature 0-100 holistic score (higher = more concerning): handling 50% + complaint-type severity 25% + issue concentration 15% + velocity 10%. The leaderboard ranks on this.
gradeStringA-F letter grade from the intelligence score
complaintRiskScoreIntegerComplaint-handling sub-score (untimely + dispute + low-relief + velocity) — a transparent driver of the intelligence score
signalsString[]Company-level signal tokens: accelerating-complaints, high-dispute-rate, high-severity-mix, issue-concentration, no-monetary-relief, …
decisionEvidenceObjectWhy the score is what it is — primaryDrivers[] + impactWeights (the actual point contribution of handling / severity / concentration / velocity) + topComponent
executiveSummaryObjectDeterministic, paste-ready { headline, summary } narrative — no LLM
themeExposureObjectShare of the company's complaints per regulatory theme (fraud, identity-theft, mortgage-servicing, credit-reporting, …)
primaryArchetypeStringSingle memorable label: Complaint Accelerator / Dispute Magnet / Slow Responder / High-Severity Risk / Single-Issue Concentrated / Consumer-Friendly Resolver / Standard Responder
companyProfileObject(watchlist mode) persistent memory — firstSeen, runsSeen, highestIntelligenceScore, scoreHistory[], intelligenceTrend
intelligenceTrendString(watchlist mode) improving / worsening / stable / new vs the last run
vsIndustryBaselineObject(product filter set) this company's untimely/relief rate ÷ the real product-wide rate
monetaryReliefRateNumberShare of complaints closed with monetary relief (distinct from total relief)
relativeRisk / cohortComparisonNumber / Object(cohort mode) intelligence score ÷ cohort average, and a worse/near/better-than-cohort position
previousRank / rankChangeInteger(watchlist mode) prior-run risk rank and the change since (positive = moved up the leaderboard)
riskLevelStringminimal / low / medium / high / critical
complianceRatingStringA-F letter grade (alias of grade)
screeningResultStringVendor-screening verdict: pass / review / fail
recommendedActionStringmonitor / review / escalate
confidenceStringHow much to trust the verdict given sample size: high (≥20 complaints) / medium (≥5) / low
verdictStringOne-sentence plain-English risk verdict, ready for a report or Slack message
riskFactorsString[]Codes that drove the score (high-untimely-rate, dispute-heavy, low-relief-rate, accelerating-complaints)
archetypeString[]Labels: Poor Responder, Dispute-Heavy, Consumer-Friendly Resolver, Rising Complaints, …
untimelyRate / reliefRate / disputeRateNumberResponse-quality rates (0..1)
severityScore / maxSeverityScore / criticalComplaintCountIntegerAverage & worst complaint-type severity, and count of critical-severity complaints
topIssueConcentration / concentrationRiskNumber / StringShare of the company's complaints from its single biggest issue, and the high/medium/low band — high concentration reads as a systemic weakness
trendString12-month velocity: accelerating / steady / declining / insufficient-data
totalMatchingForCompanyIntegerExact CFPB total matching the company's query (compare / companies[] mode); null on broad searches
watchlistDeltaObjectWhen watchlistName is set: { changeFlag, newComplaintsSinceLastRun, riskScoreDelta, … } vs the last run
timelineObject[]Per-year complaint counts
topProduct / topIssueStringMost common product category / issue for this company
rankInResults / percentileInResultsIntegerRisk rank and percentile within the result set

The runSummary row carries a headline + oneLine takeaway, riskDistribution, screeningDistribution, highestRiskCompany, and an exceptions[] list of the fail-screened companies with reasons. It is also mirrored to the SUMMARY key-value store key.

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

Output — monitoring & analytical modes

timeseries (one timeseries row): series[] of { period: "YYYY-MM", count } (exact monthly counts, computed via one count query per month so the 10,000-row cap never applies), plus total, velocityScore (0-100, 50 = on-average), velocityClass (spike / rising / steady / dropping), and changePercent / trend.

trend (one trend row): currentPeriodComplaints vs previousPeriodComplaints (exact counts for two equal-length windows), changePercent, trend, severity, and emergingIssues[] — issues that are new or grew ≥50% vs the previous period ({ issue, currentCount, previousCount, growthRate, trend }).

stateRisk (one stateRisk row per state): complaints, population (bundled US Census 2020), complaintsPer100k (normalized rate — far more comparable than raw counts), and rank.

compare = records mode with the company risk leaderboard forced on (see the company-summary fields above), ranked by the Complaint Intelligence Score with exact per-company totals.

monitor (needs watchlistName): emits only the companies whose complaint total changed since the last run, plus riskEvent records. Each riskEvent: { eventType, severity, company, detail, changePercent } where eventType is complaint-spike / risk-escalation / rapid-deterioration / high-severity-company / critical-screening (company-level) or regulatory-risk (market-level — a regulatory theme like identity-theft dominant across many companies, with theme + warningLevel + affectedCompanies). Paste-ready for Slack/Zapier/PagerDuty.

cohort: the company leaderboard plus a cohortStats block on the run summary (cohortAverageDisputeRate, cohortAverageIntelligenceScore, cohortLeader/cohortLaggard) and a per-company relativeRisk + cohortComparison. Averages are across the companies in your run, never a fabricated cross-industry figure.

dueDiligence (one dueDiligence row): a board-ready pack for a single company — executiveSummary (paste-ready {headline, summary}), complaintIntelligenceScore + grade + screeningResult, decisionEvidence, trendAnalysis, topIssues[], watchItems[], supportingMetrics, recommendedAction, vsIndustryBaseline, and the persistent companyProfile.

auditPack (one auditPack row + the company's complaint records): the due-diligence pack with the underlying complaint records kept in the dataset as evidence — built for "download → attach to the vendor review file."

When you run with a watchlistName, the runSummary adds a portfolio block (portfolioRiskScore, criticalAlerts, newCriticalAlerts, portfolioTrend) and a changes[] feed — the "what changed since last run" diff (new / rank-up / rank-down / complaints-increased per company) that monitoring workflows read first.

industryProfile (one industryProfile row): for a product/category — topIssues[], fastestGrowingIssues[] (new or +50% vs the previous period), earlyWarnings[] (named surge signals: identity-theft-surge, fraud-surge, … + a warningLevel), highestSeverityIssues[] (ranked by complaint-type severity), a real product-wide baseline (exact untimely + relief rates from CFPB aggregation across the whole product — not a fabricated cross-industry figure), and riskTrend.

Cohort mode also surfaces cohortStats.industrySignals[] — signals shared by enough of the run's companies to read as an industry-wide pattern (e.g. an identity-theft wave across the credit bureaus).

Honest scope: every per-company score is a within-result-set signal. The industryProfile baseline is the one true cross-company figure — and it's exact (a complaint-weighted product-wide rate from CFPB's own aggregation), labelled "product-wide", never an invented percentile. Complaint volume tracks company size, so the risk score deliberately leans on response-quality rates (untimely / dispute / relief) and velocity — never a cross-universe "this company is risky overall" or industry-percentile rating, which would need per-complaint data for every company in the industry.


Use cases

Enterprise risk & compliance (budget-owning teams)

  • Third-party / vendor risk management -- Screen vendors before onboarding (compare mode + a companies list → a pass/review/fail verdict each), then monitor them after onboarding (monitor mode on a schedule with a watchlistName), and auto-escalate any vendor whose complaint handling deteriorates (riskEvent records + rankChange).
  • Procurement due diligence -- Compare competing suppliers head-to-head, benchmark their response quality against the cohort (cohort mode), and detect worsening complaint trends before signing.
  • M&A screening -- Surface hidden consumer-risk signals before an acquisition: complaint velocity, severity mix, issue concentration, and the Complaint Intelligence Score for the target and its peers.

Analysis, monitoring & research

  • 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.

Use in Dify

Drop this actor into Dify workflows via the Apify plugin's Run Actor node. With enableCompanySummary on, each company comes back scored, classified, and screened as structured JSON — pass / review / fail plus the riskLevel and recommendedAction enums your downstream node branches on. A raw CFPB API call returns Elasticsearch hits you still have to interpret; this returns a vendor-screening decision.

  • Actor ID: ryanclinton/cfpb-consumer-complaints
  • Sample input (screen a list of banks before onboarding a vendor):
{
"outputMode": "records",
"companies": ["Wells Fargo", "Bank of America", "Equifax"],
"maxResults": 200,
"enableCompanySummary": true,
"outputProfile": "standard"
}

The companySummary records carry the routing primitives. A Dify if/else node branches on them without parsing prose:

  • screeningResult == "fail" → route to a manual-review / escalation branch (the verdict + riskFactors[] are paste-ready into a ticket or Slack message).
  • screeningResult == "review" → flag for a human; surface untimelyRate / disputeRate.
  • screeningResult == "pass" → continue the onboarding flow automatically.

You can also branch on recommendedAction (monitor / review / escalate) or gate automation on confidence == "high" so thin-sample verdicts route to a human instead of firing a downstream action. The runSummary record's headline / oneLine and exceptions[] are ready to drop straight into an exec email or alert. Filter the dataset by recordType (companySummary vs record vs runSummary) so each Dify branch reads only the rows it needs.


How it works

Intelligence stack — from the raw CFPB complaint database through enrichment, scoring and the decision layer to defensible decisions

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.