Identity Resolution API - PII to Pseudonymous Person ID
Pricing
$5.00 / 1,000 results
Identity Resolution API - PII to Pseudonymous Person ID
Resolve names, postal addresses, email addresses and phone numbers, plaintext or hashed, to a stable pseudonymous person identifier, so the same person can be recognised across systems without those systems exchanging contact details. Returns the match level and components. Pay per result.
Pricing
$5.00 / 1,000 results
Rating
0.0
(0)
Developer
Nabeel Hassan
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
3 days ago
Last modified
Categories
Share
Turn names, addresses, emails and phone numbers into a stable identifier for the person behind them, so two systems can agree they are talking about the same customer without either of them handing over the contact details. One flat row per result.
What this actor does
- Resolves contact details to one durable identifier. The same person, arriving as an email address in one system and as a name and postal address in another, comes back as the same identifier. That is what makes deduplication, suppression and cross-system measurement possible without moving personal data between them.
- Works down a match cascade and tells you where it landed. The provider tries name with address and postal code first, then name with email, then name with phone, then partial name with email or phone, then email alone, then phone alone, then name with postal code. Every row says which step produced it and what that step means, so a strong match and a weak one are never mixed together in the same column.
- Reports which fields did the work. The components that contributed to a match come back as their own column, so you can require the ones you trust. If your email data is good and your addresses are stale, require the email component and drop the rest.
- Distinguishes a single clear match from several plausible ones. The distinct match flag says whether one best answer stood out. It is the strictest quality filter available here, and it is exposed as a filter rather than left in the raw payload.
- Accepts hashed values as well as plaintext. If contact details must not leave your side in the clear, hash them and use the lookup mode. MD5, SHA-1 and SHA-256 are all accepted, and a digest of the wrong length for the chosen algorithm is refused here rather than sent, because one bad element can cost you a whole batch.
- Respects the provider's privacy floor rather than fighting it. No batch under 100 records is accepted and no batch resolving fewer than 25 distinct identifiers is answered at all, because a small identity lookup is a way to reidentify one person. The run gathers records into batches that clear the floor, evens the sizes so no remainder batch is refused, and stops with a plain explanation when there are too few records rather than sending a request that will be rejected.
- Never pretends results line up with inputs. The provider deliberately shuffles its responses so a caller cannot pair result three with input three. Nothing here invents that pairing. Rows carry their position in the response and say what it is.
- Reads the errors that hide inside a success. A per-record failure rides inside a 200 response with its own code and message. An opted-out person is reported as opted out, not written up as a match that happened to be empty.
- Validates before it sends. Two-letter states, postal codes of five, nine or eleven digits, ten-digit phone numbers, emails with a dot in the domain, and the rule that a name or an address may be given whole or in parts but never both. Every one is checked locally, so a malformed row is a flagged row rather than a rejected batch.
- Refreshes tokens on a clock, not on a failure. Access tokens here last about fifteen minutes and an expired one is reported the same way as a missing permission, so retrying it as a permission problem just fails again. This actor renews before expiry.
- Never charges for a miss. Only rows carrying a resolved identifier are billed.
Input
| Field | What it does |
|---|---|
mode | Match plaintext details, or look up hashed values. |
emails | Addresses to resolve, one per line. |
phones | Phone numbers to resolve, one per line. |
records | Full records as JSON objects, for names and addresses. |
hashes | Hashed values to resolve, one per line. |
hashType | MD5, SHA-1 or SHA-256. |
matchLimit | Identifiers per record, 1 to 10. |
distinctMatchesOnly | Keep only single clear matches. |
maxMatchConfidence | Weakest cascade level to accept. |
requiredComponents | Require these fields to have contributed. |
completeNamesOnly | Require the whole name to have matched. |
requestsPerMinute | Pace the run under your contract's rate limit. |
skipNotFound | Leave unresolved records out of the dataset. |
maxResults | Cap on rows written. Cannot shrink a batch. |
clientId | Your own service account client id. Stored as a secret. |
apiKey | Your own service account client secret. Stored as a secret. |
Example output
{"found": true,"mode": "match","responseIndex": 0,"code": 200,"identifier": "XiT001sgRRky74xZ6NrpSsF6z2ucg6TeV8rISolIhOMe-R94lh47QP2xuVITxFm6otlyrB","identifiers": ["XiT001sgRRky74xZ6NrpSsF6z2ucg6TeV8rISolIhOMe-R94lh47QP2xuVITxFm6otlyrB"],"matchConfidence": "2","matchConfidenceMeaning": "Name and email","matchComponents": ["name", "emailAddress"],"isDistinctMatch": true,"nameMatchIntegrity": "complete","invalidParameters": [],"isOptedOut": false,"errorCode": null,"error": null,"raw": { }}
Frequently asked questions
What is a pseudonymous person identifier for?
Recognising the same person in two places without either place handing over the person's details. Your CRM knows an email address; your agency knows a postal address; a measurement partner knows neither. Resolve all three to the same identifier and they can agree they are looking at one customer, deduplicate, suppress an existing customer from an acquisition campaign, or measure a campaign against actual conversions, while the underlying contact details stay where they were.
Why is there a minimum of 100 records?
Because the provider enforces it, and the reason is worth understanding rather than working around. An identity API that answered one record at a time would be a reidentification tool: feed it a single email address and it hands you a durable key for that individual. Requiring at least 100 records per batch, and refusing to answer unless at least 25 distinct identifiers come back, makes that use impractical. This actor gathers your records into batches that clear the floor rather than sending them as they arrive, and evens the sizes so a remainder batch is never refused for being too small.
Can I match the results back to the rows I sent?
Not by position, and that is deliberate. The provider returns responses in a randomised order specifically so that result three cannot be paired with input three, which is the whole point of a pseudonymous identifier. This actor does not invent that pairing: each row carries its position in the response, labelled as such. What you get is the set of identifiers behind your list, along with the quality of each match. If you need a per-row join, that is a different product from this one and this API is designed not to be it.
What do the match levels mean?
They are steps in the provider's cascade, tried strongest first. Level 1 is name with street address and postal code. Level 2 is name with email. Level 3 is name with phone. Levels 4 and 5 are partial name with email or phone. Levels 6 and 7 are email or phone alone. Level 8 is name with postal code. A lower number means more corroborating evidence, so the weakest-match-to-accept filter is a floor on quality rather than a ceiling.
What is the difference between a distinct match and a non-distinct one?
Distinct means one candidate scored highest on its own. Non-distinct means several were equally good and the provider returned one of them. For suppression, where a false positive means failing to contact a real prospect, non-distinct matches are usually fine. For anything where a wrong join has consequences, filter to distinct only. The flag is only reported when you ask for one identifier per record, which is another reason to leave that at one.
Should I send plaintext or hashed values?
Send hashed values when your own rules say contact details must not leave your systems in the clear, which is common and often contractual. The cost is matching power: hashed lookup is an exact match on a normalised value, so a misspelling, a nickname or a changed street type will not match, whereas the plaintext match route normalises and matches fuzzily before it gives up. Use plaintext when you can and hashed when you must, and expect a lower hit rate from hashed.
Why were some of my records refused before they were sent?
Because this provider validates strictly and rejects the whole batch when one element is malformed. A two letter state, a postal code of exactly five, nine or eleven digits, a phone of exactly ten digits, an email with a dot in the domain. There is also a rule that catches people out: a name may be given whole or split into first, middle and last, and a street address may be given whole or split into its components, but never both ways in the same record. This actor checks all of that locally, so a bad row becomes a flagged row rather than a failed run.
What does opted out mean in the results?
That the person has exercised their right to be excluded from this kind of processing. Those records come back with an error code and no identifier, by design, and no amount of retrying will change it. They are reported as their own flag rather than being lumped in with records the provider simply does not know, because they are a different fact about a different situation.
Are the routes in this actor verified against the live service?
The token route is: deliberately invalid credentials answer with the provider's own "Invalid Client Credentials". The two batch routes are not, and that is worth saying plainly. This gateway validates the bearer token before it decides whether a path exists, so a real path and an invented one both answer identically and probing proves nothing about either. Those two come from the provider's own published documentation instead.
Do I need my own API key?
Yes, and this one is not self-service. This actor does not include data access. You need a service account with LiveRamp, the provider whose identity resolution API this actor calls, which issues a client id and a client secret through your account representative rather than through a signup form. Both go into the input and are stored as Apify secrets. Your own contract, permissions and terms apply, and some capabilities, such as returning more than one identifier per record, are permissions granted separately on your account.
How much does a run cost?
Pricing is pay per result: you are charged for each identifier resolved into the dataset, and never for records that resolved to nothing, for people who have opted out, for inputs refused before they were sent, for rows dropped by the filters, or for duplicates. Apify platform usage is included in the per-result price. Your own provider contract is separate and billed by them.
Keyword map
identity resolution API, identity graph, pseudonymous identifier, person identifier, PII to ID, hashed email matching, hashed phone matching, MD5 email hash, SHA-256 email hash, deterministic matching, fuzzy name matching, match cascade, customer deduplication, cross system customer matching, suppression list matching, audience onboarding, first party data activation, clean room identity, privacy preserving matching, opt out handling, match confidence, record linkage, customer data integration, identity spine