Purgepath API · v1

DROP scrubbing API for California data brokers

Check records against your California DROP deletion list from your own pipelines. Send a record, a batch, or a CSV file. Get back exactly what to delete.

Base URLapi.purgepath.com/v1
AuthBearer token
FormatJSON · CSV upload
UsageUnlimited · $500/mo

What is the Purgepath API?

The Purgepath API is a REST API for California DROP compliance. Purgepath keeps your DROP deletion list current by syncing it daily. You send records from your CRM, data warehouse, ingestion pipeline or internal tools, and the API tells you which ones match a deletion request.

Use it to screen new data before it lands, re-check your full database after each sync, and keep a timestamped record of every check.

Quickstart

Send records with any identifiers you hold. Purgepath standardizes them to CalPrivacy's formatting rules, hashes them, and matches against your list.

curl https://api.purgepath.com/v1/scrub \
  -H "Authorization: Bearer pp_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "records": [
      { "id": "cust_1001", "email": "jane.doe@example.com" },
      { "id": "cust_1002", "phone": "(916) 555-0142" },
      { "id": "cust_1003", "first_name": "Kim", "last_name": "Nguyen",
        "dob": "1971-04-09", "zip": "90012" }
    ]
  }'

Response:

200 OK · application/json
{
  "scrub_id": "scr_7Hq2kLx9",
  "list_synced_at": "2026-10-04T06:00:00Z",
  "summary": { "checked": 3, "delete": 1, "clear": 2 },
  "results": [
    { "id": "cust_1001", "action": "delete", "matched_on": ["email"] },
    { "id": "cust_1002", "action": "clear",  "matched_on": [] },
    { "id": "cust_1003", "action": "clear",  "matched_on": [] }
  ]
}

How do I authenticate with the Purgepath API?

Send your API key in the Authorization header using the Bearer scheme. Live keys start with pp_live_. Test keys start with pp_test_ and run against a sample list, so you can build before your DROP list is linked.

Header
Authorization: Bearer pp_live_YOUR_KEY

Keep keys server-side. Every request is logged against the key that made it, and keys can be rotated from your dashboard at any time.

How do I check records in real time?

POST/v1/scrub

Send a JSON body with a records array of up to 1,000 records. Each record needs an id and at least one identifier set. Include every identifier you hold; Purgepath checks each one against the matching DROP list.

Request fields

FieldTypeDescription
recordsrequiredarrayUp to 1,000 record objects.
records[].idrequiredstringYour own reference for the record. Returned unchanged so you can act on results.
records[].emailstringEmail address. Matched against the email list.
records[].phonestringU.S. phone number in any common format. Matched against the phone list.
records[].first_namestringUsed with last_name, dob and zip as one identifier set. All four are needed to match on name.
records[].last_namestringSee first_name.
records[].dobstringDate of birth, YYYY-MM-DD.
records[].zipstringZIP code. ZIP+4 is accepted.
tagsobjectOptional. Free-form labels stored with the scrub record, e.g. {"source": "vendor_feed_q4"}.
You don't need to clean data first. Purgepath standardizes every identifier to CalPrivacy's published formatting rules before hashing, which is where most missed matches come from.

What response fields does the API return?

FieldTypeDescription
scrub_idstringUnique ID for this check. Stored with a timestamp for your audit trail.
list_synced_attimestampWhen your DROP list was last synced. Records were checked against this version.
summaryobjectCounts of checked, delete and clear.
results[].idstringYour record ID.
results[].actionstringdelete if any identifier matches an active deletion request, otherwise clear.
results[].matched_onarrayWhich identifier sets matched: email, phone, name_dob_zip.
results[].errorsarrayPresent only if an identifier couldn't be used, e.g. an invalid date.

How do I upload a CSV file?

POST/v1/scrub/file

For full-database checks, upload a file as multipart/form-data. CSV, TSV and plain text are accepted. Map your columns to identifier fields, and optionally pass a webhook URL to be notified when results are ready.

curl https://api.purgepath.com/v1/scrub/file \
  -H "Authorization: Bearer pp_live_YOUR_KEY" \
  -F "file=@customers.csv" \
  -F 'columns={"id":"customer_id","email":"email_address","phone":"mobile"}' \
  -F "webhook_url=https://example.com/hooks/purgepath"
FieldTypeDescription
filerequiredfileCSV, TSV or plain text, with a header row.
columnsrequiredJSON stringMaps Purgepath fields (id, email, phone, first_name, last_name, dob, zip) to your column names.
webhook_urlstringOptional. Called with the job result when processing finishes.
outputstringdelete_only (default) returns only records to delete. all returns every record with its action.

How do I check a file job?

GET/v1/scrub/file/:job_id
200 OK · application/json
{
  "job_id": "job_4Fz81",
  "status": "complete",
  "list_synced_at": "2026-10-04T06:00:00Z",
  "summary": { "checked": 2104882, "delete": 1932, "clear": 2102950 },
  "result_url": "https://api.purgepath.com/v1/scrub/file/job_4Fz81/result.csv",
  "expires_at": "2026-10-11T06:00:00Z"
}

status is one of queued, processing, complete or failed. Result files are available for 7 days; the scrub record itself is kept for your audit trail.

How do I check my DROP list status?

GET/v1/list
200 OK · application/json
{
  "state": "CA",
  "last_synced_at": "2026-10-04T06:00:00Z",
  "next_sync_at": "2026-10-05T06:00:00Z",
  "lists": ["email", "phone", "name_dob_zip"],
  "active_requests": 352118
}

Use this to confirm your list is current before a large job, or to surface sync status in your own monitoring.

Can I send hashes instead of raw data?

Yes. If you'd rather raw identifiers never leave your systems, standardize and hash them yourself (SHA-256, per CalPrivacy's formatting rules) and send the hash fields instead. Matching works the same way.

Request body
{
  "records": [
    { "id": "cust_1001", "email_sha256": "8f2c…e41a" },
    { "id": "cust_1003", "name_dob_zip_sha256": "b19d…07c3" }
  ]
}

Accepted hash fields: email_sha256, phone_sha256, name_dob_zip_sha256.

Webhooks

Purgepath sends a POST to your webhook_url when a file job finishes, and can notify you after each daily DROP sync. Each webhook is signed with an X-Purgepath-Signature header so you can verify it came from us.

EventDescription
file.completeA file job finished. Payload matches GET /v1/scrub/file/:id.
file.failedA file job couldn't be processed. Includes an error message.
list.syncedYour DROP list synced. Includes the count of new requests, so you can trigger a re-check.

What errors can the API return?

StatusMeaning
400Malformed JSON or multipart body.
401Missing, invalid or revoked API key.
403The key is valid but your DROP list isn't linked yet.
413More than 1,000 records in one request. Split the batch or use file upload.
422Required fields are missing, or no record has a usable identifier.
429Too many requests per second. Retry after the time in the Retry-After header.
422 · application/json
{
  "error": {
    "code": "no_identifiers",
    "message": "Record cust_1004 has no usable identifier set."
  }
}

What are the API limits?

Scrubs are unlimited on the $500/month plan. To keep latency predictable, each /v1/scrub request takes up to 1,000 records, and keys are limited to 20 requests per second. For larger jobs, use file upload, which has no record limit.

Frequently asked questions

What is the Purgepath API?
A REST API that checks records against your California DROP deletion list and tells you which to delete. It handles standardization, hashing and matching, and keeps your list synced daily.
Which identifiers can I match on?
Email, phone, and name with date of birth and ZIP code, the identifier types DROP uses. Send whichever you hold; Purgepath checks each set.
Do I have to send raw personal data?
No. Use hashed-only mode to send SHA-256 hashes you compute yourself.
How current is the list I'm checking against?
Your list syncs daily. Every response includes list_synced_at so you know exactly which version a record was checked against.
Is there a test environment?
Yes. Test keys (pp_test_) run against a sample list with known matches, so you can build and test before going live.
How much does API access cost?
$500 a month for unlimited scrubs by API or file upload. No setup fees and no per-record charges.
Does the API handle compliance for us?
The API does the heavy lifting: it keeps your DROP list current and tells you exactly which records to delete. Your team stays in charge of acting on results. The fine print is in our terms.

Get an API key

We're at capacity. Keys are issued to waitlist members as spots open.

Join the waitlist →