Technical guide

The DROP hashing specification, explained

DROP never sends you a name or an email — only SHA-256 hashes. Matching works only if your normalization is byte-identical to the state's. Here are the rules, the composites, and the official test vectors to check your implementation against.

Get a normalization rule wrong and nothing errors — you simply fail to match consumers who asked to be deleted, report "not found," and accrue $200 per request, per day. This is the highest-stakes code in the whole integration.

The algorithm

Every identifier is standardized, then hashed with SHA-256 over UTF-8 input, with the digest encoded as standard Base64 including the = padding — not URL-safe Base64. Every hash is exactly 44 characters.

Anna.Smith@Domain.com
  → normalize → anna.smith@domain.com
  → SHA-256, UTF-8, Base64 → KA18MT/ph6IHYjzT9zwETySDQyvSh87YuoSBpOQtkhE=

Normalization, identifier by identifier

TypeRuleExample
EmailRemove whitespace, lowercase. Do not strip dots or plus signs.Anna.Smith@Domain.com → anna.smith@domain.com
PhoneStrip non-numerics; keep the last 10 digits (or all, if fewer). Country codes fall away.+1(415)555-9317 → 4155559317
DOBYYYYMMDD, four-digit year.July 4, 1776 → 17760704
ZIPAlphanumerics only, drop the +4, lowercase, remove leading zeros, then take the first five characters present.00300-9999 → 300
NameLowercase; map special Latin (ß→ss, æ→ae); transliterate Greek and Cyrillic; leave CJK/Arabic/Hebrew alone; drop everything that isn't a letter or digit. First and last are hashed separately.Björn O'Connor-López → bjornoconnorlopez
MAIDHex characters only, lowercase — 32 characters.a3f1c2d4-5678-… → a3f1c2d4567890ab…
VIN / CTV IDAlphanumerics only, lowercase.1HGCM82633A004352 → 1hgcm82633a004352

The ZIP rule is the one that bites: leading zeros are stripped before the first-five truncation, so a Puerto Rico ZIP like 00712345 normalizes to 71234, not 00712.

Composite hashes: NDZ and NameVIN

Two of the six list types combine fields. The composite is not a hash of the concatenated values — each field is standardized and hashed on its own, the resulting Base64 strings (padding included) are concatenated with no delimiter, and that string is hashed again.

NDZ = FirstName + LastName + DOB + ZIP     (in that order)

danielle → 5dUD1FgiKcTJq+JQ5JZUdlyIXrSbtJ338YYbt5/HNG4=
johnson  → K+TjOqPiH2/3rRRPj9WCKKHM47UDQLSAX/DGNIDuxIg=
19850704 → IWi7qxOAbBJe0fNciDj76Eg84gmj40rB7aNMK/VnFOI=
91790    → 2FPZucR4x7U8KlM+SFAX4LPGhwNz/PIZUCSUdDh0o/s=

concat(4 × 44 chars, no separator) → SHA-256 → Base64
                                   ↓
NDZ hash = PQOfn1RffEKmqMmNAzDKKaoZCwxWbQZkQzPWmQo9REA=

NameVIN works the same way with FirstName + LastName + VIN. Forgetting to include the = padding in the concatenation is the most common way to get a plausible-looking but wrong composite.

Test vectors

The CPPA publishes worked examples. Treat them as a golden test suite — if any of these fail, your matching is wrong and you will under-delete.

email    anna.smith@domain.com  KA18MT/ph6IHYjzT9zwETySDQyvSh87YuoSBpOQtkhE=
phone    4155559317             vGM7y5n+hBXRSEAklhHDPCbysyNgYTmXdMcagGUOY8E=
dob      17760704               skXYXxBER6HQTZ3rXSZH1wVGLQ054mS5rbR/bwvzy4I=
zip      91790                  2FPZucR4x7U8KlM+SFAX4LPGhwNz/PIZUCSUdDh0o/s=
zip      m1b1a                  n8L9q8mVeT6Xt9/EeUNiTukGDrkbPJ3DvOEx14uElxk=
name     juanpablo              91hIbrbzNeqHs3o81O5yNrXUj7wDd2shvZ6THKi9qz8=
maid     a3f1c2d4567890ab…      250KY6lOgzYUB3EHrkbDCE2kMEZQE69SF38muhoDudI=
vin      1hgcm82633a004352      iNswy1m+0VSt8jAfFrvaiQ1R/0HAbgSwNGkwqo6QBss=
NDZ      (Danielle Johnson…)    PQOfn1RffEKmqMmNAzDKKaoZCwxWbQZkQzPWmQo9REA=
NameVIN  (Eve Genesis + VIN)    rtnDuXIe63jXYQQXW5r07GJ7lSsrib8+46QuKFwkOmk=

The sandbox also ships a standardization-and-hashing tool — validate against it before your first real cycle.

Check your own implementation

Our hash checker runs the same engine in your browser — type any identifier and compare.

Open the hash checkerAPI integration guide →