California Data Broker Registry Monitor — CPPA Delete Act Delta
Pricing
from $5.50 / 1,000 data broker registry rows
California Data Broker Registry Monitor — CPPA Delete Act Delta
California data broker registry API (CPPA / Delete Act): every registered data broker with 2026 disclosure flags (GenAI, foreign actor, minors, geolocation, biometric), DSAR metrics, first-registered year, new/lapsed/renamed/changed delta and is-this-company-registered verification.
Pricing
from $5.50 / 1,000 data broker registry rows
Rating
0.0
(0)
Developer
Kyle Maloney
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
4 days ago
Last modified
Categories
Share
California Data Broker Registry Monitor — CPPA Delete Act delta, disclosure flags, registration check
California data broker registry API. Reads the California Privacy Protection Agency's official Data Broker Registry export (cppa.ca.gov/data_broker_registry/registry.csv, ~600 registrants, 77 columns) and turns it into three things a privacy-compliance or adtech due-diligence team actually uses:
registry— every registered data broker with its 2026 disclosure flags normalised to true/false/null (collects minors' data, precise geolocation, biometric, reproductive-health, citizenship, union, sexual-orientation, gender-identity, government IDs, account logins; sold or shared to a GenAI developer, a foreign actor, the federal government, other states, law enforcement; FCRA / GLBA / IIPPA / CMIA / HIPAA carve-outs), the 2024 DSAR metrics (requests to delete / know / opt out / limit — received, complied, denied, response days) as numbers, and first-registered year / date joined from CPPA's 2024 and 2025 exports and the legacy OAG 2020-2023 registry.delta— only what changed: new, lapsed, renamed (same website domain re-registered under a new name — 35 such pairs between the 2025 and 2026 filings) and changed registrants (a disclosure flag flipped, a website / state / city / contact moved), withchanged_fieldsbefore/after. The first run is a real delta against CPPA's own 2025 export, not an inventory dump; later runs compare against a named cross-run baseline.verify— passnames[]and get a three-valuedis_registeredper company:true(exact normalised name or DBA match),false(no match and no candidate),null(fuzzy candidates — review, withevidencescores). A name match is never upgraded to a legal conclusion.
Who it is for
- Privacy-compliance vendors and privacy counsel (DSAR/DROP tooling, CCPA programs): a new registrant is a lead with a legal clock; a lapsed one is a compliance question; a flag flip on an existing customer is a contract conversation.
- Adtech / martech due diligence and vendor risk: "does this partner sell to GenAI developers or foreign actors, does it hold biometric or minors' data, and how many deletion requests did it deny?"
- Journalists, researchers, policy teams tracking the Delete Act cohort year over year.
- Agents / MCP clients that need "is company X a registered California data broker?" as a tool call.
The forcing calendar this actor is built around
- Annual registration is due January 31 (Cal. Civ. Code § 1798.99.82). Every row carries
next_registration_deadlineanddays_to_next_registration_deadline. - DROP (Delete Request and Opt-out Platform): registered brokers' obligation to process deletion requests within 45 days took effect 2026-08-01 (
drop_deletion_obligation_effective). - Failure to register: $200 per day administrative fine plus fees (
unregistered_penalty_usd_per_day; CPPA enforcement advisory, 2025-12-17).
Example input
{ "mode": "registry", "flags": ["sold_to_genai_developer"], "maxResults": 100 }
{ "mode": "delta", "eventTypes": ["new", "renamed"], "maxResults": 200 }
{ "mode": "verify", "names": ["Acxiom", "LexisNexis", "Oracle America"], "maxResults": 10 }
Filters (flags, nameQuery, websiteQuery, state, country) apply in registry and delta mode. state accepts CA or California — CPPA stores both spellings and this actor normalises them. flags is an AND across the listed keys.
What a row means — and what it never claims
true/false/nullon every flag is a contract.true= the broker filed Yes,false= filed No,null= the cell is blank (not answered). Counts over flags (sensitive_data_flag_count,sold_or_shared_flag_count,regulated_carveout_count) arenullwhen any component is blank — never a smaller number.- DSAR metrics: blank is
null, not 0. A broker that reported nothing is distinguishable from one that received zero requests. The year the metrics describe is read from CPPA's own column headers (dsar_metrics_year, currently 2024), never assumed. - Registration history is cross-file, with its basis on the row.
first_registered_basistells you whether the year came from a dated record (OAGDate Added2020-2023, CPPA 2024Completion time), an undated listing (2025 export), or only the current file.days_since_first_registrationexists only when a real date does. If a prior-year file could not be read this run, itsin_registry_*field isnull(not checked) andhistory_statusreadspartial— never a false "was not registered". is_registered: falseis a checked negative against the full, gate-verified registry.nullmeans there are fuzzy candidates you should look at — theevidencearray carries up to five with similarity scores.- Delta events are classified once per registrant. A name that disappears while its website domain re-registers under a new name is
renamed(withprevious_broker_names), not alapsed+newpair that would bill you twice for a non-event. DSAR metrics are deliberately not change-tracked (they change every filing year by definition); disclosure flags, website domain, state, city and contact email are.
Drift gate — runs before any billable row
Every run downloads the full export and checks it against what this actor was built on (2026-09-26): the header contract (77 named columns resolved by normalised-substring rules that survive CPPA's curly apostrophes, non-breaking hyphens and wording edits — a renamed or dropped required column fails the run), a row-count floor (≥400 registrants), row width, the closed Yes/No vocabulary on all 20 flags, numeric DSAR cells, a positive canary (at least 2 of Acxiom / Experian Information Solutions / LiveRamp present), a negative control, plus corroborating checks (name uniqueness, state populated, Last-Modified freshness ≤400 days, DSAR year readable). A load-bearing failure ends the run as FAILED with 0 rows and 0 billed and the reason in the status message. A corroborating failure is disclosed as drift_gate_status: verified_degraded and the run proceeds. The freshness headers CPPA served (source_last_modified, source_etag) ride on every row.
Traps in the source this actor handles for you
- 62 of 603 rows carry multi-line quoted comment fields — a naive line split reads ~175 "rows". RFC-4180 parsing throughout; a truncated download (unterminated quote) is refused, never parsed as a short registry.
- UTF-8 BOM, curly apostrophes and U+2011 non-breaking hyphens in the header text;
CAvsCalifornia(and 90+ other spellings, foreign regions included) in the state column; blank-vs-0 DSAR cells; the 2025 export has an internal notes row above its header. - Company names change spelling between years ("Adept ID, Inc." → "AdeptID, Inc."); matching keys are case/punctuation/suffix-insensitive and rename detection uses the website domain.
Pricing
Pay per result: $0.01 per row at the FREE tier (paid plans are discounted 20-45%; see the pricing tab). The full registry is ~600 rows ≈ $6.00; the prefilled 100-row run ≈ $1.00; a delta run costs only what changed (a scheduled run on an unchanged registry emits 0 rows and bills nothing); a verify run costs one row per name. A run that cannot answer (registry unreachable, header contract broken, drift) fails and bills nothing.
Use from an AI agent: quickstart
The smallest input that returns a real answer. Verified live on 2026-10-06: the run SUCCEEDED in about 9 seconds and returned one verdict row.
{"mode": "verify","names": ["Acxiom"]}
Call it through the hosted MCP server (https://mcp.apify.com?tools=malonestar/ca-data-broker-registry-delta) or straight over HTTP:
POST https://api.apify.com/v2/acts/malonestar~ca-data-broker-registry-delta/run-sync-get-dataset-itemsAuthorization: Bearer YOUR_APIFY_TOKENContent-Type: application/json
with the JSON above as the body. The response is a JSON array of dataset rows.
What comes back: in verify mode, one row per name; in registry mode, one row per registrant; in delta mode, one row per change event. Abbreviated row from a live run (the full row has 138 fields, all described in the output schema):
{"broker_name": "Acxiom LLC","website": "www.acxiom.com","contact_email": "askprivacy@acxiom.com","state_raw": "AR","collects_precise_geolocation": true,"dsar_delete_received": 58416,"dsar_delete_denied": 918}
Read before you conclude anything: is_registered (three-valued: a fuzzy candidate is null, never true), drift_gate_status and run_complete.
Input notes for agents
modeis required:registry,deltaorverify.verifyneedsnames.deltakeeps its baseline in a named key-value store, so a weekly schedule returns only new, lapsed, renamed or changed registrants.
Cost: $0.0100 per row at the Free-tier list price (paid plans get a discount), so the example above costs about $0.010. A run that cannot answer fails and bills no rows.
Schedule a weekly feed
Run it on a schedule and receive only what changed. Delta mode keeps the full registry as its baseline in a named key-value store in your own Apify account (the first run is seeded from CPPA's own prior-year export, so it is already a real delta). Every later run emits only registrants that are new, lapsed, renamed or changed; filters apply to the events, never to the baseline.
Input for the scheduled run:
{"mode": "delta","maxResults": 500}
Apify Console: save this input as a task, then add a weekly Schedule to the task.
n8n (free template): we keep a ready-made workflow, growth/n8n-templates/ca-data-broker-registry-delta.json: a weekly Schedule trigger, an HTTP Request node calling run-sync-get-dataset-items with the input above, a Code node that counts the returned rows, and an IF node that only continues when there is at least one new row, ending in disabled Email and Slack placeholder nodes you point at your own inbox or channel. It uses core n8n nodes only (no community node) and an HTTP Header Auth credential (Authorization: Bearer YOUR_APIFY_TOKEN). Ask for it through an Issue on this page and we will send the file.
Use as an MCP tool
Call it from any MCP client through https://mcp.apify.com with malonestar/ca-data-broker-registry-delta. The verify mode is the tool shape: { "mode": "verify", "names": ["<company>"] } → one row per name with is_registered and evidence. Billing is identical to a Console run.
Output fields
Every row carries every field below; null means not published by the broker / not applicable to the mode / not checked this run.
| Field | Type | Meaning (null = not published / not checked) |
|---|---|---|
broker_name | string | Registered legal name of the data broker exactly as filed with the CPPA. |
dba | string | Doing-business-as name(s), if the broker filed any. |
website | string | Primary website as filed (scheme and www prefix vary; see website_domain). |
contact_email | string | Primary privacy/contact email address filed with the registration. |
phone | string | Primary phone number (optional question on the CPPA form). |
street_address | string | Primary street address as filed. |
city | string | City as filed. |
state_raw | string | State/region exactly as filed ("CA" and "California" both occur; foreign regions appear here too). |
zip | string | Postal code as filed. |
country | string | Country as filed (upper-case in the CPPA export, e.g. UNITED STATES). |
privacy_rights_url | string | URL the broker filed for how California consumers exercise their CCPA rights. |
collects_minors | boolean | Broker discloses it collects personal information of minors. true = filed Yes, false = filed No, null = left blank (not answered). |
collects_account_logins | boolean | Broker collects consumers' account logins or numbers with security codes granting access to third-party accounts. true = filed Yes, false = filed No, null = left blank (not answered). |
collects_government_ids | boolean | Broker collects consumers' government-issued identification numbers. true = filed Yes, false = filed No, null = left blank (not answered). |
collects_citizenship_data | boolean | Broker collects consumers' citizenship data, including immigration status. true = filed Yes, false = filed No, null = left blank (not answered). |
collects_union_membership | boolean | Broker collects consumers' union membership status. true = filed Yes, false = filed No, null = left blank (not answered). |
collects_sexual_orientation | boolean | Broker collects consumers' sexual orientation status. true = filed Yes, false = filed No, null = left blank (not answered). |
collects_gender_identity | boolean | Broker collects consumers' gender identity and gender expression data. true = filed Yes, false = filed No, null = left blank (not answered). |
collects_biometric | boolean | Broker collects consumers' biometric data. true = filed Yes, false = filed No, null = left blank (not answered). |
collects_precise_geolocation | boolean | Broker collects consumers' precise geolocation. true = filed Yes, false = filed No, null = left blank (not answered). |
collects_reproductive_health | boolean | Broker collects consumers' reproductive health care data. true = filed Yes, false = filed No, null = left blank (not answered). |
sold_to_foreign_actor | boolean | Broker shared or sold consumers' data to a foreign actor in the past year. true = filed Yes, false = filed No, null = left blank (not answered). |
sold_to_federal_government | boolean | Broker shared or sold consumers' data to the federal government in the past year. true = filed Yes, false = filed No, null = left blank (not answered). |
sold_to_state_governments | boolean | Broker shared or sold consumers' data to other state governments in the past year. true = filed Yes, false = filed No, null = left blank (not answered). |
sold_to_law_enforcement | boolean | Broker shared or sold consumers' data to law enforcement in the past year (other than under subpoena/court order). true = filed Yes, false = filed No, null = left blank (not answered). |
sold_to_genai_developer | boolean | Broker shared or sold consumers' data to a developer of a GenAI system or model in the past year. true = filed Yes, false = filed No, null = left blank (not answered). |
regulated_fcra | boolean | Broker or a subsidiary is regulated by the federal Fair Credit Reporting Act (FCRA carve-out claimed). true = filed Yes, false = filed No, null = left blank (not answered). |
fcra_pi_types | string | If the broker claims the FCRA carve-out: free-text description of the types of personal information covered. null when not regulated or left blank. |
fcra_products | string | If the broker claims the FCRA carve-out: free-text description of the specific products or services covered. null when not regulated or left blank. |
fcra_pct_activities | string | If the broker claims the FCRA carve-out: free-text description of the percentage of data activities covered. null when not regulated or left blank. |
regulated_glba | boolean | Broker or a subsidiary is regulated by the Gramm-Leach-Bliley Act (GLBA carve-out claimed). true = filed Yes, false = filed No, null = left blank (not answered). |
glba_pi_types | string | If the broker claims the GLBA carve-out: free-text description of the types of personal information covered. null when not regulated or left blank. |
glba_products | string | If the broker claims the GLBA carve-out: free-text description of the specific products or services covered. null when not regulated or left blank. |
glba_pct_activities | string | If the broker claims the GLBA carve-out: free-text description of the percentage of data activities covered. null when not regulated or left blank. |
regulated_iippa | boolean | Broker or a subsidiary is regulated by the California Insurance Information and Privacy Protection Act. true = filed Yes, false = filed No, null = left blank (not answered). |
iippa_pi_types | string | If the broker claims the IIPPA carve-out: free-text description of the types of personal information covered. null when not regulated or left blank. |
iippa_products | string | If the broker claims the IIPPA carve-out: free-text description of the specific products or services covered. null when not regulated or left blank. |
iippa_pct_activities | string | If the broker claims the IIPPA carve-out: free-text description of the percentage of data activities covered. null when not regulated or left blank. |
regulated_cmia | boolean | Broker or a subsidiary is regulated by the California Confidentiality of Medical Information Act. true = filed Yes, false = filed No, null = left blank (not answered). |
cmia_pi_types | string | If the broker claims the CMIA carve-out: free-text description of the types of personal information covered. null when not regulated or left blank. |
cmia_products | string | If the broker claims the CMIA carve-out: free-text description of the specific products or services covered. null when not regulated or left blank. |
cmia_pct_activities | string | If the broker claims the CMIA carve-out: free-text description of the percentage of data activities covered. null when not regulated or left blank. |
regulated_hipaa | boolean | Broker or a subsidiary is regulated by HIPAA privacy, security and breach-notification rules. true = filed Yes, false = filed No, null = left blank (not answered). |
hipaa_pi_types | string | If the broker claims the HIPAA carve-out: free-text description of the types of personal information covered. null when not regulated or left blank. |
hipaa_products | string | If the broker claims the HIPAA carve-out: free-text description of the specific products or services covered. null when not regulated or left blank. |
hipaa_pct_activities | string | If the broker claims the HIPAA carve-out: free-text description of the percentage of data activities covered. null when not regulated or left blank. |
dsar_delete_received | number | Requests to delete — total requests received in the metrics year (see dsar_metrics_year). Number as filed; null when the cell is blank (NOT 0 — blank means not reported). |
dsar_delete_complied_whole | number | Requests to delete — requests complied with in whole in the metrics year (see dsar_metrics_year). Number as filed; null when the cell is blank (NOT 0 — blank means not reported). |
dsar_delete_complied_part | number | Requests to delete — requests complied with in part in the metrics year (see dsar_metrics_year). Number as filed; null when the cell is blank (NOT 0 — blank means not reported). |
dsar_delete_denied | number | Requests to delete — requests denied in the metrics year (see dsar_metrics_year). Number as filed; null when the cell is blank (NOT 0 — blank means not reported). |
dsar_delete_days_mean | number | Requests to delete — mean days to respond substantively in the metrics year (see dsar_metrics_year). Number as filed; null when the cell is blank (NOT 0 — blank means not reported). |
dsar_delete_days_median | number | Requests to delete — median days to respond substantively in the metrics year (see dsar_metrics_year). Number as filed; null when the cell is blank (NOT 0 — blank means not reported). |
dsar_know_collected_received | number | Requests to know what personal information is collected — total requests received in the metrics year (see dsar_metrics_year). Number as filed; null when the cell is blank (NOT 0 — blank means not reported). |
dsar_know_collected_complied_whole | number | Requests to know what personal information is collected — requests complied with in whole in the metrics year (see dsar_metrics_year). Number as filed; null when the cell is blank (NOT 0 — blank means not reported). |
dsar_know_collected_complied_part | number | Requests to know what personal information is collected — requests complied with in part in the metrics year (see dsar_metrics_year). Number as filed; null when the cell is blank (NOT 0 — blank means not reported). |
dsar_know_collected_denied | number | Requests to know what personal information is collected — requests denied in the metrics year (see dsar_metrics_year). Number as filed; null when the cell is blank (NOT 0 — blank means not reported). |
dsar_know_collected_days_mean | number | Requests to know what personal information is collected — mean days to respond substantively in the metrics year (see dsar_metrics_year). Number as filed; null when the cell is blank (NOT 0 — blank means not reported). |
dsar_know_collected_days_median | number | Requests to know what personal information is collected — median days to respond substantively in the metrics year (see dsar_metrics_year). Number as filed; null when the cell is blank (NOT 0 — blank means not reported). |
dsar_know_sold_received | number | Requests to know what personal information is sold or shared — total requests received in the metrics year (see dsar_metrics_year). Number as filed; null when the cell is blank (NOT 0 — blank means not reported). |
dsar_know_sold_complied_whole | number | Requests to know what personal information is sold or shared — requests complied with in whole in the metrics year (see dsar_metrics_year). Number as filed; null when the cell is blank (NOT 0 — blank means not reported). |
dsar_know_sold_complied_part | number | Requests to know what personal information is sold or shared — requests complied with in part in the metrics year (see dsar_metrics_year). Number as filed; null when the cell is blank (NOT 0 — blank means not reported). |
dsar_know_sold_denied | number | Requests to know what personal information is sold or shared — requests denied in the metrics year (see dsar_metrics_year). Number as filed; null when the cell is blank (NOT 0 — blank means not reported). |
dsar_know_sold_days_mean | number | Requests to know what personal information is sold or shared — mean days to respond substantively in the metrics year (see dsar_metrics_year). Number as filed; null when the cell is blank (NOT 0 — blank means not reported). |
dsar_know_sold_days_median | number | Requests to know what personal information is sold or shared — median days to respond substantively in the metrics year (see dsar_metrics_year). Number as filed; null when the cell is blank (NOT 0 — blank means not reported). |
dsar_optout_received | number | Requests to opt out of sale or sharing — total requests received in the metrics year (see dsar_metrics_year). Number as filed; null when the cell is blank (NOT 0 — blank means not reported). |
dsar_optout_complied_whole | number | Requests to opt out of sale or sharing — requests complied with in whole in the metrics year (see dsar_metrics_year). Number as filed; null when the cell is blank (NOT 0 — blank means not reported). |
dsar_optout_complied_part | number | Requests to opt out of sale or sharing — requests complied with in part in the metrics year (see dsar_metrics_year). Number as filed; null when the cell is blank (NOT 0 — blank means not reported). |
dsar_optout_denied | number | Requests to opt out of sale or sharing — requests denied in the metrics year (see dsar_metrics_year). Number as filed; null when the cell is blank (NOT 0 — blank means not reported). |
dsar_optout_days_mean | number | Requests to opt out of sale or sharing — mean days to respond substantively in the metrics year (see dsar_metrics_year). Number as filed; null when the cell is blank (NOT 0 — blank means not reported). |
dsar_optout_days_median | number | Requests to opt out of sale or sharing — median days to respond substantively in the metrics year (see dsar_metrics_year). Number as filed; null when the cell is blank (NOT 0 — blank means not reported). |
dsar_limit_received | number | Requests to limit use/disclosure of sensitive personal information — total requests received in the metrics year (see dsar_metrics_year). Number as filed; null when the cell is blank (NOT 0 — blank means not reported). |
dsar_limit_complied_whole | number | Requests to limit use/disclosure of sensitive personal information — requests complied with in whole in the metrics year (see dsar_metrics_year). Number as filed; null when the cell is blank (NOT 0 — blank means not reported). |
dsar_limit_complied_part | number | Requests to limit use/disclosure of sensitive personal information — requests complied with in part in the metrics year (see dsar_metrics_year). Number as filed; null when the cell is blank (NOT 0 — blank means not reported). |
dsar_limit_denied | number | Requests to limit use/disclosure of sensitive personal information — requests denied in the metrics year (see dsar_metrics_year). Number as filed; null when the cell is blank (NOT 0 — blank means not reported). |
dsar_limit_days_mean | number | Requests to limit use/disclosure of sensitive personal information — mean days to respond substantively in the metrics year (see dsar_metrics_year). Number as filed; null when the cell is blank (NOT 0 — blank means not reported). |
dsar_limit_days_median | number | Requests to limit use/disclosure of sensitive personal information — median days to respond substantively in the metrics year (see dsar_metrics_year). Number as filed; null when the cell is blank (NOT 0 — blank means not reported). |
additional_comments | string | Free-text "Additional Context or Comments" filed by the broker (may span multiple lines). |
state | string | US state as a 2-letter code normalised from state_raw ("California" → "CA"). null for non-US regions or unrecognised values — never guessed. |
website_domain | string | Registrable host extracted from website, lower-case, without scheme or www. Used for rename detection in delta mode. |
name_key | string | Normalised name key (lower-case, punctuation and corporate suffixes removed) — the identity used for delta and verify matching. |
dba_key | string | Normalised key of the DBA name, or null. |
sensitive_data_flag_count | number | Count of the 10 collects_* flags filed Yes. null if any of the 10 is blank (a count over an unanswered flag would be a wrong number). |
any_sensitive_data_collected | boolean | true if any collects_* flag is Yes; false if all 10 are No; null if none is Yes and at least one is blank. |
sold_or_shared_flag_count | number | Count of the 5 sold_to_* flags filed Yes (null if any is blank). |
any_sold_or_shared_disclosure | boolean | true if any sold_to_* flag is Yes; false if all 5 are No; null when undetermined. |
regulated_carveout_count | number | Count of the 5 regulated_* carve-out flags filed Yes (null if any is blank). |
any_regulated_carveout | boolean | true if any regulated_* flag is Yes; false if all 5 are No; null when undetermined. |
flags_true | array | List of every disclosure flag key filed Yes. |
flags_unanswered | array | List of disclosure flag keys left blank on the filing. |
dsar_total_received | number | Sum of the 5 *_received DSAR counts; null if any is blank. |
dsar_total_denied | number | Sum of the 5 *_denied DSAR counts; null if any is blank. |
dsar_reported | boolean | true if at least one DSAR received-count is a number on this filing. |
first_registered_year | number | Earliest year this name key appears across the legacy OAG registry (2020-2023, Date Added), the CPPA 2024 and 2025 exports, and the current registry. null when a prior file was unavailable and the name is not in the ones that loaded. |
first_registered_date | string | ISO date of first registration when a prior file publishes one (OAG "Date Added" or CPPA 2024 "Completion time"); null when only the year is known. |
first_registered_basis | string | Which record gives first_registered_year: oag_legacy_date_added | oag_legacy_listing_undated | registry2024_completion_time | registry2024_listing | registry2025_listing | current_registry_only | prior_files_unavailable. |
days_since_first_registration | number | Days from first_registered_date to this run; null when no dated record exists. |
registration_years_seen | array | Every registration year in which this name key appears (from the files that loaded), ascending. |
in_oag_legacy_registry | boolean | Name key present in the legacy OAG 2020-2023 registry file. null = that file could not be read this run (not checked). |
in_registry_2024 | boolean | Name key present in the CPPA 2024 export. null = file unavailable this run. |
in_registry_2025 | boolean | Name key present in the CPPA 2025 export. null = file unavailable this run. |
history_status | string | complete = all three prior files loaded; partial = some; unavailable = none (all history fields then null). |
event_type | string | delta mode only: new (not in baseline), lapsed (in baseline, absent now, no domain match), renamed (absent name whose website domain re-registered under a new name), changed (tracked field differs). null in registry/verify mode. |
previous_broker_names | array | renamed events: the baseline name(s) sharing this website domain (several when registrations consolidated). |
rename_basis | string | renamed events: how the pair was made (website_domain). |
changed_fields | array | changed/renamed events: [{field, before, after}] for every tracked field that differs (website_domain, state, city, contact_email, every disclosure flag; DSAR metrics are not tracked because they change every filing year). |
change_categories | array | Distinct categories of changed_fields: disclosure_flags | contact | location | website | name. |
query_name | string | verify mode: the name you asked about, verbatim. |
is_registered | boolean | verify mode: true = exact normalised name/DBA match in the current registry; false = no match and no fuzzy candidate ≥0.6; null = fuzzy candidates exist (see evidence) or the query was unusable — review, do not treat as negative. |
match_type | string | verify mode: exact_name | exact_dba | fuzzy_strong_review (≥0.9) | fuzzy_review (≥0.6) | none | unusable_query. |
matched_broker_name | string | verify mode: the registered name matched exactly (null for fuzzy/none). |
evidence | array | verify mode: up to 5 candidates [{broker_name, dba, website, score}] — score is bigram Dice similarity on normalised names, 1 = exact. |
candidate_count | number | verify mode: number of candidates in evidence. |
run_mode | string | registry | delta | verify. |
source_url | string | The CPPA registry export this row was read from. |
source_last_modified | string | Last-Modified header CPPA served for registry.csv on this run (freshness disclosure). |
source_etag | string | ETag header served for registry.csv on this run. |
source_bytes | number | UTF-8 bytes of the decoded export text (the 3-byte BOM CPPA serves is excluded). |
source_row_count | number | Registrants parsed from the current export before any filter. |
source_column_count | number | Columns in the current export header (77 on 2026-09-26). |
dsar_metrics_year | number | The calendar year CPPA names in its DSAR metric headers ("…in 2024"); read from the header, never assumed. |
drift_gate_status | string | verified | verified_degraded (a corroborating probe failed or could not run; disclosed) — a load-bearing failure fails the run and bills nothing. |
drift_probes_verified | array | Probe names that passed this run. |
drift_probes_unavailable | array | Probe names that could not complete (e.g. freshness when Last-Modified is not served). |
baseline_basis | string | delta mode: prior_run (named KV store) | cppa_registry2025_file (first run, seeded from the pinned prior-year export) . null in other modes. |
baseline_row_count | number | delta mode: registrants in the baseline compared against. |
baseline_source_last_modified | string | delta mode: Last-Modified of the file the baseline was built from. |
run_legs_requested | array | Sources this run attempted: registry plus (when includeHistory) oag_legacy, registry2024, registry2025. |
run_legs_ok | array | Sources that answered. |
run_legs_failed | array | Sources that failed (corroborating only — a failed registry leg fails the run). |
run_legs_failed_reason | string | Why each failed leg failed, or null. |
run_complete | boolean | true when every requested leg answered; false = partial, with history fields null where their file failed. |
matched_rows_total | number | Rows matched before maxResults was applied. |
results_truncated | boolean | true when matched_rows_total exceeds maxResults — this row set is a prefix, not the whole answer. |
next_registration_deadline | string | Next annual CPPA data-broker registration deadline (January 31) after this run, ISO date. |
days_to_next_registration_deadline | number | Days from this run to next_registration_deadline. |
drop_deletion_obligation_effective | string | Date the Delete Request and Opt-out Platform (DROP) 45-day deletion-processing obligation took effect for registered brokers. |
unregistered_penalty_usd_per_day | number | Statutory administrative fine for failing to register (Cal. Civ. Code 1798.99.82): $200 per day. |
monitored_at | string | ISO timestamp of this run. |
FAQ
Is this the official CPPA registry? It reads CPPA's own published export on every run and discloses the Last-Modified header. It is not affiliated with the CPPA.
Why does first_registered_year say 2026 for a company I know registered earlier? The name key did not match any prior-year file (first_registered_basis: current_registry_only). Companies re-register under new legal names; check renamed events in delta mode or the evidence in verify mode.
Why is a count null instead of 0? Because a component flag or metric was blank on the filing. Publishing 0 there would assert something the broker never said.
Can I get only new data brokers each week? Yes: schedule { "mode": "delta", "eventTypes": ["new"] }. The baseline lives in a named key-value store on your account, so consecutive runs compare correctly.
How do I check whether a company is a registered data broker in California? { "mode": "verify", "names": ["Company Name"] }.