Download
Retrieve a ZIP archive of CSV files containing hashed consumer identifiers for each data list enabled on your API key.
California DROP Technical Reference
We put this reference together to help data brokers understand the DROP API.
The DROP Data Broker API enables data brokers to integrate with California's Delete Request and Opt-out Platform to programmatically retrieve consumer deletion request data and report status updates.
Retrieve a ZIP archive of CSV files containing hashed consumer identifiers for each data list enabled on your API key.
Match hashed identifiers against your records and take the required action: delete, opt out, exempt, or mark as not found.
Submit a CSV response file reporting the status code for each work item back to the DROP platform.
Superset handles the full DROP pipeline from download through identity matching to status reporting. If you'd rather not build it yourself, we can help.
All requests require an API key passed in the X-API-KEY header. API keys are generated in the Data Broker Portal after registration and fee payment are complete.
X-API-KEY: your-api-key-here| Environment | Base URL |
|---|---|
| Production | https://api.drop.privacy.ca.gov |
| Sandbox | https://api.drop.privacy.ca.gov/sandbox |
Push and pull requests are closed between 1:00 AM to 3:00 AM Pacific Time daily while the platform batches the most current data. Requests during this window may return errors and should be retried afterward.
All identifiers are hashed with SHA-256 using UTF-8 input encoding. The output is Base64. The following canonicalization rules are applied before hashing. These rules are normative for interoperability with the sandbox CSV files and submission summary reports.
| Field | Rule |
|---|---|
| Remove all whitespace, then lowercase. | |
| DOB | Format as YYYYMMDD with no separators. |
| Phone | Keep digits only, then retain the last 10 digits. |
| ZIP | Keep alphanumeric characters only, lowercase, truncate to the first 5 characters, then remove leading zeros. |
| Names | Transliterate to ASCII, lowercase, then remove spaces, punctuation, separators, and any remaining non-alphanumeric characters.Lily-Anne → lilyanne, D’Amico → damico, Ella Jane → ellajane, Nguyễn → nguyen, Михаил → mikhail |
| MAID | Lowercase, then remove hyphens and any other non-alphanumeric characters. |
| VIN | Lowercase, then remove any non-alphanumeric characters. |
| CTVID | Lowercase, then remove punctuation and separators such as _, -, and :. |
Names are normalized per field (first name and last name independently) before any list-specific concatenation workflow.
For concatenated list types, each normalized field is hashed independently to Base64. Those Base64 digests are concatenated with no separator, then the concatenated UTF-8 string is hashed again and Base64-encoded to produce the final digest.
firstName + lastName + dob + zip
firstName + lastName + vin
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
static string ComputeSha256Base64(string canonical)
{
using var sha = SHA256.Create();
var hashBytes = sha.ComputeHash(Encoding.UTF8.GetBytes(canonical));
return Convert.ToBase64String(hashBytes);
}
static string NormalizeEmail(string input)
=> Regex.Replace(input ?? "", @"\s+", "").ToLowerInvariant();
static string NormalizePhone(string inputNumber)
{
var digits = new string((inputNumber ?? "").Where(char.IsDigit).ToArray());
return digits.Length > 10 ? digits[^10..] : digits;
}
static string NormalizeZip(string input)
{
var cleaned = new string((input ?? "").Where(char.IsLetterOrDigit).ToArray()).ToLowerInvariant();
var truncated = cleaned.Length <= 5 ? cleaned : cleaned[..5];
return truncated.TrimStart('0');
}/data/downloadReturns a ZIP archive containing one CSV file per consumer data list enabled for the authenticated API key.
<YYYYMMDD>_<DataBrokerId>_<DataType>.csvFilename capitalization is not significant. Preserve the exact file name when uploading your response.
| List Type | Columns |
|---|---|
NDZ | Id, Hash |
EMAIL | Id, Hash |
PHONE | Id, Hash |
MAID | Id, Hash |
NVIN | Id, Hash |
CTVID | Id, Hash |
Id,Hash
679,KA18MT/ph6IHYjzT9zwETySDQyvSh87YuoSBpOQtkhE=curl -X GET "https://api.drop.privacy.ca.gov/data/download" \
-H "accept: */*" \
-H "X-API-KEY: your-api-key-here" \
--output download.zip$headers = @{
"X-API-KEY" = "your-api-key-here"
"Accept" = "text/zip"
}
Invoke-WebRequest \
-Uri "https://api.drop.privacy.ca.gov/data/download" \
-Headers $headers \
-OutFile "download.zip"/data/uploadUpload a CSV response file for the first time for a given downloaded file. One or more CSV response files may be uploaded in the same request.
Id,Status.csv20260312_4821_Email.csv20260312_4821_Email_part01.csvFiles are sent as multipart/form-data with the field name files.
Id,Status
679,2
680,5acceptedCount and rejectedCount to determine outcome.curl -X POST "https://api.drop.privacy.ca.gov/data/upload" \
-H "accept: */*" \
-H "X-API-KEY: your-api-key-here" \
-H "Content-Type: multipart/form-data" \
-F "files=@20260312_4821_Email.csv;type=text/csv"const formData = new FormData();
formData.append('files', fileBlob, '20260312_4821_Email.csv');
const response = await fetch(
'https://api.drop.privacy.ca.gov/data/upload',
{
method: 'POST',
headers: {
'X-API-KEY': 'your-api-key-here'
},
body: formData
}
);
const result = await response.json();/data/amendUpload a corrected CSV response file for a previously submitted download. One or more corrected CSV response files may be uploaded in the same request. The request format is identical to /data/upload. Use this endpoint when you need to update statuses in a file that was already accepted via /data/upload.
acceptedCount and rejectedCount to determine outcome.curl -X POST "https://api.drop.privacy.ca.gov/data/amend" \
-H "accept: */*" \
-H "X-API-KEY: your-api-key-here" \
-H "Content-Type: multipart/form-data" \
-F "files=@20260312_4821_Email.csv;type=text/csv"Status codes reported for each work item in the uploaded CSV.
| Code | Label | Description |
|---|---|---|
2 | Exempted | Match found, data exempt under Civil Code §1798.99.86(c)(2). |
3 | Deleted | Match found, non-exempt personal information deleted. |
4 | Opted out | Multiple consumers linked, all opted out of sale or sharing. |
5 | Not found | No match after matching process. |
Response returned after a file upload (new or amend).
| Property | Type | Description |
|---|---|---|
mode | "new" | "amend" | The upload mode: new for first submission, amend for corrections. |
acceptedCount | integer | Number of files accepted in this request. |
rejectedCount | integer | Number of files rejected in this request. |
accepted | FileResult[] | List of accepted files with confirmation messages. |
rejected | FileResult[] | List of rejected files with error messages. |
Result for a single file in an upload response.
| Property | Type | Description |
|---|---|---|
fileName | string | The name of the uploaded CSV file. Must be the original downloaded file name or that name plus an optional suffix of up to 10 characters before .csv. |
message | string | Human-readable result message. |
| Column | Type |
|---|---|
Id | integer |
Hash | string (SHA-256 Base64) |
| Column | Type |
|---|---|
Id | integer |
Status | StatusCode (2, 3, 4, or 5) |
Consumer data list types enabled for the API key. These values match the live sandbox file suffixes.
{
"mode": "new",
"acceptedCount": 1,
"rejectedCount": 0,
"accepted": [
{
"fileName": "20260312_4821_Email.csv",
"message": "Accepted. NEW file queued for processing."
}
],
"rejected": []
}{
"mode": "new",
"acceptedCount": 0,
"rejectedCount": 1,
"accepted": [],
"rejected": [
{
"fileName": "20260312_4821_Email.csv",
"message": "Invalid CSV header. Expected: Id,Status"
}
]
}{
"mode": "new",
"acceptedCount": 0,
"rejectedCount": 1,
"accepted": [],
"rejected": [
{
"fileName": "20260312_4821_Email.csv",
"message": "You already uploaded a file with the same filename for this run."
}
]
}{
"mode": "amend",
"acceptedCount": 1,
"rejectedCount": 0,
"accepted": [
{
"fileName": "20260312_4821_Email.csv",
"message": "Accepted. AMEND file queued for processing."
}
],
"rejected": []
}All endpoints share the same error response codes.
| Status | Meaning | Action |
|---|---|---|
400 | Bad Request | Invalid parameters, file formatting, file name, or CSV columns. Correct the request before retrying. |
401 | Unauthorized | API key is missing or invalid. Generate a new key from the Data Broker Portal. |
403 | Forbidden | Access denied. This typically means payment has not been completed through the Data Broker Portal. |
404 | Not Found | The requested endpoint does not exist. Verify the API URL. |
429 | Too Many Requests | Rate limit exceeded. Rate limits are adjusted automatically based on system load. Back off and retry after a delay. |
500 | Server Error | Internal server error. This may occur during the daily maintenance window (1:00 AM to 3:00 AM Pacific Time) or due to a transient issue. Retry later. |
If you have questions about the DROP API, the hashing workflow, or how to operationalize your integration, reach out to us. Superset has already built a complete DROP pipeline for data brokers and we handle download, identity matching, and status reporting so you don't have to.