Using Two-Tier Searches for Superior Results

API V5 has brought with it many new features, which can be used to create new, advanced search strategies. The most interesting search strategy now possible is what we call a two-tier search.

A two tier search mimics the behavior of many users looking up someone on our search engine at Often search engine user will type a person’s name, and then click on a person from the list of potential matches to get more details. A two tier search works in a similar manner but with the API instead of the search engine. The first tier search returns a list of possible persons, and the second tier search provides all the details connected to one, selected person.

Search pointers

A two tier search is now possible with the API thanks to a new search pointer attribute introduced in V5. The search pointer is an internal representation of the data connected to a single, specific person. When looking at the JSON output, you will see the code for the search pointer displayed at the top of the person object just above the name parameter.

A search pointer represents all the data on one person, i.e. all their names, addresses, phones, emails, etc. This makes a search pointer-base query just like searching a full person object. In 99.9% of cases, a search pointer-based query will result in a person response. To learn more about search pointers and how you can use them, go here.

Basic, first-tier search

For any search query, the Pipl API can return one of three responses:

  1. No match – When no data is found.
  2. Possible persons – When the data sent/found is not enough to identify a single person.
  3. Person – When the data sent/found is enough to identify a single, matching person.

In many cases, the data points provided in a basic search query will result in a possible persons response. Most systems will have trouble deciding if the first person in the possible persons response is is the desired person. They then disregard the possible persons responses all together and treat them as if they were a no match response – which they definitely are not! So what can you do?

Second-tier search

This is where the search pointer comes handy.

An alternative to throwing away good data, is to take the first person’s search pointer and use it by itself as a separate search. A possible persons response returns possible persons in descending order based on their match rate (whether you can see the match rate or not). The most probable person will always appear as the first possible person at the top of the results and the least probable person will appear at the bottom of the list.

If you use the first search pointer from the list of persons, you will get back a single, definitive person response.

This can also be very helpful if you are seeking emails or URLs, since the API will only display these when there is a definitive person response. This makes search pointers crucial for getting all the data you want but cannot retrieve from a possible persons response.

Tips for Advanced Users

  1. One advanced strategy you can use that employs a two tier search is switching API keys to improve cost effectiveness. If for example you are seeking emails, you can start by using a basic CONTACT key. Take all your single person response search pointers and all the first search pointers from possible persons responses and run them on a BUSINESS PREMIUM key. This way you can pay less for initial searches using a cheaper plan, while maximizing the amount of data you receive for each person response.
  2. Another great aspect to search pointers is that you can run them after a long period of time has elapsed since your previous search and get updated data. You simply must state the “new_” in the match requirements parameter for the field you wish to update. This is why we usually recommend that clients using search pointers cache them for future use, or DB updates.


In the first tier query, I searched for “Clark Kent” and got a possible persons response with 50 persons.

"@http_status_code": 200,
"@visible_sources": 183,
"@available_sources": 183,
"@persons_count": 50,
"@search_id": "1609051317222351653983783995963160512",
"query": {
"names": [
"first": "Clark",
"last": "Kent",
"display": "Clark Kent"
"available_data": {
"premium": {
"relationships": 224,
"usernames": 4,
"jobs": 11,
"addresses": 217,
"phones": 15,
"educations": 4,
"languages": 50,
"user_ids": 16,
"social_profiles": 12,
"names": 161,
"dobs": 50,
"images": 8,
"genders": 43

In the second tier query, I took the first person’s search pointer and ran it again. This resulted in a person response with emails and URLs.

"@http_status_code": 200,
"@visible_sources": 141,
"@available_sources": 141,
"@persons_count": 1,
"@search_id": "1609051317552104334668329331025039020",
"query": {
"@search_pointer": "96368……b2478065"
"available_data": {
"premium": {
"relationships": 6,
"jobs": 4,
"addresses": 13,
"phones": 3,
"educations": 2,
"languages": 1,
"user_ids": 4,
"social_profiles": 2,
"names": 5,
"dobs": 1,
"images": 1,
"genders": 1,
"emails": 5