# Pipl Search API Documentation Portal
> Welcome to the Pipl Search API Documentation Portal. You'll find comprehensive guides and documentation to help you start working with Pipl Search as quickly as possible.
This file contains all documentation content in a single document following the llmstxt.org standard.
## Data Sources
Pipl includes more than 3 billion online identities cross-referenced from more than 25 billion individual records. Our search platform gathers data from sources such as public records, business listings, marketing lists, phone directories, and crowd-sourced information. Pipl also extracts facts and relevant information from web documents, personal profiles, blogs, news articles, and publications (see [PiplBot](https://pipl.com/bot)). Data gathered from all sources is cleansed, merged, and clustered to create more than three billion detailed online identities.
For each query, Pipl searches for results across millions of data sources. Some sources that are no longer available online can be found in our API's "Deep Web Archives". This page describes our sources and provides examples of sources we use. This list is not exhaustive.
## Data Source Categories
We categorize data sources into one of 10 categories based on the type of data they contain. You can see the category of each source in the [Source](/reference/source) object in API responses.
Below is the list of categories and a few examples of the websites you'll find in each:
| **Category** | **Examples** |
|-------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **Personal Profiles** | facebook.com pinterest.com last.fm |
| **Professional & Business** | linkedin.com spoke.com zoominfo.com |
| **Contact Details** | addresses.com anywho.com |
| **Media** | picasa.com flickr.com youtube.com |
| **Background Reports** | peoplefinders.com intelius.com peoplesmart.com |
| **Public Records** | bop.gov archives.com ancestry.com |
| **Publications** | uspto.gov portal.acm.org scirus.com |
| **School & Classmates** | classmates.com reunion.com schoolbank.nl |
| **Email Address** | intelius.com spokeo.com |
| **Web Pages** | Default category. This includes data sources that don't match any of the above categories. |
## Sample Data Sources
| # | Domain | Name |
| :---- | :------------------------------------------------------------------------------------------ | :---------------------------------------------------- |
| **1** | facebook.com | Personal Web Profile - Facebook |
| **2** | amazon.com | Customer Profile - Amazon.com |
| **3** | linkedin.com | Professional Profile & Networking - LinkedIn |
| **4** | instagram | Photo Sharing Profile - Instagram.com |
| **5** | tiktok | Video-sharing app |
| **6** | twitter.com | Personal Profile - Twitter |
| **7** | groups.google.com | Messages - Google Groups |
| **8** | video.google.com | Video - YouTube |
| **9** | youtube.com | Personal Profile - YouTube |
| **10** | home.live.com | Window Live Profile - Windows Live |
| **11** | ebay.com | Buyer, Seller Profile - eBay |
| **12** | pinterest.com | Virtual Pinboard - Pinterest |
| **13** | imgur | Image Sharing Personal Profile - Imgur |
| **14** | amazon.co.uk | Wish Lists - Amazon (UK) |
| **15** | amazon.ca | Wish Lists - Amazon (Canada) |
| **16** | skype | Personal Profiles - Skype |
| **17** | myspace.com | Personal Web Space - MySpace |
| **18** | github | Open Source Collaboration - Github |
| **19** | reddit.com | Personal Profile - Reddit |
| **20** | yelp | Business Reviews - Yelp |
| **21** | tripadvisor.com | Personal Profile - TripAdvisor |
| **22** | imdb.com | Actor, Director, Producers Profile - IMDB |
| **23** | vimeo.com | Personal Profile - Vimeo |
| **24** | vk.com | Personal Profile - VK |
| **25** | Academia | Scholar/Student Profile - Academia.edu |
| **26** | wikipedia.org | The Free Encyclopedia - Wikipedia |
| **27** | flickr.com | Online Photo Album - Flickr |
| **28** | en.gravatar.com | Globally Recognized Avatars - Gravatar |
| **29** | picasaweb.google.com | Web Albums - Picasa |
| **30** | tumblr.com | Microblogging - Tumbler |
| **31** | vids.myspace.com | Videos - MySpace |
| **32** | tagged.com | Personal Profile - Tagged |
| **33** | arin.net | American Internet Registry - ARIN |
| **34** | ratemyteachers.com | Teachers Profile - RateMyTeachers |
| **35** | plaxo.com | Online Address Book - Plaxo |
| **36** | peoplesmart.com | Professional Listings - PeopleSmart |
| **37** | infobel.com | Phone Directory - Infobel France |
| **38** | nasza-klasa.pl | Personal Profile - Nasza-Klasa |
| **39** | uspto.gov | Patent - US Patent & Trademark Office |
| **40** | vitals.rootsweb.com | California Death Records - RootsWeb |
| **41** | findagrave.com | Non-Famous Grave Record - FindAGrave |
| **42** | findmypast.co.uk | UK family history records - Findmypast.co.uk |
| **43** | instantcheckmate.com | Check Criminal Records Online - Instant Check Mate |
| **44** | last.fm | Personal Music Profile - Last.fm |
| **45** | grono.net | Profiles - Grono |
| **46** | ratemyprofessors.com | Professors Profile - RateMyProfessor |
| **47** | xanga.com | Personal Web Profile - Xanga |
| **48** | gaiaonline.com | Virtual World Personal Profile - Gaia Online |
| **49** | meetup.com | Member Profile - Meetup |
| **50** | en.netlog.com | Personal Profile - Netlog |
| **51** | webshots.com | Member's Profile - Webshots.com |
| **52** | scribd.com | Sharing Community Member Profile - Scribd.com |
| **53** | stumbleupon.com | Web Recommendations Personal Profile - StumbleUpon |
| **54** | date.com | Personal Profile - Date.com |
| **55** | datehookup.com | Dating Person Record - DateHookUp |
| **56** | deviantart.com | Community of Artists and Art Devoted - DeviantArt |
| **57** | behance.net | People - Behance Network |
| **58** | wayn.com | Travelers Profile - Wayn |
| **59** | soundcloud.com | Audio Platform Personal Profile - SoundCloud |
| **60** | ustream.tv | Personal Profile - Ustream.TV |
| **61** | dailymotion.com | Videos Community Personal Profile - Dailymotion |
| **62** | qik.com | Personal Profile- Qik |
| **63** | goodreads.com | Book Reading List & Profile - Goodreads |
| **64** | plurk.com | Member Profile - Plurk |
| **65** | twicsy.com | Twitter Pic Trends and Users - Twicsy |
| **66** | bebo.com | Personal Profile - Bebo |
| **67** | photobucket.com | Photo & Video Sharing - Photobucket |
| **68** | metacafe.com | User Profiles - Metacafe |
| **69** | club.ign.com | Personal Profile - IGN |
| **70** | stickam.com | Photos and Personal Profile - Stickam |
| **71** | break.com | Personal Profile - Break.com |
| **72** | pbase.com | Member's Profile - PBase |
| **73** | digg.com | Latest News Headlines, Videos and Images - Digg |
| **74** | zedge.net | Mobile Entertainment - Zedge |
| **75** | hubpages.com | Personal Profile - HubPages |
| **76** | it.toolbox.com | IT Community Profile- ToolBox |
| **77** | fotolog.com | Personal profile - Fotolog |
| **78** | kongregate.com | Gamer's Profile - Kongregate |
| **79** | taringa.net | Personal Profile - Taringa |
| **80** | videojug.com | Video Sharing - VideoJug |
| **81** | martindale.com | Law Professional Profile - LexisNexis |
| **82** | strategis.ic.gc.ca | Corporation Canada - Strategis Canada |
| **83** | avvo.com | Attorney Rating - Avvo |
| **84** | zoominfo.com | Web Extracted Biography - ZoomInfo |
| **85** | trulia.com | Real Estate Professional Profile - Trulia |
| **86** | dirigeant.societe.com | Business Leaders Profiles - Dirigeant |
| **87** | 118218.fr | White Pages - L'annuaire téléphonique en ligne |
| **88** | paginebianche.it | White Pages - Paginebianche.it |
| **89** | local.ch | White Pages - Tel.local |
| **90** | tel.search.ch | Phone Directory - Switzerland |
| **91** | telelistas.net | White Pages - Brazil |
| **92** | 11880.com | Telephone Directory - 11880.com |
| **93** | nettkatalogen.no | Phone Directory - Nettkatalogen |
| **94** | phonebookonline.co.za | The Phone Book - South Africa's White Pages |
| **95** | anywho.com | White Pages - AnyWho |
| **96** | dasoertliche.de | White Pages - Germany |
| **97** | canada411.ca | Personal Records - Canada411 |
| **98** | whitepages.be | Phone Directory - WhitePages Belgium |
| **99** | extrakoll.se | White Pages Swedan - Extrakoll |
| **100** | 1881.no | Personal Contact Information - 1881.no |
| **101** | hi5.com | Social Entertainment Personal Profile - hi5 |
| **102** | scirus.com | Scientific Publication - Scirus |
| **103** | patentstorm.us | Patent Record - PatentStorm |
| **104** | deltacomputersystems.com | Case Record - Virtual Courthouse Marion County |
| **105** | sos.mo.gov | Registered Agent Record - Missouri Secretary of State |
| **106** | index.rbhayes.org | Obituary Index - RB Hayes, OH |
| **107** | nationalarchives.gov.uk | Family History - National Archives |
| **108** | recorder.maricopa.gov | Public Records - Maricopa County, AZ |
| **109** | indianaunclaimed.com | Unclaimed Property - Indiana |
| **110** | leeclerk.org | Public Records - Lee County Clerk, FL |
| **111** | tax1.co.monmouth.nj.us | Tax Record - Monmouth County, NJ |
| **112** | archives.gov | Army Enlistment Records (1938 - 1946) - NARA |
| **113** | dockets.justia.com | Case Records - Justia Federal District Court |
| **114** | vitals.rootsweb.ancestry.com | Marriage Records - Rootsweb Kentucky |
| **115** | 192.com | People In The UK - 192.Com |
| **116** | ancestry.com | Message Boards Search - Ancestry |
| **117** | familysearch.org | Genealogical Index - Familysearch |
| **118** | vampirefreaks.com | User Profile - Vampirefreaks.com |
| **119** | fr.netlog.com | Personal Profile - Netlog France |
| **120** | upcoming.yahoo.com | Personal Profile - Upcoming Events Yahoo |
| **121** | pof.com | User Profile - Plentyoffish |
| **122** | disqus.com | Webwide Discussion - Disqus |
| **123** | slideshare.net | Slide Sharing - SlideShare |
| **124** | veoh.com | Free Videos Watch TV Online - Veoh |
| **125** | recruitingblogs.com | Recruiting Community - RecruitingBlogs |
| **126** | reverbnation.com | Member's Profile - ReverbNation.com |
| **127** | cis.state.mi.us | Insurance Licensee - DLEG, Michigan |
| **128** | phonebook.yellowpages.co.za | PhoneBook - South Africa |
| **129** | laguia.com.ve | White Pages - Venezuela |
| **130** | paginasamarillas.com.pe | White Pages - Peru |
| **131** | pagesjaunes.fr | Phone Lookup - Pagesjaunes |
| **132** | yellowpages.com | Phone LookUp - YellowPages |
| **133** | klicktel.de | Telefonbuch auf klicktel - klicktel |
| **134** | reunion.com | School & Contact Details - MyLife.com |
| **135** | patents.ic.gc.ca | Patents - Canada Intellectual Property Office |
| **136** | ilsos.gov | Public Domain Land Tract Sales Database - Illinois |
| **137** | criminalcheck.com | Sex Offenders - CriminalCheck |
| **138** | reviewcentre.com | Consumer Review & Price Comparison - Review Centre |
| **139** | myyearbook.com | Personal Profile - MeetMe |
| **140** | nummar.fo | White Pages - Nummar.fo |
| **141** | buttecourt.ca.gov | Court Case Record - Butte County, California |
| **142** | co.bibb.ga.us | Property Ownership Inquiry - Bibb County, GA |
| **143** | maricopa.gov | Property Records - Maricopa County, Arizona |
| **144** | abish.byui.edu | Death Certificates - Special Collections |
| **145** | miamidade.gov | Property Tax Information - Miami Dade County, FL |
| **146** | genealogy.az.gov | Birth and Death Certificates - Arizona Genealogy |
| **147** | friendster.com | Social Networking Profile - Friendster |
| **148** | ning.com | Member's Profile - Ning.com |
| **149** | medium | Read and Write Things That Matter - Medium |
| **150** | strava | Track athletic activity - Strava |
| **151** | Infospace | White Pages - Infospace |
| **152** | fotki | Online Photo Album - Fotki |
| **153** | friend finder | Dating Person Record - Friend Finder |
| **154** | sonico.com | Personal Profile - Sonico |
| **155** | badoo.com | Photos, Videos & Personal Profile - Badoo |
| **156** | flixster.com | Movie Fan Profile - Flixster |
| **157** | care2.com | Green Living Community Personal Profile - Care2 |
| **158** | irc-galleria.net | Photos And Personal Profile - IRC-Galleria |
| **159** | perfspot.com | Personal Profile - PerfSpot |
| **160** | skyrock.com | Blogging and Personal Profile - Skyrock.com |
---
## Data Types
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faCheck, faMobile, faPhone, faEnvelope, faUsers, faBirthdayCake, faTransgender, faMapMarker, faBriefcase, faGraduationCap, faCar, faLink, faLanguage, faThumbTack, faExternalLinkSquare, faGlobe, faImage, faRing, faHeartCrack, faSkull, faHouse, faIdCard, faUserDoctor } from '@fortawesome/free-solid-svg-icons';
Our API returns a wide range of data types for each query. These data types contain what we know about the person you’re looking for. Each field comes from our records, our data sources, or is inferred using advanced statistical analysis. If a field is [inferred](inferred-data), it will be marked as inferred. You also can turn off this feature.
This page explains the kinds of data you can expect to receive in search results. For a technical explanation of each field, please refer to our [full API reference](/reference/data-fields).
Note that a response can be variable and not contain all the data types you might be looking for. To only pay for responses that contain the data types you want, specify match requirements with your [match criteria](/reference/match-criteria).
| **Field** | **CONTACT** | **SOCIAL** | **BUSINESS** |
| ------------- | ----------- | ---------- | ------------ |
| [Name](/reference/name)Current name as well as maiden name and nicknames. | | | |
| [Email addresses](/reference/email)Full email addresses. Personal and Work emails. | | | |
| [Phones](/reference/phone)Phone numbers. Current and past, mobile and landline , home and office.*CONTACT and SOCIAL keys do not include mobile phones . The BUSINESS key includes all phone types including mobile.* | * | * | |
| [Usernames](/reference/username)Usernames in use online by the person. This includes screen names, handles, and nicknames from across the web, social media sites, forums, and more. | | | |
| [Images](/reference/image)Image URL of profile images and other images that are related to the person. | | | |
| [Age](/reference/date-of-birth)Date of Birth results might be given as a range if the exact date is unknown. | | | |
| [Gender](/reference/gender)Male or Female | | | |
| [Addresses](/reference/address)Home and work, current and past addresses associated with the person. Includes house number, street, city, ZIP code, state, and country. | | | |
| [Career](/reference/job)Current and past jobs. Includes the Period, Job Title and Organization. | | | |
| [Education](/reference/education)Degrees from various schools. Includes the Institution, Degree, and the Period. | | | |
| [Vehicles](/reference/vehicle)Vehicles owned by the individual. | | | |
| [Associates](/reference/relationship)Friends, family, colleagues, social media followers, and other people associated with the person. | | | |
| [Language](/reference/language)Languages spoken by the individual. | | | |
| [Origin Country](/reference/origin-country)An individual's ancestral country. | | | |
| [Related URLs](/reference/url)URL of pages related to the person. Includes social profiles, professional licenses, publications, phone directories, court records, blogs, and much more. | | | |
Pipl may also return the following data, some of which appears in [tags](pipl-api-tags)):
| **Data** | **CONTACT** | **SOCIAL** | **BUSINESS** |
| ------------- | ----------- | ---------- | ------------ |
| Marriage and divorce records | | | |
| Deceased information | | | |
| US properties information such as ownership, APN and tax assessed value | | | |
| A Brazilian ID (CPF) for Brazilian individuals | | | |
| A National Provider Identity (NPI) for medical professionals | | | |
---
## Frequently Asked Questions
## How do you bill for API usage?
Billing is simple. You are charged only when the API response includes a match to your query. A match can be a person or a list of possible persons that meet your criteria (see below). Each API response that meets your criteria will be charged once. Whether the list of possible persons contains 3 or the maximum of 50 people, you are charged only once per response.
The cost per match depends on the API plan you use to make the query.
> 🚧 Duplicates are charged
>
> Every query that returns a match is charged. Because Pipl's unique Identity Resolution engine continuously obtains new data, a query performed today might return a different result in an hour, day, or even a month later. For this reason, each query represents a new search.
## Can I define what's considered a match?
Yes! You're in complete control of what qualifies as a match for your account. The options you have to define your match are:
### Must-have data types
You decide which types of data must be returned to constitute a match. For example, "a match must include an email address or phone number."
You'll only receive and be billed for API responses that include your minimum fields—everything else is ignored.
You can make the criteria as simple or as complex as needed. For example, you can simply specify that you require email addresses. Or, you can create nested requirements, such as: "name AND address AND (email OR phone)". For more information about constructing match requirements criteria, please visit our [Match Criteria Parameters](/reference/match-criteria) section in the API reference.
### Minimum match
Set the minimum confidence level desired for your API response to be considered a match. The default is 0.
An API response can include one or both of:
- **Person object (definite match)**: This is a single person who is the person you're looking for with all of their information.
- **Possible persons (possible match)**: This is a list of people who might be the person you're looking for. Each possible person includes summary data and search pointers for a follow-up search.
- You can raise or lower your minimum match to include or exclude possible persons. Setting your minimum match to 1 means only definite matches (person objects) will be returned.
### Minimum probability
This parameter allows you to set a minimum confidence level for the data returned in a match.
In some cases, we can use statistical models to infer part or all of the data—such as email address or gender—for the person you’re querying.
You can raise or lower your minimum probability to include or exclude inferred data. Setting your minimum probability to 1 means no inferred data will be used to determine a match or be included in matches. For more information, please see [Inferred Data]inferred-data).
## How many calls can I make per second?
Queries made with live_feeds allow up to 10 asynchronous parallel calls per second. Queries without live_feeds allow up to 20 asynchronous parallel calls per second. You can learn more about this [here](/docs/rate-limiting).
If these limits hinder your API usage, you can create custom settings. Please contact your Account Director or Integration Specialist to learn how.
## How fast is the API response time?
Our API typically returns results in \<1 second for queries that do not use live_feeds and \<2 seconds for queries with live_feeds.
## Where does Pipl get its data?
Pipl gathers data from sources such as public records, business listings, marketing lists, phone directories, and crowd-sourced data. Pipl also extracts facts and other relevant information from web documents, personal profiles, blogs, news articles, and publications. Data gathered from all sources is cleansed, merged, and clustered to create more than three billion detailed online identities. For more information, please see [Data Sources]data-sources).
## How accurate is Pipl's data?
In short, very accurate. Pipl combines and cross-references data from more than one million publicly available sources. Although it is difficult to effectively verify the accuracy of each data field in more than 25 billion records, Pipl still delivers higher accuracy than other people-data providers.
## What about privacy?
Understanding the potential sensitivity of people's data makes privacy critical for us. The API only provides information already publicly available from free or paid sources. For more information, please see [Pipl's Privacy Center](https://pipl.com/privacy-center).
## Can I add multiple users to my Pipl account?
Yes, you can create multiple users for one Pipl account. Simply sign up for an account and invite additional users in your [account area](https://pipl.com/accounts/manage-users/users/). Be sure to set them as administrators to have access to the API keys.
## Can I use MD5 hashes to query the API instead of full email addresses?
When information privacy is important, an email address can be sent as an MD5. See the [Email](/reference/email) section in the API reference for instructions on MD5 calculation guidelines. However, we suggest sending the full email address when possible to enhance the value of possible results and inferred data in case we don't have an exact email match.
## Can I use Pipl to query social network services?
You can query Pipl using the username, user_id, or URL of the social service.
You can search for the username across all social network services or by specifying the specific service with an @service suffix, where "service" is the name of the service. For a list of all the supported social network services, please see [User ID](/reference/user-id) in the API reference.
---
## Inferred Data
Our people data is source-validated, meaning that every piece of information originates from records in one or more of our data sources. Full details of these sources are available in the API response.
In addition to source-validated data, we offer inferred data. This data might not be validated by a source, but based on our advanced statistical model it is highly likely to be correct.
Inferred data is useful when information does not have to be precisely accurate, such as when it's used for marketing purposes. You can set the accuracy level that fits your application or turn this feature off. Note that whenever a data element—or even part of an element is inferred, Pipl clearly marks it as “inferred” so you can easily separate it from source-validated data.
Examples of inferred data:
- Gender from Name
- Location from Phone number
- Workplace from Email address
You can use the [minimum_probability and infer_persons parameters](/reference/configuration-parameters) to define when the Search API returns inferred data.
For more information about inferred data, see [Get data outta thin air](https://pipl.com/resources/blog/data-outta-thin-air).
---
## API Key Security - Best Practices

## You are responsible for your key protection.
Keys are directly connected to your account and accrued usage is charged at the end of each billing cycle. It is imperative to make sure active keys are stored securely on your system with access only to trusted personnel in your organization.
_If you suspect your key is compromised, deactivate your key immediately and generate a new key. Please [contact us online](https://pipl.com/customer-support) or contact your Account Manager ASAP. We can help you locate potential culprits._
:::info IP Address Allowlisting Available
As a robust security addition, Pipl can provide an allowlist of IP addresses (also known as whitelisting). By providing your list of IPs, we can ensure that only your API keys may be used by the listed IP addresses. Simply [contact us](https://pipl.com/customer-support) to add the IP addresses you require.
:::
## 7 Quick Best Practice DO’s
1. DO deactivate old/unused keys.
2. DO deactivate any key you suspect is compromised IMMEDIATELY from the [API management console](https://search.pipl.com/api/manage/keys/). Then create a new key only if needed.
3. DO review your logs regularly for suspicious key use.
4. DO only use secure methods to send your key such as encrypted email, encrypted documents, encrypted text messages, etc).
5. DO use the only last four digits when communicating your key to appropriate parties. Even if you’re communicating with Pipl, please only use the last 4 characters of your key.
## Best Practice DO NOT’s
1. DO NOT store your API key in public facing source code repositories such as public Github’s.
2. DO NOT store your API key in phone apps, browsers or any software running outside your secure control. It can be cracked using tools such as sniffers, HTML viewers, hex viewers, etc.
3. DO NOT send your full API key in email.
4. DO NOT store your API key in an insecure hard drive or network resource.
5. DO NOT reveal your key to employees or contractors who do not need to know.
## Secondary Best practices DO’s:
1. DO use separate keys for separate functions/business units to isolate & analyze key usage.
2. If building mobile Apps, browser apps and/or uncontrolled software, DO store your key in your network servers and force your remote app to call your server to get the Pipl API data. If the key is always on your server, it’s more secure.
3. DO only expose your key to relevant employees/contractors. Two sets of keys can be created, one for production and one for development/other.
4. DO make sure the admins on your Pipl account are related to your organization and are authorized to handle sensitive data.
5. DO set [quotas on your keys](/docs/rate-limiting#key-quota-limits).
6. DO keep a strong password on your Pipl login account. If they can hack your portal, all of your keys are exposed.
7. DO store your keys on secure devices/servers inside your controlled network with appropriate permissions.
8. DO draft and enforce a key storage policy within your organization.
## Key Attack Vectors
- Insecure network handling, lack of HTTPS or using GET for API calls.
- Clear text reveal via email or insecure document handling.
- Poor application design which reveals your keys over TCP/IP such as phone app or browser.
- Employees or contractors leaking keys.
---
## Best Practices By Use Case
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
# Best Practices by Use Case
Pipl Search applies to a variety of use cases. Each use case has unique objectives and requirements, as well as preferred ways of working with the Pipl Search API. This article provides recommendations based on successful approaches for key use cases. This provides a starting point for integration and optimization efforts; adapt it based on your specific goals and requirements.
## Contact Enrichment
The contact enrichment use case is using the Pipl Search API to add new data points to an existing profile or contact. New data might include contact information such as phone numbers, email addresses or social media profiles.
To return the most relevant results for each contact, limit queries to only those that have the information you need. To do this, [set your match requirements](/reference/match-criteria#match-requirements) appropriately. For example if you are enriching contacts with social media profiles, you can limit the query to only return matches for people that have a social media profile:
`match_requirements=social_profiles`
Use boolean operators (`OR` and `AND`) to further refine the match requirements.
### Recruiting
#### LinkedIn to Contact Information
LinkedIn URLs, usernames or UserIDs are often sufficient, on their own, to match to a profile and find contact information. You can also try adding supplementary demographic information such as a name and location (even just a country or country + state). The [sources layer](/reference/know-your-sources) includes tags for professional skills and courses that may be relevant to your application.
_Recommended Parameters:_
- `minimum match=1.0` (for LinkedIn alone) or `top_match=true` when including demographic info
- `match_requirements= 'phone OR email'`
- `live_feeds=false` (except for low volume/throughput)
- `show_sources=matching`
```python
SearchAPIRequest.set_default_settings(api_key=u'YOURKEY', minimum_match=1.0,
match_requirements='phone OR email', live_feeds=False, show_sources='matching')
request = SearchAPIRequest(url='https://www.linkedin.com/in/clarkkent')
response = request.send()
contact_phone_1 = response.person.phones[0].number
contact_email_1 = response.person.emails[0].address
```
```ruby
Pipl.configure do |c|
c.api_key = 'YOURKEY'
c.minimum_match = 1.0
c.match_requirements = 'phone OR email'
c.live_feeds = false
c.show_sources = 'matching'
end
response = Pipl::client.search url: 'https://www.linkedin.com/in/clarkkent'
contact_phone_1 = response.person.phones[0].number
contact_email_1 = response.person.emails[0].address
```
```java
import com.pipl.api.search.SearchAPIRequest;
import com.pipl.api.search.SearchAPIResponse;
import com.pipl.api.search.SearchConfiguration;
SearchConfiguration defaultConfiguration = SearchAPIRequest.getDefaultConfiguration();
defaultConfiguration.apiKey = "YOURKEY";
defaultConfiguration.minimumMatch = 1.0;
defaultConfiguration.matchRequirements = "phone OR email";
defaultConfiguration.liveFeeds = false;
defaultConfiguration.showSources = "matching";
SearchAPIRequest request = new SearchAPIRequest.Builder()
.url("https://www.linkedin.com/in/clarkkent")
.configuration(defaultConfiguration)
.build();
SearchAPIResponse response = request.send();
String contactPhone1 = response.getPerson().getPhones().get(0).getNumber();
String contactEmail1 = response.getPerson().getEmails().get(0).getAddress();
```
```php
api_key = "YOURKEY";
PiplApi_SearchAPIRequest::get_default_configuration()->minimum_match = 1.0;
PiplApi_SearchAPIRequest::get_default_configuration()->match_requirements = "phone OR email";
PiplApi_SearchAPIRequest::get_default_configuration()->live_feeds = false;
PiplApi_SearchAPIRequest::get_default_configuration()->show_sources = "matching";
$request = new PiplApi_SearchAPIRequest(array('url' => 'https://www.linkedin.com/in/clarkkent'));
$response = $request->send();
$contact_phone_1 = $response->person->phones[0]->number;
$contact_email_1 = $response->person->emails[0]->address;
?>
```
```csharp
using Pipl.APIs.Search;
SearchConfiguration defaultConfiguration = SearchAPIRequest.DefaultConfiguration;
defaultConfiguration.ApiKey = "YOURKEY";
defaultConfiguration.MinimumMatch = 1.0;
defaultConfiguration.MatchRequirements = "phone OR email";
defaultConfiguration.LiveFeeds = false;
defaultConfiguration.ShowSources = "matching";
SearchAPIRequest request = new SearchAPIRequest(url: "https://www.linkedin.com/in/clarkkent",
requestConfiguration: defaultConfiguration);
var response = await request.SendAsync();
string contactPhone1 = response.Person.Phones[0].Number;
string contactEmail1 = response.Person.Emails[0].Address;
```
```bash
curl "https://api.pipl.com/search/?key=YOURKEY&minimum_match=1.0&match_requirements=phone%20OR%20email&live_feeds=false&show_sources=matching&url=https%3A%2F%2Fwww.linkedin.com%2Fin%2Fclarkkent"
```
#### Name and Job to Contact Info
Searching by job requires using a full person search; See [Searching by job]searching-by-specific-parameters#jobeducation). If you have job history, consider adding multiple jobs to increase the probability that Pipl Search finds the individual. Adding a LinkedIn profile, if you have it, may increase your match rate (see the [Linkedin to Contact Information]best-practices-by-use-case#recruiting) section above). When searching for work email addresses, you can get a greater fill of inferred work emails by reducing the threshold needed for an inferred email to be included in a response (with parameter `minimum_probability`).
_Recommended Parameters:_
- `top_match=true`
- `match_requirements='phone OR email'`
- `live_feeds=false` (except for low volume/throughput)
- `minimum_probability=0.6`
```python
SearchAPIRequest.set_default_settings(api_key=u'YOURKEY', top_match=True,
match_requirements='phone OR email', live_feeds=False, minimum_probability=0.6)
```
```ruby
Pipl.configure do |c|
c.api_key = 'YOURKEY'
c.top_match = true
c.match_requirements = 'phone OR email'
c.live_feeds = false
c.minimum_probability = 0.6
end
```
```java
import com.pipl.api.search.SearchAPIRequest;
import com.pipl.api.search.SearchConfiguration;
SearchConfiguration defaultConfiguration = SearchAPIRequest.getDefaultConfiguration();
defaultConfiguration.apiKey = "YOURKEY";
defaultConfiguration.topMatch = true;
defaultConfiguration.matchRequirements = "phone OR email";
defaultConfiguration.liveFeeds = false;
defaultConfiguration.minimumProbability = 0.6;
```
```php
api_key = "YOURKEY";
PiplApi_SearchAPIRequest::get_default_configuration()->top_match = true;
PiplApi_SearchAPIRequest::get_default_configuration()->match_requirements = "phone OR email";
PiplApi_SearchAPIRequest::get_default_configuration()->live_feeds = false;
PiplApi_SearchAPIRequest::get_default_configuration()->minimum_probability = 0.6;
?>
```
```csharp
using Pipl.APIs.Search;
SearchConfiguration defaultConfiguration = SearchAPIRequest.DefaultConfiguration;
defaultConfiguration.ApiKey = "YOURKEY";
defaultConfiguration.TopMatch = true;
defaultConfiguration.MatchRequirements = "phone OR email";
defaultConfiguration.LiveFeeds = false;
defaultConfiguration.MinimumProbability = 0.6;
```
```bash
# Set these parameters in your API requests:
# top_match=true&match_requirements=phone%20OR%20email&live_feeds=false&minimum_probability=0.6
```
### Real Estate
A common use-case for the Search API in real estate is to find contact or social media information for the owner or resident of an address. To do this, use [the address](/reference/address) and any other information you have on the person as the query input. While a US Address alone meets [the minimum requirements](/reference/request-overview#minimum-requirements) for a query, this type of search will usually return a [possible person response](/reference/response-types#possible-person), since there are almost always multiple people connected to a single address (multiple residents, previous residents, owner and renter). Include a name and/or other information to help the API determine which of those connected people is the individual you are searching for.
To ensure the API reads the address correctly, we recommend splitting it into individual components (country, state, city, zip, street & house) to send to the API. The API can also take an address in raw form (the full address in a single input parameter), but you will need to verify that our API is parsing correctly for your address format.
For US addresses, [the source layer](/reference/know-your-sources) includes [tags]pipl-api-tags) for home ownership (apn), most recent sale, and home type. This information can be used to verify current home ownership. Search for tags with the classifications 'apn', 'last_sale_date' and 'type'. See [popular tag classifications for more details]pipl-api-tags#popular-tag-classifications).
_Recommended Parameters:_
- `top_match=true`
- `match_requirements= 'phone OR email OR social_profiles'`
- `show_sources=all`
- `live_feeds=true`(depends on expected volume/throughput)
```python
SearchAPIRequest.set_default_settings(api_key=u'YOURKEY', top_match=True,
match_requirements='phone OR email OR social_profiles', show_sources='all', live_feeds=True)
```
```ruby
Pipl.configure do |c|
c.api_key = 'YOURKEY'
c.top_match = true
c.match_requirements = 'phone OR email OR social_profiles'
c.show_sources = 'all'
c.live_feeds = true
end
```
```java
import com.pipl.api.search.SearchAPIRequest;
import com.pipl.api.search.SearchConfiguration;
SearchConfiguration defaultConfiguration = SearchAPIRequest.getDefaultConfiguration();
defaultConfiguration.apiKey = "YOURKEY";
defaultConfiguration.topMatch = true;
defaultConfiguration.matchRequirements = "phone OR email OR social_profiles";
defaultConfiguration.showSources = "all";
defaultConfiguration.liveFeeds = true;
```
```php
api_key = "YOURKEY";
PiplApi_SearchAPIRequest::get_default_configuration()->top_match = true;
PiplApi_SearchAPIRequest::get_default_configuration()->match_requirements = "phone OR email OR social_profiles";
PiplApi_SearchAPIRequest::get_default_configuration()->show_sources = "all";
PiplApi_SearchAPIRequest::get_default_configuration()->live_feeds = true;
?>
```
```csharp
using Pipl.APIs.Search;
SearchConfiguration defaultConfiguration = SearchAPIRequest.DefaultConfiguration;
defaultConfiguration.ApiKey = "YOURKEY";
defaultConfiguration.TopMatch = true;
defaultConfiguration.MatchRequirements = "phone OR email OR social_profiles";
defaultConfiguration.ShowSources = "all";
defaultConfiguration.LiveFeeds = true;
```
```bash
# Set these parameters in your API requests:
# top_match=true&match_requirements=phone%20OR%20email%20OR%20social_profiles&show_sources=all&live_feeds=true
```
## Investigation and Background Checks
Routine background checks, criminal and OSint investigations use Pipl Search to uncover as much useful information as possible on an applicant or person of interest.
While you can run a search with just a single piece of information (see [minimum search requirements](/reference/request-overview#minimum-requirements) ), including as much information as possible in your query will generally connect to more records and return more data in your response. [The sources layer](/reference/know-your-sources) can provide additional data and context to your person of interest.
_Recommended Parameters:_
- `show_sources=all`
\*`live_feeds=true` (up to 10 QPS)
```python
SearchAPIRequest.set_default_settings(api_key=u'YOURKEY', show_sources='all', live_feeds=True)
```
```ruby
Pipl.configure do |c|
c.api_key = 'YOURKEY'
c.show_sources = 'all'
c.live_feeds = true
end
```
```java
import com.pipl.api.search.SearchAPIRequest;
import com.pipl.api.search.SearchConfiguration;
SearchConfiguration defaultConfiguration = SearchAPIRequest.getDefaultConfiguration();
defaultConfiguration.apiKey = "YOURKEY";
defaultConfiguration.showSources = "all";
defaultConfiguration.liveFeeds = true;
```
```php
api_key = "YOURKEY";
PiplApi_SearchAPIRequest::get_default_configuration()->show_sources = "all";
PiplApi_SearchAPIRequest::get_default_configuration()->live_feeds = true;
?>
```
```csharp
using Pipl.APIs.Search;
SearchConfiguration defaultConfiguration = SearchAPIRequest.DefaultConfiguration;
defaultConfiguration.ApiKey = "YOURKEY";
defaultConfiguration.ShowSources = "all";
defaultConfiguration.LiveFeeds = true;
```
```bash
# Set these parameters in your API requests:
# show_sources=all&live_feeds=true
```
### Reverse relationship searches
Use reverse relationship searches to discover more about a person you find in the relationship section of a Pipl Search result. Say you are searching for Alex Jensen and you see in your API response that he has a family relationship with Brian Jensen and you want to find out more about him. To do this, swap the name element with the relationship element from the API response, in this case name is "Brian Jensen" and the relationship to "Alex Jensen".

See [how to perform a search using the relationship parameter ]searching-by-specific-parameters#relationship)
## Identity Investigation and Fraud
The Search API can be used in fraud investigation and identity resolution to confirm whether specific data points connect to an individual and to build a full picture of the identity behind a piece of data. In addition, the data from Pipl search can be used in decisioning engines or machine learning models to calculate fraud risk scores.
It is especially important in these use cases to make sure that all query parameters provided to the API are known to be accurate and connected to the person you are searching for. Leave out any data points that are not certain to be connected to a person.
> 📘 Pipl Trust
>
> [Pipl Trust](https://trust.pipl.com) is another suite in the Pipl portfolio. It scores the risk of a data point or action using identity, connectivity, behavioral, and device signals — powered by Elephant, Pipl's large risk model.
For more information about using Pipl Search as part of a machine learning model see [Using-Pipl-Search-in-Machine-Learning-and-Data-Driven-Decisioning]using-pipl-search-in-machine-learning-and-data-driven-decisioning)
### Data Point Validation
One common use of the Pipl Search API in the fraud investigation and identity resolution space is to validate whether certain data points connect to an individual. For example if you have a user account and the phone number changes, you want to validate if that new phone number is connected to the account owner. When doing this, separate your data into two categories: 1. Known data with a confirmed link to the individual and 2. Data to be verified. Only send the known data in the search query, then in the response, check for the data you are trying to confirm.
Pipl Search does not have 100% fill of all data points, so not finding the data point in the response is not definitive proof that it is not connected to the individual.
Expect lower latency responses for searches by just a phone or email address.
It may be helpful to see [the source layer](/reference/know-your-sources) to check what source was used to validate the data point.
_Recommended Parameters:_
- `live_feeds=false` (except for low volume/throughput)
- `minimum_probability=0`
- `show_sources=all`
```python
SearchAPIRequest.set_default_settings(api_key=u'YOURKEY', show_sources='all', live_feeds=False, minimum_probability=0)
```
```ruby
Pipl.configure do |c|
c.api_key = 'YOURKEY'
c.show_sources = 'all'
c.live_feeds = false
c.minimum_probability = 0
end
```
```java
import com.pipl.api.search.SearchAPIRequest;
import com.pipl.api.search.SearchConfiguration;
SearchConfiguration defaultConfiguration = SearchAPIRequest.getDefaultConfiguration();
defaultConfiguration.apiKey = "YOURKEY";
defaultConfiguration.showSources = "all";
defaultConfiguration.liveFeeds = false;
defaultConfiguration.minimumProbability = 0.0;
```
```php
api_key = "YOURKEY";
PiplApi_SearchAPIRequest::get_default_configuration()->show_sources = "all";
PiplApi_SearchAPIRequest::get_default_configuration()->live_feeds = false;
PiplApi_SearchAPIRequest::get_default_configuration()->minimum_probability = 0;
?>
```
```csharp
using Pipl.APIs.Search;
SearchConfiguration defaultConfiguration = SearchAPIRequest.DefaultConfiguration;
defaultConfiguration.ApiKey = "YOURKEY";
defaultConfiguration.ShowSources = "all";
defaultConfiguration.LiveFeeds = false;
defaultConfiguration.MinimumProbability = 0;
```
```bash
# Set these parameters in your API requests:
# show_sources=all&live_feeds=false&minimum_probability=0
```
### Identity Discovery and Scoring
Another investigation use case is to try to build a profile for the identity behind a data point and, in some cases, provide a score for that identity.
You may want to access the source layer to be able to include tag data such as vehicle and home ownership and professional credentials in your analysis.
_Recommended Parameters:_
- `live_feeds=false` (except for low volume/throughput)
- `minimum_probability=0`
- `show_sources=all`
```python
SearchAPIRequest.set_default_settings(api_key=u'YOURKEY', show_sources='all', live_feeds=False, minimum_probability=0)
```
```ruby
Pipl.configure do |c|
c.api_key = 'YOURKEY'
c.show_sources = 'all'
c.live_feeds = false
c.minimum_probability = 0
end
```
```java
import com.pipl.api.search.SearchAPIRequest;
import com.pipl.api.search.SearchConfiguration;
SearchConfiguration defaultConfiguration = SearchAPIRequest.getDefaultConfiguration();
defaultConfiguration.apiKey = "YOURKEY";
defaultConfiguration.showSources = "all";
defaultConfiguration.liveFeeds = false;
defaultConfiguration.minimumProbability = 0.0;
```
```php
api_key = "YOURKEY";
PiplApi_SearchAPIRequest::get_default_configuration()->show_sources = "all";
PiplApi_SearchAPIRequest::get_default_configuration()->live_feeds = false;
PiplApi_SearchAPIRequest::get_default_configuration()->minimum_probability = 0;
?>
```
```csharp
using Pipl.APIs.Search;
SearchConfiguration defaultConfiguration = SearchAPIRequest.DefaultConfiguration;
defaultConfiguration.ApiKey = "YOURKEY";
defaultConfiguration.ShowSources = "all";
defaultConfiguration.LiveFeeds = false;
defaultConfiguration.MinimumProbability = 0;
```
```bash
# Set these parameters in your API requests:
# show_sources=all&live_feeds=false&minimum_probability=0
```
[Pipl Trust](https://trust.pipl.com) is another suite in the Pipl portfolio. It scores the risk of a data point or action based on connections between elements, associated profiles, and other signals — powered by Elephant, Pipl's large risk model.
## General Recommendations
### Performance Optimization
Depending on the metrics that are most important to your application, there are different configuration strategies you can use. Often optimizing for one metric comes with trade-offs in another metric, so be sure to balance your approach according to your priorities.
### Optimizing for Match and Fill Rates
In general, the more data you provide in search query parameters, the better the match and fill rate will be on a search response. Try adding more information about the person to the query. For example, if you’ve searched by email address alone, try adding the name and location to the query. Adding even just a country or a country + state to a search query can significantly increase the match and fill rate.
When searching for individuals in the US, turning on live feeds can also slightly increase your match and fill rates. Live feeds are data partners outside of Pipl's infrastructure that can provide additional data (approximately 2-3% more) specifically within the USA. Please note that this will come with the downside of increased latency and [decreased throughput](/docs/rate-limiting-your-queries).
### Optimizing Query Speed
The most important factor to increase speed is to turn off live feeds. This will both decrease latency and increase your [throughput rate limit](/docs/rate-limiting-your-queries) You can do this by setting the parameter 'live_feeds' to 'false'. Please note that turning off live feeds will lead to a slight reduction in data match and fill rates (see Optimizing for Match and Fill Rates section above)
If low latency is your top priority, there are a few single-parameter queries that will run faster than multi-parameter queries. These include phone-only, email-only and address-only queries. Keep in mind that these single parameter queries come with significant trade-offs in terms of match and fill rate, so be sure that the benefit in latency is worth the cost of data fill.
---
## Searching by Address
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
# Searching by Address
This guide walks through the best practices for using an address or location as an input parameter of a Search API query
## Using the Address Parameters
The best way to include an [address](/reference/address) into an API query is to separate it into individual fields (`house, street, city, state, country, zip_code`). This ensures that the address is parsed correctly.
If it is not possible to separate the address into individual fields, there is also the option to use the `raw address` field to pass the full address. The Search API will do its best to interpret the address into the separate fields for the query. The address should be comma separated and follow the standard formatting of the country. If the address is outside of the US, you must include the two-digit country code at the end of the address for it to be parsed correctly. Check the [query field in an API response](/reference/response) to see how the API parsed your address and ensure that it was done correctly.
Below are some examples of addresses that can be parsed successfully by the Search API in the `raw_address` field:
- `510 S Clearwater Loop, Post Falls, ID, 83854, US`
- `1600 Pennsylvania Avenue NW, Washington, DC 20500`
- `2 Gabriel Avenue, 75008 Paris, FR`
> 🚧 Meeting Minimum Search Criteria
>
> In the US, a full street address (down to the house number) can be searched by itself. Outside the US, you must include at least one other required parameter in order to fulfil the [minimum requirements](/reference/request-overview#minimum-requirements) for a valid search
## Partial Addresses
Even if you do not have the full street address of a person, if you are able to include location information in a query in the form of a partial address, this can significantly improve your results.
For example, if you are searching by a combination of name + email address, but you have information on the country of these individuals, consider adding this information into the query using the `country` field. If you have details of location down to the state or city level, this will likely improve the results even further.
### Examples
```text
//Example 1: Country only
email=clark.kent@example.com&country=US
//Example 2: Country, State and City
email=clark.kent@example.com&country=US&state=NY&city=New York City
```
```text
//Example 1: Country only
https://api.pipl.com/search/?key=YOUR-API-KEY&email=clark.kent@example.com&country-US
//Example 2: Country, State and City
https://api.pipl.com/search/?key=YOUR-API-KEY&email=clark.kent@example.com&country-US&state=NY&city=New York City
```
```python
from piplapis.data import Person, Email, Address
from piplapis.search import SearchAPIRequest
#Example 1: Country only
fields = [Email(address='clark.kent@example.com'), Address(country='US')]
request = SearchAPIRequest(person=Person(fields=fields), api_key='YOUR-API-KEY')
response = request.send()
#Example 2: Country, State and City
fields = [Email(address='clark.kent@example.com'), Address(country='US', state='NY', city='New York City')]
request = SearchAPIRequest(person=Person(fields=fields), api_key='YOUR-API-KEY')
response = request.send()
```
```ruby
require 'pipl'
#Example 1: Country only
person = Pipl::Person.new
person.add_field Pipl::Email.new(address: 'clark.kent@example.com')
person.add_field Pipl::Address.new(country: 'US')
response = Pipl::client.search person: person, api_key: 'YOUR-API-KEY'
#Example 2: Country, State and City
person = Pipl::Person.new
person.add_field Pipl::Email.new(address: 'clark.kent@example.com')
person.add_field Pipl::Address.new(country: 'US', state: 'NY', city: 'New York City')
response = Pipl::client.search person: person, api_key: 'YOUR-API-KEY'
```
```java
import java.util.ArrayList;
import java.util.List;
import com.pipl.api.search.SearchAPIRequest;
import com.pipl.api.data.containers.Person;
import com.pipl.api.data.fields.*;
import com.pipl.api.search.SearchConfiguration;
SearchConfiguration configuration = new SearchConfiguration();
configuration.setProtocol("https");
configuration.apiKey = "YOUR-API-KEY";
//Example 1: Country only
List fields = new ArrayList();
fields.add(new Email.Builder().address("clark.kent@example.com").build());
fields.add(new Address.Builder().country("US").build());
Person person = new Person(fields);
SearchAPIRequest request = new SearchAPIRequest(person, configuration);
SearchAPIResponse response = request.send();
//Example 2: Country, State and City
fields = new ArrayList();
fields.add(new Email.Builder().address("clark.kent@example.com").build());
fields.add(new Address.Builder().country("US").state("NY").city("New York City").build());
person = new Person(fields);
request = new SearchAPIRequest(person, configuration);
response = request.send();
```
```php
use_https = true;
$configuration->api_key = 'YOUR-API-KEY';
//Example 1: Country only
$fields = array(
new PiplApi_Email(array("address" => "clark.kent@example.com")),
new PiplApi_Address(array("country" => "US"))
);
$person = new PiplApi_Person($fields);
$request = new PiplApi_SearchAPIRequest(array('person' => $person), $configuration);
$response = $request->send();
//Example 2: Country, State and City
$fields = array(
new PiplApi_Email(array("address" => "clark.kent@example.com")),
new PiplApi_Address(array("country" => "US", "state" => "NY", "city" => "New York City"))
);
$person = new PiplApi_Person($fields);
$request = new PiplApi_SearchAPIRequest(array('person' => $person), $configuration);
$response = $request->send();
?>
```
```csharp
using Pipl.APIs.Search;
using System.Collections.Generic;
SearchConfiguration searchConfiguration = new SearchConfiguration(
apiKey: "YOUR-API-KEY",
url: "api.pipl.com/search/",
useHttps: true
);
//Example 1: Country only
List fields = new List()
{
new Email(address: "clark.kent@example.com"),
new Address(country: "US")
};
var person = new Person(fields);
SearchAPIRequest request = new SearchAPIRequest(
person: person,
requestConfiguration: searchConfiguration
);
var response = await request.SendAsync();
//Example 2: Country, State and City
fields = new List()
{
new Email(address: "clark.kent@example.com"),
new Address(country: "US", state: "NY", city: "New York City")
};
person = new Person(fields);
request = new SearchAPIRequest(
person: person,
requestConfiguration: searchConfiguration
);
response = await request.SendAsync();
```
---
## Searching by Names
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
# Searching by Names
## Introduction
Names are the most common data field used in a Pipl Search query. However, they are also a common source of API errors, especially when used alone without any other data fields. Incorrectly formatted names may be parsed incorrectly leading to erroneous results and API warnings. This guide gathers some of the best practices on how to use names in your Pipl Search API queries.
You can send a name to Pipl Search in one of two ways:
- The first name, middle name/initial and last name, all in separate fields
- A single raw name field which will be automatically parsed into the first, middle name/initial and last name fields
### Examples
```text
//Using parsed name fields
first_name=Clark&middle_name=Joseph&last_name=Kent
//Using raw name field
raw_name=Clark Joseph Kent
```
```text
//Using parsed name fields
https://api.pipl.com/search/?key=YOUR-API-KEY&first_name=Clark&middle_name=Joseph&last_name=Kent
//Using raw name field
https://api.pipl.com/search/?key=YOUR-API-KEY&raw_name=Clark Joseph Kent
```
```python
from piplapis.data import Person, Name
from piplapis.search import SearchAPIRequest
#Using parsed name fields
fields = [Name(first='Clark', middle='Joseph', last='Kent')]
request = SearchAPIRequest(person=Person(fields=fields), api_key='YOUR-API-KEY')
response = request.send()
#Using raw name field (direct parameter)
request = SearchAPIRequest(raw_name='Clark Joseph Kent', api_key='YOUR-API-KEY')
response = request.send()
#Using raw name field (in Person object)
fields = [Name(raw='Clark Joseph Kent')]
request = SearchAPIRequest(person=Person(fields=fields), api_key='YOUR-API-KEY')
response = request.send()
```
```ruby
require 'pipl'
#Using parsed name fields
person = Pipl::Person.new
person.add_field Pipl::Name.new(first: 'Clark', middle: 'Joseph', last: 'Kent')
response = Pipl::client.search person: person, api_key: 'YOUR-API-KEY'
#Using raw name field (direct parameter)
response = Pipl::client.search raw_name: 'Clark Joseph Kent', api_key: 'YOUR-API-KEY'
#Using raw name field (in Person object)
person = Pipl::Person.new
person.add_field Pipl::Name.new(raw: 'Clark Joseph Kent')
response = Pipl::client.search person: person, api_key: 'YOUR-API-KEY'
```
```java
import com.pipl.api.search.SearchAPIRequest;
import com.pipl.api.search.SearchAPIResponse;
import com.pipl.api.data.containers.Person;
import com.pipl.api.data.fields.*;
import com.pipl.api.search.SearchConfiguration;
import java.util.ArrayList;
import java.util.List;
SearchConfiguration configuration = new SearchConfiguration();
configuration.setProtocol("https");
configuration.apiKey = "YOUR-API-KEY";
//Using parsed name fields
List fields = new ArrayList();
fields.add(new Name.Builder().first("Clark").middle("Joseph").last("Kent").build());
Person person = new Person(fields);
SearchAPIRequest request = new SearchAPIRequest(person, configuration);
SearchAPIResponse response = request.send();
//Using raw name field (direct parameter)
request = new SearchAPIRequest.Builder()
.rawName("Clark Joseph Kent")
.configuration(configuration)
.build();
response = request.send();
//Using raw name field (in Person object)
fields = new ArrayList();
fields.add(new Name.Builder().raw("Clark Joseph Kent").build());
person = new Person(fields);
request = new SearchAPIRequest(person, configuration);
response = request.send();
```
```php
use_https = true;
$configuration->api_key = 'YOUR-API-KEY';
//Using parsed name fields
$fields = array(
new PiplApi_Name(array("first" => "Clark", "middle" => "Joseph", "last" => "Kent"))
);
$person = new PiplApi_Person($fields);
$request = new PiplApi_SearchAPIRequest(array('person' => $person), $configuration);
$response = $request->send();
//Using raw name field (direct parameter)
$request = new PiplApi_SearchAPIRequest(
array('raw_name' => 'Clark Joseph Kent'),
$configuration
);
$response = $request->send();
//Using raw name field (in Person object)
$fields = array(
new PiplApi_Name(array("raw" => "Clark Joseph Kent"))
);
$person = new PiplApi_Person($fields);
$request = new PiplApi_SearchAPIRequest(array('person' => $person), $configuration);
$response = $request->send();
?>
```
```csharp
using Pipl.APIs.Search;
using System.Collections.Generic;
SearchConfiguration searchConfiguration = new SearchConfiguration(
apiKey: "YOUR-API-KEY",
url: "api.pipl.com/search/",
useHttps: true
);
//Using parsed name fields
List fields = new List()
{
new Name(first: "Clark", middle: "Joseph", last: "Kent")
};
var person = new Person(fields);
SearchAPIRequest request = new SearchAPIRequest(
person: person,
requestConfiguration: searchConfiguration
);
var response = await request.SendAsync();
//Using raw name field (direct parameter)
request = new SearchAPIRequest(
rawName: "Clark Joseph Kent",
requestConfiguration: searchConfiguration
);
response = await request.SendAsync();
//Using raw name field (in Person object)
fields = new List()
{
new Name(raw: "Clark Joseph Kent")
};
person = new Person(fields);
request = new SearchAPIRequest(
person: person,
requestConfiguration: searchConfiguration
);
response = await request.SendAsync();
```
## Basic Rules for Names
The basic rules regarding names in the Pipl API, and the validation thereof are as follows:
- When searched alone, names must include a first and last name. Because of Pipl’s worldwide index, a name alone will likely return many Possible Persons - especially if a name is very common. It is best practice to include other searchable fields such as a [high-level address](/reference/address) (e.g. with country and/or state and/or city) when available with a name to help narrow down the results.
- Both the first name and the last name must be at least 2 characters in length.
\*\* These conditions are relaxed with [partial name searches](/reference/name#partial-name-searching) as long as the [minimum search requirements](/reference/request-overview#minimum-requirements) are met by adding other searchable fields
- The middle name can be 1 or more characters in length. Initials are allowed with or without a dot suffix.
- The first, middle or last fields can include multiple names. These can be separated by spaces, or by a dash/hyphen (i.e double-barrel names).
- “Double-barrel” or “Triple-barrel” names should be sent using a dash/hyphen between the names (e.g. Van-Der-Bank)
- It is suggested to also try alternatives such as VanDerBank
- Foreign characters and special characters can be used for a search should they meet the minimum character length requirements. They will be parsed as UTF-8 encoded strings.
- Company names should not be used (the technology is used to search for a person), but they can be included [as a job](/reference/job) .
- Don’t include two people’s names in one, the identity resolution technology is used to find a single person
### How raw names are parsed
Pipl recommends sending the name parsed into the first, middle and last parts to dismiss any doubt as to how the name should be parsed. However in some cases, you might not have the name separated into first, middle and last, and would need to send the name in a single field to have the Pipl API parse out the name parts for you automatically. Sending the full name in a single field can be done by using the ‘raw’ name field in a [Person request](/reference/full-person) or [raw_name](/reference/name) in a search parameter request.
The “query” section of a Pipl Search API response shows how the API interpreted all the query fields sent to it including how raw names were parsed.

The parsing of names is straightforward for simple names that include first, middle and last name, all as a single string such as “Clark Joseph Kent” or “Clark J Kent”.
Example 1. Taking for example the name “Clark Joseph Kent”, the API parses names from the raw field in the following manner:
| Name Component | Detail | Example Parsed | Example Result |
| :------------- | :----------------------------------------------------------------------------------------------------------------- | :-------------------- | :------------- |
| First name | The first string token, up to the first space character | **Clark** Joseph Kent | Clark |
| Last Name | The last string token, from the last space character | Clark **Joseph** Kent | Kent |
| Middle Name | Anything between the first string token and the last string token ( excluding the first and last space characters) | Clark Joseph **Kent** | Joseph |
Example 2. Taking for example a name with a comma such as “Kent, Clark Joseph”, the API parses names from the raw field in the following manner:
| Name Component | Detail | Example Parsed | Example Result |
| :------------- | :--------------------------------------------- | :--------------------- | :------------- |
| First Name | The first string token after the comma | Kent, **Clark** Joseph | Clark |
| Last name | The first string token before the comma | **Kent**, Clark Joseph | Kent |
| Middle name | All string tokens after the first string token | Kent, Clark **Joseph** | Joseph |
> 📘 How are names searched on Pipl?
>
> When sending names in raw_name, the search engine, although parsing the name as described above, might attempt, in some cases, to switch first name and last name in order to find the person you are seeking. This might happen when the last name is a common first name, for example Jackson Curtis (parses to Curtis Jackson), Ryan Phillip (parses to Phillip Ryan).
>
> The search engine will recognize some surnames with more than one word (ie “De La Rocha” or “Von Welsbach”) and preserve them as the last name it extracts from a raw_name search. Due to the near infinite number of possible surnames this process is not perfect, but should hold for most compound surnames.
### Examples of raw name parsing
The following **valid raw names** illustrate how titles and names consisting of more than 3 words are parsed.
| Raw Name | Parsed First Name | Parsed Middle Name | Parsed Last Name |
| :----------------------------- | :---------------- | :----------------- | :--------------- |
| Clark Joseph Kent | Clark | Joseph | Kent |
| Clark J Kent | Clark | J | Kent |
| Ramon Antonio Gerard Estevez | Ramon | Antonio Gerard | Estevez |
| Daniel Michael Blake Day-Lewis | Daniel | Michael Blake | Day-Lewis |
| Dr. Victor Frankenstein\* | Victor | | Frankenstein |
| Professor Albert Einstein\* | Albert | | Einstein |
| Robert Downey Jr.\*\* | Robert | | Downey |
| Dench, Judi | Judi | | Dench |
| David Larry | Larry | | David |
| Zach De La Rocha | Zach | | De La Rocha |
| Zacarias Manuel De La Rocha | Zacarias | Manuel | De La Rocha |
| Jorge Dos Santos | Jorge | | Dos Santos |
- Pipl will parse the title to the sub-field ‘prefix’
\*\* Pipl will parse the suffix to the sub-field ‘suffix’
The following are examples of **invalid names**, unless searched as a [partial name](/reference/name#partial-name-searching) with additional search parameters included in the search.
| Raw Name | Error/Issue |
| :--------------- | :------------------------------------------- |
| C Kent | First name does not contain 2 characters. \* |
| Clark K. | Last name does not contain 2 characters. \* |
| Dr. Frankenstein | “Dr.” will be parsed as a first name. \* |
| R. Downey Jr. | First name does not contain 2 characters. \* |
- Cannot be searched alone, is however a valid partial name
## Partial name searches
[Partial name searches](/reference/name#partial-name-searching) in Pipl Search allow you to search with a portion of the name if the minimum query requirements have already been met with an additional field such as an email, phone or username.
| First | Middle | Last | Additional Data Field in Query |
| :------ | :----- | :----------- | :----------------------------- |
| J | | | phone |
| | | Frankenstein | email |
| Patrick | | | username |
### Examples
```text
//Example 1: First name only with phone
first_name=J&phone=+15551234567
//Example 2: Last name only with email
last_name=Frankenstein&email=victor.frankenstein@example.com
//Example 3: First name only with username
first_name=Patrick&username=patrick@twitter
```
```text
//Example 1: First name only with phone
https://api.pipl.com/search/?key=YOUR-API-KEY&first_name=J&phone=+15551234567
//Example 2: Last name only with email
https://api.pipl.com/search/?key=YOUR-API-KEY&last_name=Frankenstein&email=victor.frankenstein@example.com
//Example 3: First name only with username
https://api.pipl.com/search/?key=YOUR-API-KEY&first_name=Patrick&username=patrick@twitter
```
```python
from piplapis.data import Person, Name, Email, Phone
from piplapis.search import SearchAPIRequest
#Example 1: First name only with phone
fields = [Name(first='J'), Phone(raw='+15551234567')]
request = SearchAPIRequest(person=Person(fields=fields), api_key='YOUR-API-KEY')
response = request.send()
#Example 2: Last name only with email
fields = [Name(last='Frankenstein'), Email(address='victor.frankenstein@example.com')]
request = SearchAPIRequest(person=Person(fields=fields), api_key='YOUR-API-KEY')
response = request.send()
#Example 3: First name only with username
request = SearchAPIRequest(first_name='Patrick', username='patrick@twitter', api_key='YOUR-API-KEY')
response = request.send()
```
```ruby
require 'pipl'
#Example 1: First name only with phone
person = Pipl::Person.new
person.add_field Pipl::Name.new(first: 'J')
person.add_field Pipl::Phone.new(raw: '+15551234567')
response = Pipl::client.search person: person, api_key: 'YOUR-API-KEY'
#Example 2: Last name only with email
person = Pipl::Person.new
person.add_field Pipl::Name.new(last: 'Frankenstein')
person.add_field Pipl::Email.new(address: 'victor.frankenstein@example.com')
response = Pipl::client.search person: person, api_key: 'YOUR-API-KEY'
#Example 3: First name only with username
response = Pipl::client.search first_name: 'Patrick', username: 'patrick@twitter', api_key: 'YOUR-API-KEY'
```
```java
import com.pipl.api.search.SearchAPIRequest;
import com.pipl.api.search.SearchAPIResponse;
import com.pipl.api.data.containers.Person;
import com.pipl.api.data.fields.*;
import com.pipl.api.search.SearchConfiguration;
import java.util.ArrayList;
import java.util.List;
SearchConfiguration configuration = new SearchConfiguration();
configuration.setProtocol("https");
configuration.apiKey = "YOUR-API-KEY";
//Example 1: First name only with phone
List fields = new ArrayList();
fields.add(new Name.Builder().first("J").build());
fields.add(new Phone.Builder().raw("+15551234567").build());
Person person = new Person(fields);
SearchAPIRequest request = new SearchAPIRequest(person, configuration);
SearchAPIResponse response = request.send();
//Example 2: Last name only with email
fields = new ArrayList();
fields.add(new Name.Builder().last("Frankenstein").build());
fields.add(new Email.Builder().address("victor.frankenstein@example.com").build());
person = new Person(fields);
request = new SearchAPIRequest(person, configuration);
response = request.send();
//Example 3: First name only with username
request = new SearchAPIRequest.Builder()
.firstName("Patrick")
.username("patrick@twitter")
.configuration(configuration)
.build();
response = request.send();
```
```php
use_https = true;
$configuration->api_key = 'YOUR-API-KEY';
//Example 1: First name only with phone
$fields = array(
new PiplApi_Name(array("first" => "J")),
new PiplApi_Phone(array("raw" => "+15551234567"))
);
$person = new PiplApi_Person($fields);
$request = new PiplApi_SearchAPIRequest(array('person' => $person), $configuration);
$response = $request->send();
//Example 2: Last name only with email
$fields = array(
new PiplApi_Name(array("last" => "Frankenstein")),
new PiplApi_Email(array("address" => "victor.frankenstein@example.com"))
);
$person = new PiplApi_Person($fields);
$request = new PiplApi_SearchAPIRequest(array('person' => $person), $configuration);
$response = $request->send();
//Example 3: First name only with username
$request = new PiplApi_SearchAPIRequest(
array('first_name' => 'Patrick', 'username' => 'patrick@twitter'),
$configuration
);
$response = $request->send();
?>
```
```csharp
using Pipl.APIs.Search;
using System.Collections.Generic;
SearchConfiguration searchConfiguration = new SearchConfiguration(
apiKey: "YOUR-API-KEY",
url: "api.pipl.com/search/",
useHttps: true
);
//Example 1: First name only with phone
List fields = new List()
{
new Name(first: "J"),
new Phone(raw: "+15551234567")
};
var person = new Person(fields);
SearchAPIRequest request = new SearchAPIRequest(
person: person,
requestConfiguration: searchConfiguration
);
var response = await request.SendAsync();
//Example 2: Last name only with email
fields = new List()
{
new Name(last: "Frankenstein"),
new Email(address: "victor.frankenstein@example.com")
};
person = new Person(fields);
request = new SearchAPIRequest(
person: person,
requestConfiguration: searchConfiguration
);
response = await request.SendAsync();
//Example 3: First name only with username
request = new SearchAPIRequest(
firstName: "Patrick",
username: "patrick@twitter",
requestConfiguration: searchConfiguration
);
response = await request.SendAsync();
```
---
## Blacklisting People with Pipl
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
# Blacklisting People with Pipl
The following is a guide for blacklisting people on your product for opt-out and compliance purposes. You can use this strategy with or without multiple data providers.
## Overview
There may be a requirement to blacklist people who have requested their data to not appear in your product. This will require you to maintain a list of data and/or IDs and mask those. If a person requests to be blacklisted, that person's ID/data is added to the blacklist.
Pipl results don't have a persistent ID for profiles (person_ids differ per response), so it's impossible to search for them in the blacklist & filter them out. In addition, even if you create an ID for a person, identity resolution imperfections may cause the same person to be represented as multiple different IDs, so blacklisting an ID isn't guaranteed to block all of that person's information.
## Solutions
A 3-pronged approach to dealing with blacklists should be taken, with each step providing an additional safeguard against accidentally showing blocked information.
### Approach 1: Blacklisting by internal ID
If you maintain an internal ID for a person, maintain this blacklist list and they are filtered by that info.
### Approach 2: Blacklist Pipl Source IDs
Each Pipl person has an associated list of sources, which are the original web pages/online and offline data from which data was obtained. Pipl indexes such source records and assigns these individual records a unique source ID.
Here is an example of a source ID record, which can be enabled by using the show_sources parameter:
```json
{
"@id": "34892949906cd1b52b690f86e2370c59",
"@category": "professional_and_business",
"@name": "USA Business Contact",
"@premium": true,
"@person_id": "efad9998-6d2d-4dbe-8333-7b7b4861f2f5",
"@match": 1.0,
...
}
```
- The "@id" of the source will remain static, and will not change
- The "@match" has a value of 1, indicating that the source record was used to create the profile
- The "@person_id" value is dynamic and will change on every request. This is an indicator that the source record was used in the profile
Please use the following approach when blacklisting using Pipl source IDs:
- When a person is to be blocked, all of the Pipl source IDs associated with that person should be added to a blacklist. Since the source IDs will remain static and never change, should a future search for the person be made the same source IDs will be returned
- Set show_sourceids=true with your SEARCH API query to include a list of source IDs for each person or possible person in a response (see examples below). Store these source IDs in your blacklist.
- In subsequent responses, if any source IDs are returned that match a source ID in the blacklist, then mask that response. You can enable the sources layer with show_sources=matching to view the source that corresponds with each source ID.
- It is possible to apply this retroactively by running Pipl queries for all the people who are currently blacklisted, and then adding all returned matching source IDs into a "Source ID blacklist".
- The show_sourceids parameter is available on all Pipl Search keys, including the Teaser key.
**Example list of source IDs for a person response when using show_sourceids=true:**
**Example list of source IDs for a possible person response when using show_sourceids=true:**
**Examples for turning on source ID array in a response:**
```java
//Update the default configuration on init, which will be used.
//Use the extraParams variable of the defaultConfiguration. See example below:
SearchConfiguration defaultConfiguration = SearchAPIRequest.getDefaultConfiguration();
defaultConfiguration.extraParams = "&show_sourceids=True";
```
```python
# Extend the BASE_URL before making an API request.
SearchAPIRequest.BASE_URL += "&show_sourceids=true"
request = SearchAPIRequest(email="clark.kent@example.com")
```
```php
/* Please see the source code on GitHub for the code library for reference (base_url definition - https://github.com/piplcom/piplapis-php/blob/master/src/piplapis/search.php#L84).
Once you construct a PiplApi_SearchAPIRequest object, you will need to change the base_url from:
*/
public static $base_url = 'api.pipl.com/search/?';
/* to the following to execute a request */
$base_url = 'api.pipl.com/search/?show_sourceids=true&';
```
```csharp
//Use reflection to modify the Url property of your SearchAPIRequest object instance
typeof(SearchAPIRequest).GetProperty("Url")
.SetValue(yourSearchAPIRequest, "https://api.pipl.com/search/?show_sourceids=true&");
```
### Approach 3: Blacklist core data hash
In addition to blacklisting IDs, it may be useful to block the actual identity of a person from showing up again in a provider-agnostic fashion.
- For each currently blacklisted person, create one/more combinations of identifying information (``, `` or any other such combination), hash the data, and blacklist the hash.
- When a teaser person results are obtained from any provider, run a similar algorithm on it, so that you search the data-blacklist with various hashes of possible combinations.
- Do NOT be tempted to hash the entire data of a person, since this hash will stop being matched whenever there's any new data, and will also not work due to small differences between providers.
---
## Checking for new data updates
In some cases, Pipl allows caching of search results as long as you’re a paying customer, you may end up looking for the best way to update that cache. This may be useful for getting the most recent contact information of an individual or finding up to date knowledge of an individual in an investigation. This document explains a strategy to do so, and provides best practices for such data update requests.
## Index updates
Pipl updates its data index periodically with new data coverage. All administrators of an API account will be informed of data index updates.
## Recommended time frame
> ❗️ Maximum Update Frequency
>
> The recommended timeframe to check for updates of data is three months from each request, or once there has been an update to the index - whichever comes first. Please do not query for updates more frequently than every 3 months as you will not see any significant changes to profiles in between index updates and these requests will bog down our system from other requests. Pipl considers too frequent update checks to be an abuse of our API platform.
There are certain things to consider with regards to what data fields would change over time for an individual. For example:
- An individual may keep a personal email address for a long time, but if they switch jobs they’ll get a new work email address.
- The time period that the average person stays at a job should be considered.
- Some data may not change very often, such as the person’s phone number.
## The strategy

It is recommended to cache the search pointer of the person you’re saving into your cache, as it’ll be used to check for any new information.
After the recommended time frame, should you wish to check for updates, you should make use of the following API mechanisms:
- Query the API by search pointer, using the search pointer you have cached.
- Use the new\_ feature of the match_requirements query parameter (see [match criteria](/reference/match-criteria)), to specify which data fields you’re looking to update (costs can be reduced by requiring important updates, such as new emails/jobs).
- Use minimum_match=1.0 to make sure that you are still getting a single matching profile.
Should the response have no new information of the data types you’ve specified, you’ll get a non-matching response (with no person or possible_person appearing in the response), and you won’t be charged.
If there is updated information, a new Person will be returned, which will contain the up-to-date information we have about that individual. For example, if your match_requirements criteria was ‘new_email’, you will want to compare the cached emails with the new emails, to see which is (are) the new email(s) that was (were) received.
In most cases, you’ll want to simply replace your current cache with the new response, including the new search pointer.
---
## Data-Driven Decisioning
> 📘 Pipl Trust
>
> Pipl Trust is Pipl's fraud-decisioning suite. It uses the same identity data foundation as Search — plus connectivity, behavioral, and device signals scored by Elephant, Pipl's large risk model — to generate a risk score for an action or data point. If you are looking into machine-learning solutions for identity-risk scoring or fraud prevention, consider whether [Pipl Trust](https://trust.pipl.com) will meet your needs.
## Pipl Search API in Data-driven Decisioning
The Pipl Search API response includes a wide array of person-centric information that can be leveraged for your data-driven decisions in methods such as Machine Learning (ML) models and Rules Engines. This document summarizes some best practices to consider when using Pipl data.
## Confirming Identity with Pipl
The Pipl response contains a vast amount of information about the identity of a person that can be used in a rules engine or an ML model to help confirm an identity and/or gain additional knowledge about them. This data includes: [data fields](/reference/data-fields), [metadata](/reference/response), [sources](/reference/source), and [tags](/docs/pipl-api-tags). Each of these categories of data can be useful and should be considered in building a rules engine or an ML model.
### Best Practices When Comparing Data Fields
When confirming and comparing your existing data with a Pipl API response, consider the following for specific data fields:
- **Emails: **Normalize emails before comparison. Personal email services such as Gmail can be written as both [bob.franklin@gmail.com](mailto:bob.franklin@gmail.com) and [bobfranklin@gmail.com.](mailto:bobfranklin@gmail.com.) [These guidelines](/reference/email#md5-calculation-guidelines) in the Pipl API reference for md5 calculations will be useful as you begin to compare data fields.
- **Names:** Due to spelling variations or people from the same family using the same account, consider breaking up a name into first, middle and last components and comparing them separately. These individual parts can then be confirmed using methods such as fuzzy matching, comparing common nicknames, sounds like, and transliteration if in foreign languages.
- **Addresses:** Compare the individual address components (street, city, state, zip) by using methods such as fuzzy matching and spelling variations. Use fuzzy logic to accurately compare street name variations, such as “731B Union Street” vs “731 B Union St”
- **Phones:** Phone numbers vary in local and international formats in different countries. Compare phone numbers in international format to get the best results.
### Gaining Additional Knowledge About an Identity
The Pipl response returns a complete online/offline historical footprint of an identity which contains additional layers of information that may be useful. The following data points are worth considering as you design a model to make a determination about an identity:
- **Counts:** _The quantity of data returned may correlate to confirming a real identity_
- Data field counts.
The Pipl API response contains a section called “available data” indicating a summary for the number of data fields associated with the person (e.g. the number of emails, phones, addresses, etc). A real person typically has multiple emails, phones, or addresses over the course of their lifetime.
- Number of sources.
The identity of a person is created from various public source records. A real person typically appears in many public sources.
- **Time Stamps:** _A history of public source records may correlate to confirming a real identity_
- Pipl returns timestamps as to when the data was first seen and when we last came across the data. A real person typically appears in public records over a long period of time proportional to their age.
- It is possible to extract the age of data, for example, how long Pipl has known about an email or phone number and generally what is the “oldest” piece of information related to an identity as real identities tend to have rich data history.
- **Data Types:** _Knowing more about the types of data may correlate to confirming a real identity_
- Pipl returns metadata that describes the type of specific data fields. For example, an email is indicated as personal, work, whether the email is of a free service provider such as Gmail or Hotmail or a one-time disposable email service. Similarly, [phones](/reference/phone) are marked as mobile, home_phone, or work_phone.
- **Boolean indicators:** _Knowing more about the existence may correlate to confirming a real identity_
- Pipl returns social media data from networks such as Facebook, Twitter, Linkedin, and others. The existence of social media profiles over time may be an indicator of a real identity. For example, a person who has several social media accounts that have been in existence for several years is more likely to be a real person versus one who just created a social media account last month. You might find that the mere existence of a Job in a profile is a valid signal.
### Handling multiple results
In some cases, especially when using Pipl to query for a phone number or an address, [Pipl Search returns multiple persons](/reference/response-types#possible-person) relating to that data point. There is no need to decide which person to compare, as in investigation and fraud-assessment situations there is a high likelihood that people who share an address, phone or email will use the same account for a transaction, so any comparison of any data point to any of the persons relating to that piece of information will usually prove valuable.
## Example Use Cases
Pipl data combined with or compared to your data can provide an opportunity to improve your rules engine or ML models to achieve better outcomes. The combination of these two data sets can help answer questions to validate the identity of a new customer on your platform or a transaction in which the purchaser ships to a new recipient at a new address. For these use cases, the following are questions you may want to consider when using Pipl data in your data-driven decisions:
### Validate the identity of a new customer on your platform
Using Pipl you may be able to determine if a new customer is who they say they are.
- Does the Pipl API return a Person response when queried by the personal information they provided?
- How long has Pipl known about the data associated with the person?
- Does the name in the Pipl response match the name on record?
- Is the billing address, shipping address, or phone number present in the Pipl response?
- Is there a partial match? What is the distance between the physical locations in the response?
### Validate if a new shipping address or a new person shipped to is associated with the account holder
Using Pipl you may be able to determine if the new person and/or the new address is related in any way to the account holder. Query the Pipl API for the account holder and the new person being shipped to. Based on the Pipl Search response:
- Is there a relationship between the persons?
- Are there shared addresses or phone numbers?
---
## Basic Coding Flowchart
Many applications using the Pipl Search API follow the same general structure. This is a starting point and will need to be adjusted and enhanced depending on your specific needs and application.
1. [Person Response](/reference/response-types#person-perfect-match)
2. [Possible Person Response](/reference/response-types#possible-person)
3. [No Match Response](/reference/response-types#no-match)
4. [Minimum Request Requirements](/reference/request-overview#minimum-requirements)
5. [Rate limiting](rate-limiting)
6. [Key quota limits](rate-limiting#key-quota-limits)
---
## Monitoring Package key usage and spend
Congratulations on your new Search API package key! Now we'll teach you how to use its features to monitor and control your usage and spend for the key.
Please note that this article is complementary to the article '[Monitoring usage and spend](/docs/monitoring-usage-and-spend)'.
## Understanding your API key quota
Package API keys have a specific quota (number of matches) associated with them when they are generated. The key’s quota is for the full term of the key.
API package key match limits represent the number of matches you have to use during the package period, for example:
| Key | Price per match | Package limit | Package period | Package Cost |
| :--------------- | :-------------- | :------------ | :------------- | :----------- |
| Package Business | $0.55 | 15000 | 1 year | **$8250** |
To know how many matches you have left on your Package key, see the[ API keys](https://search.pipl.com/api/manage/keys) page on your Pipl account.
You also can set a quota for a more specific time frame, such as 100 matches per day. Please see [setting your API key quota]monitoring-usage-and-spend#setting-your-api-key-quota).
## Using the HTTP headers
The Package key usage details are shown on every API response in the [HTTP header](/reference/rate-limiting-information) :
- "X-Package-Allotted" —The total number of matches defined on the key.
- "X-Package-Current" —The number of used matches.
- "X-Package-Expiry" —The date and time when the key and remaining matches will expire.
Every billable response (i.e. every match) you get from the API will be counted against the package key limit and will be added to the "X-Package-Current".
Applying the example used in the table above, the headers will return as follows:
```json
X-Package-Allotted 12500
X-Package-Expiry 2018-10-08 00:00:00+00:00 ##1 year from issue date##
X-Package-Current 16 ##after 16 matches were returned##
```
Use these three headers to calculate relevant values for your business. For example:
1. Calculate the number of queries you have left before your package key expires:
**Queries Remaining** = **X-Package-Alloted** - **X-Package-Current**
2. Calculate the current spend on your package key:
**Current Spend** = **Price-per-match/\***\_ x **X-Package-Current**
\*_Depending on the key you used_
## Example Python code
The 'moneyed' and 'decimal' libraries are used to help handle the calculation and presentation.
```python
from piplapis.error import APIError
from piplapis.search import SearchAPIRequest
from piplapis.search import SearchAPIResponse
from piplapis.data import Person
from piplapis.data.fields import Address, Email, Name, Phone
from moneyed import Money
from decimal import *
person = Person()
person.emails.append(Email('clark.kent@example.com'))
SearchAPIRequest.set_default_settings(api_key='YOUR_PACKAGE_KEY_HERE')
request = SearchAPIRequest(person=person)
response = request.send()
# Plain messages
print("This is your Quota for the key: ", response.package_allotted)
print("This is your usage of the key: ", response.package_current)
print("This is when the key and quota expire: ", response.package_expiry)
# Calculated messages
usagePercent = Decimal(Decimal(response.package_current)/Decimal(response.package_allotted))
keyPrice = Decimal('0.40')
totalUsage = Money(amount=(keyPrice*response.package_current),currency='USD')
print("You have used ", response.package_current," of ",response.package_allotted,"queries.")
print("You have used ",usagePercent,"% of your quota")
```
---
## Monitoring usage and spend
Did you know that as an API customer you can track your usage and billing in your Pipl account? The [usage page](https://search.pipl.com/api/manage/usage) shows a history of your queries and match rates. The [billing page](https://search.pipl.com/api/accounts/billing/) shows your previous invoices as well as your current spend, which is updated hourly. The current spend is displayed prior to applying any adjustments, refunds, or discounts.
You also can monitor your account proactively via code using the [HTTP headers](/reference/rate-limiting-information) returned by every Search API [response](/reference/response)
> 📘 Log Your Own API Usage
>
> We recommend logging every API request, including [search_ids](/reference/response), [errors](/reference/errors) and [warnings](/reference/warnings) in order to improve your integration. These logs should be reviewed regularly.
## Setting your API key quota
API keys do not have a specific quota when they are generated. Only a Pipl account administrator can set your API key quota.
To set a quota for the key you want to use:
1. Go to your [API keys page](https://search.pipl.com/api/manage/keys).
2. Hover over the key you want to use to view the options menu for that key.
3. Select ‘Set quota’ from the menu.

4. The ‘Change Key Quota’ popup window will appear.
5. Select the quota limit. The quota limit is the number of **matches** you want to allow for the quota period. Setting the quota to 0 will reset the quota.
6. Select the quota period (hourly/daily/monthly).
7. Press ‘Change’.
8. The new quota you’ve set will show under the key.
API key quotas represent the number of matches for a given period of time. They allow you to set a budget per key and control your spend. We’ve provided an example below.
| Key | Price per match | Quota limit | Quota period | Quota per invoice |
| :--------------- | :-------------- | :---------- | :----------- | :---------------- |
| Business Premium | $0.55 | 2000 | Monthly | $1100 |
## Using the HTTP headers
The quota that you have set will be shown on every API response in the [HTTP header](/reference/rate-limiting-information) as "X-APIKey-Quota-Alloted".
The date and time of the quota reset will show in the [HTTP header](/reference/rate-limiting-information) as "X-Quota-Reset".
Every billable response—such as every match returned from the API—will be counted against the quota of the key used and will be shown in the [HTTP header](/reference/rate-limiting-information) as "X-APIKey-Quota-Current".
Applying the example used in the table above, the headers will return as follows:
```json
X-APIKey-Quota-Allotted 2000
X-Quota-Reset 2018-10-01 00:00:00 ##The end of the month##
X-APIKey-Quota-Current 1
```
Use the three headers above to calculate relevant values for your business. For example:
1. Calculate the number of queries you have left before your quota is reached:
**Queries Remaining** = **X-APIKey-Quota-Alloted** - **X-APIKey-Quota-Current**
2. Calculate your spend on an API key during a quota period:
**Spend** = **Price-per-match\*** x **X-APIKey-Quota-Current**
\*_Depending on the key you used_
---
## Throttling Your Queries
You might have just received an email error alert from Pipl with the subject “Whoa Nellie! Too many API calls per second…” What now?
We can help. Pipl does use rate limiting, and here are tips for implementing a throttling mechanism for your Pipl API integration.
## Why the rate limit?
The Pipl API has rate limits per account, across all keys. Pipl’s technology operates like a search engine rather than a traditional database. This means that records are indexed and clustered on every request made. We limit the number of queries per second (QPS) sent to the API at the same time to ensure that all customers have fair access.
Implementing a throttling mechanism is important. First, it helps ensure that you receive the data you need. When you hit the rate limit, you will receive an HTTP 403 error status response. Second, rate limits help prevent abuse of our services. Consistently exceeding rate limits can result in suspension of your account.
## What are the limitations?
If you use Pipl with peaks of query volumes, please make sure that your application is adhering to the [allotted rate limits](rate-limiting), otherwise we consider this abuse.
Below is a chart indicating the allowed number of queries to be performed in a certain period.
| API key type | Live feeds | Second | Minute | Hour | Day | Week | Month |
| --- | --- | --- | --- | --- | --- | --- | --- |
| Contact, Social, or Business | true (default) | 10 | 600 | 36,000 | 864,000 | 6,048,000 | 25,920,000 |
| Contact, Social, or Business | false | 20 | 1200 | 72,000 | 1,728,000 | 12,096,000 | 51,840,000 |
As the table above shows, the default is 10 QPS. You can increase your rate to 20 QPS, but you will need to use live_feeds=false in your queries.
## Error management and HTTP headers
Each API response will return [HTTP headers](/reference/rate-limiting-information) to help you adhere to rate limits. QPS rate limits depend on whether or not you use live_feeds with your queries. Depending on the query, different QPS rates apply and different [HTTP headers](/reference/rate-limiting-information) need to be checked by your application code.
Once you hit the rate limit and receive an HTTP 403 status message, every succeeding query received counts towards your rate-limiting quota. See the table below for the error message and the [HTTP headers](/reference/rate-limiting-information) to watch for, depending on whether you are using live feeds.
| API Key Type | Configuration Parameter: live_feeds | QPS | Response HTTP Headers and Status Code |
| --- | --- | --- | --- |
| Contact, Social, or Business | true | 10 | • X-QPS-Live-Current > X-QPS-Live-Allotted• HTTP Status Code 403• Error Message "Per second limit for live calls reached" |
| Contact, Social, or Business | false | 20 | • X-QPS-Current > X-QPS-Allotted• HTTP Status Code 403• Error Message "Per second limit for total calls reached" |
## How to best implement a throttling mechanism?
To implement throttling, you can implement a pause (thread.sleep) between each request. If you need a multithreaded solution with low latency, there are many open source solutions available to help. Open source code libraries can be used in conjunction with your API for a rate limiting solution, but this solution depends on your use case. Some Pipl customers use open source libraries such as:
### Programming language and platform independent
- [Nginx proxy](https://monterail.com/blog/2011/outbound-api-rate-limits-the-nginx-way/). Take advantage of the built-in nginx module, the HttpLimitReqModule.
- [HAProxy](http://blog.serverfault.com/2010/08/26/1016491873/). Better Rate Limiting For All with HAProxy
### Java
- [Google Guava RateLimiter class](https://google.github.io/guava/releases/19.0/api/docs/index.html?com/google/common/util/concurrent/RateLimiter.html). See also how this can be implemented using [Guava on StackOverflow](https://stackoverflow.com/questions/1407113/throttling-method-calls-to-m-requests-in-n-seconds).
- [Java Rate Limit API](https://github.com/jabley/rate-limit). Contains the primitives and utilities used to rate-limit Java applications and a CircuitBreaker implementation.
### PHP
- [Stiphle](https://github.com/davedevelopment/stiphle). A simple PHP library for throttling or rate limiting.
### Python
- [Rate Limit](https://pypi.org/project/ratelimit/). API rate limit decorator.
- [Limit](https://pypi.org/project/limit/). Decorator that limits the calling rate of a function.
- [RequestsThrottler](https://pypi.python.org/pypi/RequestsThrottler/). Python HTTP requests throttler.
- [Throttle](https://pypi.python.org/pypi/throttle). A robust and versatile throttling implementation relying on the token bucket algorithm.
### Ruby
- [Sidekiq framework](https://github.com/sensortower/sidekiq-throttled) for background processing has a Concurrency and threshold throttling library.
- [ThrottleQueue](https://github.com/ryancalhoun/throttle-queue). A thread-safe rate-limited work queue with foreground and background operations.
- [Slow Web](https://github.com/benbjohnson/slowweb). An HTTP request governor.
### C#/ASP.net
- [How to implement rate limiting in ASP.NET Core](https://www.infoworld.com/article/3442946/how-to-implement-rate-limiting-in-aspnet-core.html)
> 🚧 What's under the hood of Pipl's rate limiting mechanism?
>
> If you’re curious about what’s under the hood, Pipl’s rate limiting engine uses a sliding window mechanism and starts counting from the time of the first request sent. If you’d like more specifics, visit [here](https://engagor.github.io/blog/2017/05/02/sliding-window-rate-limiter-redis/) and [here](https://engineering.classdojo.com/blog/2015/02/06/rolling-rate-limiter/) (note the second comment regarding the "Rolling Window")
## Consider queuing your requests to Pipl
If your platform supports multiple users or requires a backlog of requests, consider using a modern queueing technology in your Pipl API integration. This will give you control over rate-querying the Pipl API and allow you to specify priority queues.
### Consider the following architecture and flow:

### 1. User Action
- A user action can trigger single- and multiple-batch enrichments
- You can segment users by subscription. For example, you can designate priority vs. normal users, with trial users receiving the lowest priority.
### 2. Queuing
- A priority-based queue is created per user, FIFO
- Define priority based on use case/flow
### 3. Threading
- Multiple threads collect queries from each of the queues based on a priority algorithm
- Serve multiple users fairly based on their subscription levels
- Queues can be depleted based on priority
- Run optimally and adhere to Pipl API rate limits. The thread turns requests into API requests and sends them according to the specified rate limit, based on the key.
- Event-based, push to user feedback
### 4. User Feedback
- UI Dialog to show progress
- Show a progress bar. Estimate time remaining based on queue size and remainder.
- Update the number of enriched data points as the queue gets smaller.
- Upsell other features to customers.
- User can optionally close dialog and be notified by email.
- Use creative UI techniques instead of a dialog. Data gets updated on UI in near-real time as enriched.

## Rate limit not enough for your needs?
Speak to your account manager. Pipl will assess your volume and requirements, and we can come to an agreement. You will need to use live_feeds=false, however.
---
## Rate Limiting in Pipl Search
We want you to use our API as much as possible. However, sometimes we must limit the numbers of API calls run. This document outlines the default rate-limiting configurations for our API and the reasoning behind those limits.
If you feel these limits hinder your API usage, contact your Account Director or Integration Specialist to create custom settings.
## Queries Per Second Limit
The queries-per-second (QPS) limit is the number of queries you can run per second.
> 🚧 Rate-limit your Pipl API integration
>
> We require Pipl API customers to implement a rate-limiting mechanism in their integrations to prevent HTTP status 403 throttling errors. Please see the tutorial on [throttling your queries]rate-limiting-your-queries) for best practices.
**Why do we have this limit?**
Limits enable us to deliver consistently high performance for all customers and to protect them from accidental overuse.
**What is the default limit?**
The default limit is different for queries that use live feeds and those that do not. With live feeds, limits help us protect our external feed providers from extreme usage spikes.
Defaults are:
- 20 total queries
- 10 queries that includes live feeds
**Where can I see my limit and current status?**
Refer to the [HTTP headers of the API responses](/reference/rate-limiting-information).
**What if I need more?**
Please contact your Account Director or Integration Specialist.
### Live Feeds
**What are live_feeds?**
Live feeds are data partners outside of Pipl's infrastructure that can provide additional data—2-3% more—specifically within the USA.
**Why do queries with live feeds have a lower QPS limit?**
Live feeds have a lower default QPS limit in order to limit load on external data providers. Queries with live feeds also have increased latency. Consider turning live_feeds to false to increase your query throughput and decrease latency.
## Key Quota Limits
In addition to our rate-limiting systems, we enable customers to configure hard quotas on specific API keys. Key quotas can be set as a number of matches/queries per day, week, or month. Quotas will apply to the number of billed queries, so if your API key is billed per-match then the quota will limit the number of matches whereas if your API key is billed per call, then the quota will limit your calls.
**Why do we have this quota limit?**
This enables you to set limits for specific applications, development environments (QA/staging) or for specific employees based on the key issued.
**What is the default limit?**
There are no default key quotas.
**Can I set my own key quota limits?**
Yes. Organization administrators—usually the person who opened the account— can manage custom quotas [on the API keys page](https://pipl.com/api/manage/keys). They can set a monthly, daily, or weekly quota per key.
**Where can I see my limit and current status?**
If you set custom quota limits, they will be displayed on your [key management page](https://pipl.com/api/manage/keys). The [HTTP headers of the API responses](/reference/rate-limiting-information) also show the quota.
Notifications via email alerts will be sent out to account administrators when reaching 80% and 100% of quota.
Read more about this in the tutorial on [monitoring usage and spend]monitoring-usage-and-spend).
## Account Spend Limit
The account spend limit is a monthly limit on the amount of money you can spend on API queries. Once you reach the limit, further API queries will be rejected.
**Why do we have this limit?**
This limit protects customers from accidental overuse and protects Pipl from credit line abuse.
**What is the default limit?**
$1,000 per month.
**Where can I see my limit and current status?**
In your [API billing overview page](https://pipl.com/api/manage/billing).
Notifications via email alerts will be sent out to account administrators when reaching 80% and 100% of spend.
**What if I need more?**
Once we verify your identity and payment information, simply contact us and request a new spend limit based on your needs and approved credit line.
---
## Code Libraries
import PYTHON from '../static/img/python.png'
import RUBY from '../static/img/ruby.png'
import JAVA from '../static/img/java.png'
import PHP from '../static/img/php.png'
import CSHARP from '../static/img/csharp.png'
import SWAGGER from '../static/img/swagger.png'
# Code Libraries
We love developers, so we want to make your life as easy as possible. We've created a set of client libraries for major programming languages so that you can integrate our APIs into your code in minutes.
What are you waiting for? Just choose your preferred language and get started.
| **Python** | **Ruby** | **Java** | **PHP** | **C#** | **Swagger** |
| -------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ |
| | | | | | |
## Python
The Python library is on PyPI, so you can use pip or easy_install.
```
pip install piplapis-python
```
Or grab the source from [github](https://github.com/piplcom/piplapis-python).
## Ruby
The Ruby library is on RubyGems.org, so you can gem install it.
```
bundle install piplapis-ruby
```
Or grab the source from [github](https://github.com/piplcom/piplapis-ruby).
## Java
The Java library is on [Maven Central](https://search.maven.org/artifact/com.pipl.api/piplapis/5.0.16/jar).
```
dependency
groupIdcom.pipl.api/groupId
artifactIdpiplapis/artifactId
version5.0.16/version
/dependency
```
Or grab the source from [github](https://github.com/piplcom/piplapis-java).
## PHP
The PHP library is available on Packagist for Composer.
```
"pipl/piplapis-php": "*"
```
Or grab the source from [github](https://github.com/piplcom/piplapis-php).
## C#
The C# library is available on NuGet
```
PM> Install-Package piplclient
```
Or grab the source from [github](https://github.com/piplcom/piplapis-csharp).
## Swagger
The Swagger definition is available on [github](https://github.com/piplcom/search-api-examples/tree/main/Swagger)
For more information on using swagger, see [Swagger's getting started guide](https://swagger.io/tools/open-source/getting-started/).
---
## Code Snippets and Example Programs
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faMale, faUsers } from '@fortawesome/free-solid-svg-icons';
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
# Code Snippets and Example Programs
The following snippets and examples are meant to highlight some commonly used capabilities of the API. For a complete understanding of the API's features, please refer to the libraries' source code (available on [github](https://github.com/piplcom/)).
## Example Scripts
Example scripts using the Pipl API can be found at the [Search API Examples github page](https://github.com/piplcom/search-API-examples)
## Code Snippets
Below are a few snippets for the basic things that you can do with the API [Code Libraries](code-libraries).
### Creating a request
**Option 1** - This is a fast, direct method for simple requests with few parameters:
```python
from piplapis.search import SearchAPIRequest
request = SearchAPIRequest(email=u'clark.kent@example.com', api_key='YOURKEY')
```
```ruby
require 'pipl'
response = Pipl::client.search email: 'clark.kent@example.com', api_key: 'YOURKEY'
```
```java
import com.pipl.api.search.SearchAPIRequest;
import com.pipl.api.search.SearchAPIResponse;
import com.pipl.api.search.SearchConfiguration;
SearchConfiguration configuration = new SearchConfiguration();
configuration.setProtocol("https");
configuration.apiKey = 'YOURKEY'
SearchAPIRequest request = new
SearchAPIRequest.Builder().email("clark.kent@example.com").firstName("Clark").lastName("Kent").configuration(configuration).build();
```
```php
use_https = true;
$configuration->api_key = 'YOURKEY';
$request = new PiplApi_SearchAPIRequest(array('email' => 'clark.kent@example.com',
'first_name' => 'Clark',
'last_name' => 'Kent'), $configuration);
?>
```
```csharp
using Pipl.APIs.Search;
SearchConfiguration searchConfiguration = new SearchConfiguration(apiKey: "YOURKEY",url: "api.pipl.com/search/", useHttps: true);
SearchAPIRequest request = new SearchAPIRequest(email: "clark.kent@example.com",
firstName: "Clark",
lastName: "Kent", requestConfiguration: searchConfiguration);
```
**Option 2 - Using the data-model.** This method is useful for more complex queries, such as when you need to send multiple values of the same field type:
```python
from piplapis.data import Person, Name, Address, Job
fields = [Name(first=u'Clark', last=u'Kent'),
Address(country=u'US', state=u'KS', city=u'Smallville'),
Address(country=u'US', state=u'KS', city=u'Metropolis'),
Job(title=u'Field Reporter')]
request = SearchAPIRequest(person=Person(fields=fields), api_key='YOURKEY')
```
```ruby
person = Pipl::Person.new
person.add_field Pipl::Name.new(first: 'Clark', last: 'Kent')
person.add_field Pipl::Address.new(country: 'US', state: 'KS', city: 'Smallville')
person.add_field Pipl::Address.new(country: 'US', state: 'KS', city: 'Metropolis')
person.add_field Pipl::Job.new(title: 'Field Reporter')
response = Pipl::client.search person: person, api_key: 'YOURKEY'
```
```java
import java.util.ArrayList;
import java.util.List;
import com.pipl.api.search.SearchAPIRequest;
import com.pipl.api.data.containers.Person;
import com.pipl.api.data.fields.*;
import com.pipl.api.search.SearchConfiguration;
SearchConfiguration configuration = new SearchConfiguration();
configuration.setProtocol("https");
configuration.apiKey = 'YOURKEY';
List fields = new ArrayList();
fields.add(new Name.Builder().first("Clark").last("Kent").build());
fields.add(new Address.Builder().country("US").state("KS").city("Smallville").build());
fields.add(new Address.Builder().country("US").state("KS").city("Metropolis").build());
fields.add(new Job.Builder().title("Field Reporter").build());
Person person = new Person(fields);
// Or the short version:
// Person person = new Person(new Name(null, "Clark", null, "Kent", null), new Address("US", "KS", "Smallville", null, null, null, null, null), new Address("US", "KS", "Metropolis", null, null, null, null, null), new Job("Field Reporter", null, null));
SearchAPIRequest request = new SearchAPIRequest(person, configuration);
```
```php
use_https = true;
$configuration->api_key = 'YOURKEY';
$fields = array(new PiplApi_Address(array("country" => "US",
"state" => "KS", "city" => "Metropolis")),
new PiplApi_Address(array("country" => "US",
"state" => "KS", "city" => "Smallville")),
new PiplApi_Name(array("first" => "Clark",
"middle" => "Joseph", "last" => "Kent")),
new PiplApi_Job(array("title" => "Field Reporter")),
);
$person = new PiplApi_Person($fields);
$request = new PiplApi_SearchAPIRequest(array('person' => $person), configuration);
return $request;
```
```csharp
using Pipl.APIs.Search;
SearchConfiguration searchConfiguration = new SearchConfiguration(apiKey: "YOURKEY",url: "api.pipl.com/search/", useHttps: true);
List fields = new List()
{
new Name(first: "Clark",last: "Kent"),
new Address(country: "US", state: "KS", city: "Smallville"),
new Address(country: "US", state: "KS", city: "Metropolis"),
new Job(title: "Field Reporter")
};
var person = new Person(fields);
SearchAPIRequest request = new SearchAPIRequest(person: person, requestConfiguration: searchConfiguration);
```
### Sending a request
**Option 1 – Synchronously**
```python
from piplapis.search import SearchAPIError
try:
response = request.send()
except SearchAPIError as e:
print(e.http_status_code, e)
```
```ruby
begin
response = Pipl::client.search email: 'clark.kent@example.com'
rescue Pipl::Client::APIError => e
puts e.status_code, e.message
end
```
```java
import java.io.IOException;
import com.pipl.api.search.SearchAPIError;
import com.pipl.api.search.SearchAPIResponse;
try {
SearchAPIResponse response = request.send();
} catch (SearchAPIError | IOException e) {
e.printStackTrace();
}
```
```php
send();
} catch (PiplApi_SearchAPIError $e) {
print $e->getMessage();
}
```
```csharp
try
{
var response = await _request.SendAsync();
}
catch (SearchAPIError e)
{
Console.Out.WriteLine(e.ToString());
}
catch (IOException e)
{
Console.Out.WriteLine(e.ToString());
}
```
**Option 2 – Async: Send the query with a non-blocking call**
```python
def my_callback(response=None, error=None):
print response or error
request.send_async(my_callback)
do_other_things()
```
```ruby
thread = Pipl::client.search email: 'clark.kent@example.com', async: true do |resp|
puts resp[:response] or resp[:error]
end
do_other_things()
```
```java
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
ExecutorService threadPool = Executors.newSingleThreadExecutor();
// Other alternatives contain more advanced thread pools and FutureTask.
Future future = threadPool.submit(request.sendAsync(false));
doOtherThings();
try {
SearchAPIResponse response = future.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
```
```php
# Not available in PHP
```
```csharp
var task = _request.SendAsync();
_doOtherThings();
try
{
var response = task.Result;
}
catch (TaskCanceledException e)
{
Console.Out.WriteLine(e.ToString());
}
```
### Working with a response
> 📘 A response can return either a Person , a list of Possible Persons , or no data.
>
> When working with the response, first check for a person object. If it's null, check for the possible_persons array. If there are neither, there is no data in the response (the persons_count property will be 0 in this case).
The below syntax is available for all fields to quickly access frequently used data (the most recent name, last address, most prominent username, etc.). For example, when using the fast, direct option #1 method:
```python
>>> print(response.name)
u'Clark Joseph Kent'
>>> print(response.gender)
u'Male'
>>> print(response.address)
u'10-1 Hickory Lane, Smallville, Kansas'
>>> print(response.job)
u'Field Reporter at The Daily Planet (2000-2012)'
```
```ruby
puts response.name
# Output: 'Clark Joseph Kent'
puts response.gender
# Output: 'Male'
puts response.address
# Output: '10-1 Hickory Lane, Smallville, Kansas'
puts response.job
# Output: 'Field Reporter at The Daily Planet (2000-2012)'
```
```java
System.out.println(response.name());
// Output: "Clark Joseph Kent"
System.out.println(response.gender());
// Output: "Male"
System.out.println(response.address());
// Output: "10-1 Hickory Lane, Smallville, Kansas"
System.out.println(response.job());
// Output: "Field Reporter at The Daily Planet (2000-2012)"
```
```php
person->addresses[0]; // 10-1 Hickory Lane, Smallville, Kansas
```
```csharp
Console.Out.WriteLine(_response.Name);
// Output: "Clark Joseph Kent"
Console.Out.WriteLine(_response.Gender);
// Output: "Male"
Console.Out.WriteLine(_response.Address);
// Output: "10-1 Hickory Lane, Smallville, Kansas"
Console.Out.WriteLine(_response.Job);
// Output: "Field Reporter at The Daily Planet (2000-2012)"
```
Access the person object that came with the response:
```python
>>> response.person
>>> response.person.addresses
[Address(country=u'US', state=u'KS', city=u"Metropolis", street=u"Broadway", house=u"1000", apartment=u"355"), Address(country=u'US', state=u'KS', city=u"Smallville", street=u"Hickory Lane", house=u"10", apartment=u"1")]
```
```ruby
puts response.person.addresses
# Output: '10-1 Hickory Lane, Smallville, Kansas'
# Output: '1000-355 Broadway, Metropolis, Kansas'
```
```java
System.out.println(response.getPerson().getAddresses().get(0));
// Output: "10-1 Hickory Lane, Smallville, Kansas"
```
```php
person->addresses[0]; // 10-1 Hickory Lane, Smallville, Kansas
```
```csharp
Console.Out.WriteLine(_response.Person.Addresses[0]);
// Output: "10-1 Hickory Lane, Smallville, Kansas"
```
### Working with sources
Access the response data's list of sources. This is only available if you set the “show_sources” flag to “all” or “matching”:
```python
>>> len(response.sources)
2
>>> response.sources[0]
>>> response.sources[0].phones
[Phone(country_code=1, number=9785550145)]
>>> response.sources[0].origin_url
u'http://linkedin.com/clark.kent'
```
```ruby
response = Pipl::client.search email: 'clark.kent@example.com', show_sources: 'all'
puts response.sources[1].phones[0].display
# Output: '(978) 555-0145'
puts response.sources[1].origin_url
# Output: 'http://facebook.com/superman'
```
```java
System.out.println(response.getSources().size());
// Output: 2
System.out.println(response.getSources().get(1).getPhones().get(0).getDisplayInternational());
// Output: "+1 978-555-0145"
System.out.println(response. getSources().get(0).getOriginUrl());
// Output: "http://linkedin.com/clark.kent"
```
```php
sources); // 2
print $response->sources[1]->phones[0]->display_international; // http://linkedin.com/clark.kent
print $response->sources[1]->domain; // linkedin.com
```
```csharp
Console.Out.WriteLine(_response.Sources.Count);
// Output: 2
Console.Out.WriteLine(_response.Sources[1].Phones[0].DisplayInternational);
// Output: "+1 978-555-0145"
Console.Out.WriteLine(_response.Sources[0].OriginUrl);
// Output: "http://linkedin.com/clark.kent"
```
Group sources. Sources can be grouped by domain, category, match and more:
```python
>>> type(response.group_sources_by_domain())
>>> response.group_sources_by_domain().get(u'linkedin.com')
[, ]
```
```ruby
response = Pipl::client.search email: 'clark.kent@example.com', show_sources: 'all'
puts response.group_sources_by_domain['linkedin.com'].size
# Output: 1
```
```java
System.out.println(response.groupSourcesByDomain().get("linkedin.com").size());
// Output: 1
```
```php
group_sources_by_domain()['linkedin.com']); // array
print get_class($response->group_sources_by_domain()['linkedin.com'][0]); // PiplApi_Source
```
```csharp
Console.Out.WriteLine(_response.GroupSourcesByDomain()["linkedin.com"].Count());
// Output: 1
```
### Useful utilities
There are useful utilities implemented for the field objects. Here are some examples:
```python
>>> address = response.address
>>> address.state
u'KS'
>>> address.state_full
u'Kansas'
>>> email = response.email
>>> email.username
u'clark.kent'
```
```ruby
address = response.address
puts address.state
# Output: 'KS'
puts address.state_full
# Output: 'Kansas'
email = response.email
puts email.username
# Output: 'clark.kent'
```
```java
Address address = new Address.Builder().country("US").state("KS").build();
System.out.println(address.getState());
// Output: "KS"
System.out.println(address.stateFull());
// Output: "Kansas"
Email email = new Email.Builder().address("clark.kent@example.com").build();
System.out.println(email.username());
// Output: "clark.kent"
```
```php
address()->state; // KS
print $response->address()->state_full(); // Kansas
print $response->email(); // clark.kent@example.com
print $response->email()->username; // clark.kent
```
```csharp
Address address = new Address(country: "US", state:"KS");
Console.Out.WriteLine(address.State);
// Output: "KS"
Console.Out.WriteLine(address.StateFull);
// Output: "Kansas"
Email email = new Email(address: "clark.kent@example.com");
Console.Out.WriteLine(email.Username);
// Output: "clark.kent"
```
### Global Preferences
You also can set search preferences globally, and they will apply to all search requests. Examples shown in the snippet are the default preferences.
Setting global preferences is optional—you can choose query settings per request if you prefer.
```python
SearchAPIRequest.set_default_settings(api_key=u'YOURKEY', minimum_probability=None,
show_sources=None, minimum_match=None, hide_sponsored=None, live_feeds=None, use_https=True)
```
```ruby
Pipl.configure do |c|
c.api_key = 'YOURKEY'
c.show_sources = 'all'
c.minimum_probability = 0.7
c.minimum_match = 0.5
c.strict_validation = true
end
```
```java
import com.pipl.api.search.SearchAPIRequest;
import com.pipl.api.search.SearchConfiguration;
SearchConfiguration defaultConfiguration = SearchAPIRequest.getDefaultConfiguration();
defaultConfiguration.protocol = "https";
defaultConfiguration.apiKey = "YOURKEY";
defaultConfiguration.minimumProbability = null;
defaultConfiguration.showSources = null;
defaultConfiguration.possibleResults = null;
defaultConfiguration.hideSponsored = null;
defaultConfiguration.liveFeeds = null;
```
```php
api_key = "YOURKEY";
PiplApi_SearchAPIRequest::get_default_configuration()->minimum_probability = 0.9;
PiplApi_SearchAPIRequest::get_default_configuration()->minimum_match = 0.8;
PiplApi_SearchAPIRequest::get_default_configuration()->hide_sponsored = true;
PiplApi_SearchAPIRequest::get_default_configuration()->live_feeds = false;
PiplApi_SearchAPIRequest::get_default_configuration()->use_https = true;
PiplApi_SearchAPIRequest::get_default_configuration()->show_sources = "all";
```
```csharp
SearchConfiguration defaultConfiguration = SearchAPIRequest.DefaultConfiguration;
defaultConfiguration.UseHttps = true;
defaultConfiguration.ApiKey = "YOURKEY";
defaultConfiguration.MinimumProbability = null;
defaultConfiguration.ShowSources = null;
defaultConfiguration.MinimumMatch = null;
defaultConfiguration.HideSponsored = null;
defaultConfiguration.LiveFeeds = null;
```
---
## First Steps
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
## 1. Get an API key
All API calls must include a valid API key. This is our way of identifying you and authorizing your call.
If you have an account, you can choose a key on your [API Keys page](https://search.pipl.com/api/manage/keys).
To experiment with our API and try a few calls, use the [demo page](https://search.pipl.com/api/demo) or [try out the Postman collection](postman-collection).
## 2. Choose your code library
Integrating to an API should be easy. We've written code libraries for major programming languages to make integration a breeze. Choose your preferred language. We currently support Python, Ruby, Java, C# and PHP.
[Download a code library here](code-libraries)
## 3. Run a "Hello World" query
When you query Pipl, simply enter the information you have about someone and we'll deliver all of the data available about that person.
Let's say we're looking for Clark Kent, who's using the email [clark.kent@example.com](mailto:clark.kent@example.com):
````text
https://api.pipl.com/search/?first_name=Clark&last_name=Kent&email=clark.kent@example.com&key=YOURKEY
````
> 📘 Free query
>
> Any query that contains the email address `clark.kent@example.com` will not be charged and it will provide static example output as a result.
> 👍 Use Encryption
>
> We require SSL—change any URL prefix to HTTPS instead of HTTP.
> **API Endpoint:** [https://api.pipl.com/search/](https://api.pipl.com/search/)
```text
https://api.pipl.com/search/?email=clark.kent@example.com&key=YOURKEY
```
```python
#imports
from piplapis.search import SearchAPIRequest
#run search (request/response)
request = SearchAPIRequest(email=u'clark.kent@example.com',
first_name=u'Clark', last_name=u'Kent', api_key='YOURKEY')
response = request.send()
#print portion of response
if response.person: #Has data so single Full Person response
currentPerson = response.person
print("Hello World:")
print("Number of Names:", len(currentPerson.names))
print("Name(s):" + "\n" .join(map(str, currentPerson.names)))
print("Username(s):" + "\n" .join(map(str, currentPerson.usernames)))
print("Emails(s):" + "\n" .join(map(str, currentPerson.emails)))
print("\n")
```
```ruby
require 'pipl'
response = Pipl::client.search email: 'clark.kent@example.com', first_name: 'Clark',
last_name: 'Kent', api_key: 'YOURKEY'
```
```java
import com.pipl.api.search.SearchAPIRequest;
import com.pipl.api.search.SearchAPIResponse;
import com.pipl.api.search.SearchConfiguration;
SearchAPIConfiguration configuration = new SearchConfiguration();
configuration.setProtocol("https");
configuration.apiKey = 'YOURKEY'
SearchAPIRequest request = new
SearchAPIRequest.Builder().email("clark.kent@example.com").firstName("Clark").lastName("Kent").configuration(configuration).build();
SearchAPIResponse response = request.send();
```
```php
api_key = 'YOURKEY';
$configuration->use_https = true;
$request = new PiplApi_SearchAPIRequest(array('email' => 'clark.kent@example.com',
'first_name' => 'Clark',
'last_name' => 'Kent'), $configuration);
$response = $request->send();
?>
```
```csharp
using Pipl.APIs.Search;
SearchConfiguration searchConfiguration = new SearchConfiguration(apiKey: "YOURKEY",url: "api.pipl.com/search/", useHttps: true);
SearchAPIRequest request = new SearchAPIRequest(email: "clark.kent@example.com",
firstName: "Clark",
lastName: "Kent", requestConfiguration: searchConfiguration);
SearchAPIResponse response = await request.SendAsync();
```
```bash
curl https://api.pipl.com/search/\?email=clark.kent@example.com\&key=YOURKEY
```
You can query with email addresses, phone numbers, usernames, names, addresses, age, or other attributes. Please review the full API reference.
## 4. Work with the results
When your search is unique—such as entering an email address, social profile, or a very unique name—the search [response](/reference/response) will contain a **single person object**. This indicates that we've confidently matched your search parameters to a single, real-world person. The response will look like this:
```json
{
...
"person": {a person object},
...
}
```
If we cannot match your search to a single person, the [response](/reference/response) will contain a **list of possible persons**. This can happen if, for example, you searched for a common name such as `John Smith`.
This list of people will be prioritized and ordered in descending order by a @match score, representing the confidence level that each result is the person you're looking for.
```json
{
...
"possible_persons":
[{a person object},
{a person object},
... ,
{a person object}
],
...
}
```
The person objects in the response hold the actual data fields.
## 5. Learn More!
[The API Reference](/reference/overview) is the best resource for learning about using the Pipl Search API.
[The Pipl Search API Integration Checklist](pipl-search-api-integration-checklist) walks through the steps and tips for integrating the Pipl Search API
[The Pipl Search Basic Workflow Diagram](general-application-flow-diagram) shows a simple coding workflow using the Pipl Search API.
---
## MCP Server
Pipl provides an [MCP Server](https://modelcontextprotocol.io/) that connects the Pipl Search API to AI assistants like **Cursor**, **Claude Desktop**, **Windsurf**, and any other MCP-compatible client. Once configured, you can run identity searches using natural language — instead of writing API calls or switching to Postman, you can ask your assistant things like *"Search for john.smith@example.com"* and get full identity results inline.
You can connect in two ways:
- **Remote MCP (recommended)** — hosted by Pipl at [`https://mcp.pipl.com/search/`](https://mcp.pipl.com/search/). No install, no local Node.js, always up to date.
- **Local MCP** — run the open-source server from [GitHub](https://github.com/piplcom/piplapis-search-mcp) on your own machine. Useful for offline development, air-gapped environments, or when you want to extend the server.
Both options expose the same Search tools and require only a valid Pipl API key.
## What You Can Do
The MCP server exposes the full power of the Pipl Search API through a set of purpose-built tools:
| Tool | Description |
|------|-------------|
| `search_by_email` | Search by email address |
| `search_by_phone` | Search by phone number (international format, e.g. `+15551234567`) |
| `search_by_name` | Search by name, optionally combined with email, phone, or address |
| `search_by_address` | Search by physical address |
| `search_by_username` | Search by social username (e.g. `superman@facebook`) |
| `search_by_url` | Search by social profile URL (e.g. LinkedIn, Facebook) |
| `search_by_search_pointer` | Follow up on a previous result using a search pointer |
| `search_by_person` | Advanced search with a structured person JSON object |
| `search_raw` | Raw API call with any combination of parameters |
Each tool returns identity data including names, emails, phone numbers, addresses, jobs, education, social profiles, and more.
## Prerequisites
- A **Pipl API key** — sign in at [search.pipl.com/api/manage/keys](https://search.pipl.com/api/manage/keys), or [contact Pipl](https://pipl.com/contact-us) to get access
- **Node.js** 18 or later — *only required for the local MCP option*
## Option 1: Remote MCP (Recommended)
The remote MCP is hosted by Pipl at **`https://mcp.pipl.com/search/`** and serves the Pipl Search product. Authentication is handled per-request by passing your API key as a Bearer token in the `Authorization` header.
### Cursor IDE
Open **Cursor Settings > MCP**, or edit `~/.cursor/mcp.json` directly:
```json
{
"mcpServers": {
"pipl": {
"url": "https://mcp.pipl.com/search/",
"headers": {
"Authorization": "Bearer YOUR_PIPL_API_KEY"
}
}
}
}
```
### Claude Desktop
Edit `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):
```json
{
"mcpServers": {
"pipl": {
"url": "https://mcp.pipl.com/search/",
"headers": {
"Authorization": "Bearer YOUR_PIPL_API_KEY"
}
}
}
}
```
Replace `YOUR_PIPL_API_KEY` with your Pipl API key. Restart your MCP client for the changes to take effect.
:::tip Why use the remote MCP
You don't need to clone a repo, install Node.js, or rebuild after updates — new tools and fixes are deployed automatically.
:::
## Option 2: Local MCP (Self-Hosted)
Prefer to run the MCP server on your own machine? Clone the open-source server from GitHub:
```bash
git clone https://github.com/piplcom/piplapis-search-mcp.git
cd piplapis-search-mcp
npm install
```
### Cursor IDE
Open **Cursor Settings > MCP**, or edit `~/.cursor/mcp.json` directly:
**macOS / Linux:**
```json
{
"mcpServers": {
"piplapis-search": {
"command": "node",
"args": ["/absolute/path/to/piplapis-search-mcp/index.js"],
"env": {
"PIPL_API_KEY": "YOUR_PIPL_API_KEY"
}
}
}
}
```
**Windows:**
```json
{
"mcpServers": {
"piplapis-search": {
"command": "node",
"args": ["C:\\Users\\username\\piplapis-search-mcp\\index.js"],
"env": {
"PIPL_API_KEY": "YOUR_PIPL_API_KEY"
}
}
}
}
```
Restart Cursor for changes to take effect.
### Claude Desktop
Edit `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):
```json
{
"mcpServers": {
"piplapis-search": {
"command": "node",
"args": ["/absolute/path/to/piplapis-search-mcp/index.js"],
"env": {
"PIPL_API_KEY": "YOUR_PIPL_API_KEY"
}
}
}
}
```
Replace `/absolute/path/to/` with the actual path to the cloned repository and `YOUR_PIPL_API_KEY` with your Pipl API key.
:::tip Security
The API key is read from the `PIPL_API_KEY` environment variable and is never logged or exposed in tool outputs.
:::
## Use Cases
### Identity Lookup During Development
While building onboarding, identity-enrichment, or investigation flows, ask your AI assistant to look up and connect real identity data without leaving the IDE:
> *"Search for jane.doe@company.com and check if the name matches Jane Doe in San Francisco"*
The assistant calls `search_by_email` (or `search_by_name` with email), returns the matched identity, and you can immediately see whether the name, location, and other attributes align — all without writing a single API call.
### Investigating Suspicious Users
When reviewing flagged accounts or investigating fraud signals, pull up a complete identity profile in seconds:
> *"Look up the phone number +14155550123 and show me all associated social profiles"*
The assistant calls `search_by_phone`, returns names, emails, addresses, social URLs, and more — giving you a full picture of the person behind the number.
### Enriching Contact Data
Enrich partial contact records by searching with what you have and getting back the full identity profile:
> *"I have a LinkedIn profile linkedin.com/in/johndoe — find the person's email and phone number"*
The assistant calls `search_by_url` and returns all available identity data associated with that profile.
### Resolving Ambiguous Matches
When a search returns multiple candidates, use the search pointer to drill into a specific person:
> *"Search for John Smith in New York"*
If the API returns several possible persons, you can follow up:
> *"Resolve the second candidate using their search pointer"*
The assistant calls `search_by_search_pointer` to retrieve the full profile for that specific individual.
### Bulk Testing & Validation
Use the `search_raw` tool for flexible queries during testing, or `search_by_person` for structured multi-field searches:
> *"Search for a person with first name Clark, last name Kent, email clark.kent@example.com"*
:::info Free Test Query
Any query containing the email `clark.kent@example.com` is free and returns static example output — useful for testing your setup without consuming API credits.
:::
## Understanding Responses
The Pipl Search API returns one of three outcomes:
- **Person Match** — A single high-confidence person was found. This is a definitive match.
- **Possible Persons** — Multiple candidates were found. Each includes a `@search_pointer` you can use with `search_by_search_pointer` to resolve a specific person.
- **No Match** — No person found.
:::warning Important
A match score of `0` does **not** mean "no match" — it means the confidence level is undetermined (not enough data to rank). All returned possible persons are real candidates.
:::
## Resources
- [Remote MCP Endpoint](https://mcp.pipl.com/search/) — hosted by Pipl
- [Local MCP Server GitHub Repository](https://github.com/piplcom/piplapis-search-mcp)
- [MCP Protocol Specification](https://modelcontextprotocol.io/)
- [Pipl Search API Documentation](https://docs.pipl.com)
- [API Reference](https://docs.pipl.com/reference)
---
## Integration Checklist
As you integrate the Pipl Search API, you want to make sure that your integration is robust and optimized. This integration checklist is meant to help guide you through the process and make sure you covered all your bases.
## Optimizing Requests
- [ ] Do you need [match criteria](/reference/match-criteria)? Set correctly to get as much useable data as possible
- [ ] If multiple data fields can be used in a response, use the OR parameter
- [ ] Use @type metadata for more granular filtering, if necessary
- [ ] What [query parameters](/reference/using-search-parameters) are being sent to Pipl?
- Generally, more info in the query leads higher match rate and data fill
- [ ] Take a look at [some common search queries](/reference/using-search-parameters#common-search-queries) to get an idea for what you can include in a search query
- [ ] Are you [optimizing for speed/throughput or maximum data fill]best-practices-by-use-case#performance-optimization) ?
- [ ] Consider parameter [live_feeds=true](rate-limiting#live-feeds) for 2-3% more data fill, but with increased latency (1 to 2 seconds) and a maximum QPS of 10 (compared to 20 with live_feeds=false)
- [ ] Have you implemented [query rate throttling](rate-limiting-your-queries)?
- [ ] QPS limit (by default 20, 10 when live_feeds=true)
- [ ] Review [Recommended libraries](rate-limiting-your-queries#how-to-best-implement-a-throttling-mechanism)
- [ ] Are you validating data before sending?
- [ ] Validate phone numbers using Google's libphonenumber (Pipl Search uses this). Raw phone numbers are in international format
- [ ] Validate email format
- [ ] Are you ensuring your queries meet [minimum requirements](/reference/request-overview#minimum-requirements)?
## Reading a Response
- [ ] Are you taking advantage of [the source layer](/reference/know-your-sources)?
- [ ] Set parameter show_sources=matching
- [ ] Attributes data points in the response to their source
- [ ] Use [Tags in the source layer](/docs/pipl-api-tags) for additional data such as professional skills and courses, vehicle info, NPI, home ownership, and death records
- [ ] Are you keeping data in the order that Pipl returned it?
- The data items in a Search response will be ordered by relevance and recency
- [ ] Are you paying attention to [last seen and valid since dates](/reference/data-fields)?
- [ ] Are you using the metadata @type(example: phone type= mobile vs work)
- [ ] Can you handle null data fields?
- If the response doesn’t have a data field, that field key will be removed. For example, if a response has no jobs, there will be no jobs key or field in the response.
## Processing and storing a query and response
- [ ] How do you want to [handle possible person responses](/reference/response-types#how-to-handle-possible-person-responses)?
- [ ] Show me the best possible person in the response ([parameter top_match](/reference/top_match-configuration-parameter)=true)
- [ ] Don't show me possible person responses (parameter [minimum_match](/reference/match-criteria#minimum-match)=1)
- [ ] Only show me possible persons above a certain threshold of match (parameter [minimum_match](/reference/match-criteria#minimum-match) between 0 and 1)
- [ ] Dig deeper into possible person responses (use a two tiered search approach by searching on [the search pointer](/reference/search-pointer) of one or all of the possible persons)
- [ ] Show me all possible persons (make no adjustments to configuration parameters)
- [ ] Are you logging all queries made to the Pipl API?
- [ ] Also log the @search_id for troubleshooting with Pipl
- [ ] Do you have appropriate [error handling](/reference/errors) in your code?
- [ ] Are you logging and reviewing warnings and errors returned by the Pipl Search API?
- [ ] Review warnings in order to optimize searches (address or name was parsed wrong, a field was ignored because it was invalid)
## General
- [ ] Have you tested your search flow using the non-billed example email, [clark.kent@example.com](mailto:clark.kent@example.com)?
- [ ] Reach out to your Account Manager, Customer Success team or [contact customer support](https://pipl.com/customer-support) to answer any questions or review your search strategy
---
## Postman Collection
Use Postman to test the Pipl Search API to troubleshoot query issues before integrating. To do this, [download and install Postman](https://www.postman.com/downloads/) and then [import](https://learning.postman.com/docs/getting-started/importing-and-exporting/importing-data#import-postman-data) the Pipl Search API Postman Collection.
## Configure Your Search API Key
After importing the collection, open its **Authorization** tab and update the API key `value` with your own key. You can find your key on your [API Keys page](https://search.pipl.com/api/manage/keys).
[Learn more about using Postman as an API testing tool](https://learning.postman.com/docs/getting-started/introduction/)
---
## Welcome to the Pipl Search API
import { Card, CardGroup } from '@site/src/components/Card';
import { faRocket, faCode, faFlask, faDatabase, faGlobe, faTags, faWandMagicSparkles, faLightbulb, faGaugeHigh, faMagnifyingGlass, faLocationDot, faChartLine, faSitemap, faSliders, faImage, faBook, faClipboardList, faCircleQuestion, faEnvelope, faFileCode, faClockRotateLeft } from '@fortawesome/free-solid-svg-icons';
# About the Pipl Search API
Pipl Search helps you gather information on customers and contacts to ensure that you are targeting the right people with the right content. This is useful across multiple use cases:
- **Fraud Investigation & Risk** — Fraud / Risk Management, E-commerce, AML, Fintech.
- **Investigation** — OSINT Platforms, Law Enforcement, Government, News Media, Risk Management, Cyber Security & Insurance.
- **Consumer People Search** — Background reporting websites.
- **Contact Enrichment** — Lead Enrichment, Recruitment, Real Estate and Sales Intelligence platforms. Medical Recruiting (US) & Marketing.
Use the Pipl Search API to automate your searches and collect results into a format that is easily consumable by your website or application. If you need more detailed information on the API, see the [Pipl Search API Reference](/reference/overview).
---
## Get Started
If you're new to Pipl Search, start here to set up your environment and make your first API call.
Set up your API key and make your first search request.
Official SDKs for Python, Ruby, Java, PHP, and C#.
Ready-to-use code examples and sample programs for common API operations.
Import our Postman collection for quick API testing.
---
## Learn About Pipl Data
Understand the data types, sources, and capabilities of the Pipl Search API.
Learn about the different data fields returned by the API.
Discover where Pipl data comes from and how it's collected.
Understand how Pipl infers additional data points.
Use tags to get more data out of your integration. Access deceased info, marriage and divorce records, home ownership, and more.
---
## Best Practices
Optimize your integration and get the most out of Pipl Search.
Visual guide to the recommended integration flow.
Tailored recommendations for contact enrichment, real estate, investigation, fraud prevention, and performance optimization.
Understand and manage API rate limits effectively.
Tips for getting the best results when searching by name.
Optimize your address-based searches for better matches.
Use Pipl data in machine learning models and identity investigation to make informed business decisions.
---
## Tutorials
Step-by-step guides to help you master the Pipl Search API.
Learn advanced search techniques including multiple fields, social profiles, VIN, CPF, NPI, job/education, relationships, and MD5 email searches.
Display and use profile images in your application using the free Pipl Thumbnails API.
---
## Reference & Resources
Complete API documentation with endpoints, parameters, and response formats.
Ensure your integration follows all best practices before going live.
Stay updated with the latest API changes, new features, and improvements.
---
## Support
Find answers to frequently asked questions.
Get help with technical issues, billing, or other support requests.
---
## Email Owner API Key
Responses made from an Email Owner API key have the same basic response structure as other search API responses, but only can be queried by an email, and the name of the is returned (if available). Data coverage is similar to all other keys, including but live sources are not included.
The Email Owner API key is used with the regular search endpoint (`https://api.pipl.com/search`), but a special key issued to your organization will tell the system that you're doing a Email Owner search.
Email Owner is the Search-powered member of the **Pipl Elements** suite: it resolves the likely owner of an email address on the Pipl Identity Graph. Unlike Email Score and Email Intelligence, it is not powered by Elephant and does not return a Trust Score.
## **Practical Applications**
***
The Email Owners key is intended for applications that require understanding of possible owners of a particular email address. If more data is needed than is included in the Email owner key response, one can opt to make the query using a regular Business key instead.
## **Main Characteristics**
***
**Billing** – The Email Owner key, like any regular API key, is a Pay-Per-Match key, and both Person and Possible Persons responses are considered a match.
**Use case** - Only an Identity Verification use case is permitted.
**Query input** - Both parameter search and a Person search are permitted, but in the Person search, limited to a single email address in the search. Note that MD5 hash of an email address is permitted.
**Data Coverage** – Responses return data from Pipl's indexes, however live sources are not available.
**Data Types** – Only the data type of name is returned. Metadata tags such as @match, @valid_since and @last_seen are returned as well. In the query section, information about the Email address will be returned, including the type of email. See the [Email Search API reference](/reference/email) for a complete list of metadata that will be returned if available (prefixed with the @ sign).
**Available Data** - The available data summary is not returned.
**Configuration parameters** - No configuration parameters are permitted. By default any profile with a name will be returned by this key.
**Testing**
To test your key, you can query using your Email owner key with the email address '[clark.kent@example.com](mailto:clark.kent@example.com)' This query will not be charged and will return an API response that can be used for testing.
**Response types**
Only possible_person or no match responses will be returned for this key.
**Errors and warnings**
If an email address is not of valid format, and cannot be searched, an HTTP status code of 400 will be returned.
---
## Emails API Key
Responses made from an Emails API key have the same basic response structure as other search API responses, but only the emails data field is returned (if available). Data coverage is similar to all other keys, including optional live sources.
The Emails API key is used with the regular search endpoint (`https://api.pipl.com/search`), but a special key issued to your organization will tell the system that you're doing an Emails key search.
## **Practical Applications**
***
The Emails key is intended for applications that require one or more email addresses but no other response elements. If more data is needed than is included in the Emails key response, one can opt to make the query using a regular Business key instead (either on the data elements used in the original query or on the search pointer that was returned for it.)
## **Main Characteristics**
***
**Billing** – The Emails key, like any regular API key, is a Pay-Per-Match key.
**Data Coverage** – Responses return data from Pipl's indexes, including optional live sources.
**Data Types** – Only the data type of email is returned. Metadata tags such as @match, @valid_since and @last_seen are returned as well.
**Available Data** - The available data summary returned is a reflection of what is available if the query were made with a Business key.
**Configuration parameters** - All configuration parameters are supported according to the data that's available. By default any profile with an email will be returned by this key. [Match requirements](/reference/match-criteria) using [email subtypes](/reference/email) can further refine which profiles will be returned as matches.
**Testing**
To test your key, you can query using the email '[clark.kent@example.com](mailto:clark.kent@example.com)' This query will not be charged and will return an API response that can be used for testing.
---
## Phone Owner API Key
Responses made from a Phone Owner API key have the same basic response structure as other search API responses, but only can be queried by a single phone number, and the name of the is returned (if available). Data coverage is similar to all other keys, including but live sources are not included.
The Phone Owner API key is used with the regular search endpoint (`https://api.pipl.com/search`), but a special key issued to your organization will tell the system that you're doing a Phone Owner search.
Phone Owner is the Search-powered member of the **Pipl Elements** suite: it resolves the likely owner of a phone number on the Pipl Identity Graph. Unlike Phone Score and Phone Intelligence, it is not powered by Elephant and does not return a Trust Score.
## **Practical Applications**
***
The Phone Owner key is intended for applications that require understanding of possible owners of a particular phone number. If more data is needed than is included in the Phones owners key response, one can opt to make the query using a regular Business key instead.
## **Main Characteristics**
***
**Billing** – The Phone Owner key, like any regular API key, is a Pay-Per-Match key, and only Possible Persons responses are considered a match.
**Use case** - Only an Identity Verification use case is permitted.
**Query input** - Both parameter search and a Person search are permitted, but in the Person search, limited to a single phone number in the search.
**Data Coverage** – Responses return data from Pipl's indexes, however live sources are not available.
**Data Types** – Only the data type of name is returned. Metadata tags such as @match, @valid_since and @last_seen are returned as well. In the query section, information about the Phone number will be returned, including the carrier of the phone number. See the [Phone Search API reference](/reference/phone) for a complete list of metadata that will be returned if available (prefixed with the @ sign).
**Available Data** - The available data summary is not returned.
**Configuration parameters** - No configuration parameters are permitted. By default any profile with a name will be returned by this key.
**Testing**
To test out this key, you can request a temporary testing key from your sales/account manager. Because this key only accepts phone numbers, the testing email address '[clark.kent@example.com](mailto:clark.kent@example.com)' will not work.
**Response types**
Only possible_person or no match responses will be returned for this key.
**Errors and warnings**
If a phone number is not valid and cannot be searched, an HTTP status code of 400 will be returned.
---
## Phones and Emails API Key
Responses made from a Phones+Emails API key have the same basic response structure as other search API responses, but only the emails and phone numbers data fields are returned (if available). Data coverage is similar to all other keys, including optional live sources.
The Phones+Emails API key is used with the regular search endpoint (`https://api.pipl.com/search`), but a special key issued to your organization will tell the system that you're doing a Phones+Emails key search.
## **Practical Applications**
***
The Phones+Emails key is intended for applications that require one or more email addresses, phone numbers or both in the response but do not require other response elements. In case more data is needed than is provided in the Phones+Emails key response, one can make the query using a regular Business key instead (either on the data elements used in the original query or on the search pointer that was returned for it).
## **Main Characteristics**
***
**Billing** - The Phones+Emails key, like any regular API key, is a Pay-Per-Match key, and both Person and Possible Persons responses are considered a match.
**Data Coverage** - Responses return data from Pipl's indexes, including optional live sources.
**Data Types** - Only the data types of [phone](/reference/phone) and/or [email](/reference/email) are returned. The meta data tags such as @match, @valid_since and @last_seen are returned.
**Available Data** - The available data summary returned is a reflection of what is available when running on a Business key.
**Configuration parameters** - All configuration parameters are supported according to the data that's available. By default any profile with either a phone or email will be returned by this key. [Match requirements](/reference/match-criteria) including with phone and email subtypes can further refine which profiles will be returned as matches.
**Testing**
To test your key, you can query using your phone+email key and the email '[clark.kent@example.com](mailto:clark.kent@example.com)' This query will not be charged and will return an API response that can be used for testing.
---
## Phones API Key
Responses made from a Phones API key have the same basic response structure as other search API responses, but only the phones data field is returned (if available). Data coverage is similar to all other keys, including optional live sources.
The Phones API key is used with the regular search endpoint (`https://api.pipl.com/search`), but a special key issued to your organization will tell the system that you're doing a Phones key search.
## **Practical Applications**
***
The Phones key is intended for applications that require one or more phone numbers but no other response elements. If more data is needed than is included in the Phones key response, one can opt to make the query using a regular Business key instead (either on the data elements used in the original query or on the search pointer that was returned for it.)
## **Main Characteristics**
***
**Billing** – The Phones key, like any regular API key, is a Pay-Per-Match key, and both Person and Possible Persons responses are considered a match.
**Data Coverage** – Responses return data from Pipl's indexes, including optional live sources.
**Data Types** – Only the data type of phone is returned. Metadata tags such as @match, @valid_since and @last_seen are returned as well.
**Available Data** - The available data summary returned is a reflection of what is available if the query were made with a Business key.
**Configuration parameters** - All configuration parameters are supported according to the data that's available. By default any profile with a phone will be returned by this key. [Match requirements](/reference/match-criteria) using [phone subtypes](/reference/phone) can further refine which profiles will be returned as matches.
**Testing**
To test your key, you can query using your phone key and the email '[clark.kent@example.com](mailto:clark.kent@example.com)' This query will not be charged and will return an API response that can be used for testing.
---
## Pipl Search Subscription Plan
The subscription plan supports Pipl's customers in the contact enrichment space by subscribing you to a query result from Pipl Search for each of your contacts. It is a cost effective way to update and maintain a large list of contacts. You pay a monthly fee per enriched record for as long as you want to keep & update your database.
A Pipl Search subscription entitles you to:
1. The Pipl Search result for all your subscribed contacts
2. Quarterly updates on all subscribed contacts for the duration of the subscription
3. Free, unlimited use of the [Teaser key](/docs/teaser-api)
4. Free, unlimited use of the [Summary key](/docs/summary-api)
## How it Works
The Subscription API key is used with the regular search endpoint (`https://api.pipl.com/search`), but a special key issued to your organization. This same key will also be used for free quarterly updates.
> 🚧 The [Pipl Search code libraries](/docs/code-libraries) do not currently support the Subscription plan.
Responses made from a Subscription plan API key have the [same basic response structure](/reference/response) as other search API responses, but the only difference is that the search_pointer is replaced by an update_pointer for Person responses. The update_pointer can only be used with a Subscription plan key. Data coverage is the same as standard keys, including optional live sources.

If a new query returns a match, then that query result will be added to your subscription. Queries using the update pointer will be counted toward your quarterly allotment of updates. Queries returning a [no match](/reference/response-types#no-match) or that do not meet [your match requirements](/reference/match-criteria#match-requirements) will not be counted towards your subscription.
> 📘 Please note that all matches on the subscription key, except those using the update pointer, will add a contact to your subscription. If you send [duplicate queries](/docs/faq#how-do-you-bill-for-api-usage) without using the update pointer, each query that matches will be charged to your subscription.
The subscription plan grants free, unlimited use of the Summary and Teaser keys. This can help you determine availability of data as well preview a "tease" of that data. Please note that the summary key doesn't differentiate between personal and work emails, so you would need to use the Teaser key for this.
[Teaser key documentation](/docs/teaser-api)
[Summary key documentation](/docs/summary-api)
## Plan Details
**Billing** – All Subscription keys, like any regular API key, work similar to a Pay-Per-Match key, and both Person and Possible Person responses are considered a subscribed match. Please note:
- Person responses will contain update_pointer instead of a search_pointer
- Possible Person responses, will contain an update_pointer in the query section, and each Possible Person in the response will have search_pointer that can be used to [expand to a full person profile](/reference/response-types#how-to-handle-possible-person-responses).
**Data Coverage **– Responses return data from Pipl's indexes, including optional live sources.
**Data Types** – Data types returned are based on the Subscription plan key type used. Metadata tags such as @match, @valid_since and @last_seen are returned as well.
**Available Data** - The available data summary returned is a reflection of what is available if the query were made with a Business key. This section of the response can also be seen using the [Summary key](/docs/summary-api) which is provided free of charge with the subscription plan.
**Configuration parameters** - All configuration parameters are supported according to the data that's available for the key type used. It is recommended to use [match_requirements](/reference/match-criteria#match-requirements) to only subscribe to profiles that are relevant to the enrichment use case.
## Performing updates with the update pointer
Subscription customers are entitled to free quarterly updates using the subscription key and the dedicated update_pointer parameter.
Each quarter, you receive credit to update each contact you are subscribed to a single time. Each query that uses the update_pointer as a query input parameter will count towards your total allotment. Quarters are defined by month based on standard fiscal quarters (Q1 = January through March, etc.). This cadence lines up with Pipl's quarterly index updates.
> 📘 Pipl sends email notifications each time we update our quarterly index, generally in the first month of each quarter. Your subscription record updates should be performed after this notification is sent to ensure the updates reflect the most recent data.
> 🚧 We will count each update request (and reduce it from the quarterly limit of updates) - even if the update_pointer has already been requested several times.
Your invoice reflects the number of contacts you are subscribed to. The update usage is not on your invoice, however. You can see through [your Pipl account](https://search.pipl.com/api/manage/usage) the number of remaining updates.

### Sending update pointer queries
You may use all standard configuration parameters when running updates.It's recommended to run updates using minimum_match=1.
Because update pointers can be very long, searches made with them should be made via POST with the update pointer included in the request body. Requests using GET or with POST and the search pointer embedded directly in the URL are likely to return HTTP 414 Request-URI too long errors.
> 🚧 For most use cases, it's not recommended to run update_pointer requests returned from Possible Person responses.
#### Example
Replace UPDATE_POINTER_STRING with a valid update pointer and YOURKEY with a PIpl Search Key with an active subscription plan.
```curl
curl -X POST https://api.pipl.com/search/ \
-d update_pointer='UPDATE_POINTER_STRING' \
-d key=YOURKEY
```
## Testing
To test your key, you can query using the email 'clark.kent@example,com' This query will not be charged and will return an API response that can be used for testing.
## Errors
Please be sure to add error handling to your integration to accommodate for the following errors.
| Status Code | Error Type | Error message | Description | Resolution |
|-------------|------------|---------------|-------------|------------|
| 400 | Reached Update Limit | Your updates have exceeded the limit. For more information, contact your account manager or our support team at [support@pipl.com](mailto:support@pipl.com) | You have run updates this quarter that meet your total number of subscribed records | Subscribe to more records or wait until the next quarter to update records. |
| 400 | Invalid update_pointer or using an update_pointer on a non-subscription key | The provided parameter is not valid for this plan. | Update pointers and search pointers are not interchangeable. Attempting to use a search_pointer or anything other than an update pointer in the update_pointer query input parameter will result in this error. You will also see this error when trying to send the update pointer parameter in keys that are not subscription keys, or when sending an updated pointer that is not related to the plan (e.g sending a social plan update pointer to a business plan subscription key). | Make sure the API key you are using is valid and connected to an active subscription plan. Also make sure, if performing an update, that the update_pointer is a valid update_pointer. |
| 403 | Subscription Expired | Your plan expired on 2019-04-08 04:59:59+00:00 | Your subscription expired | Contact your Pipl account manager to renew your Pipl Search subscription |
---
## Recruiter API Key
Pipl's Recruiter Key API response is similar to a regular API response, except for certain data fields that are not shown. Data coverage is similar to the [Business key](https://pipl.com/api/pricing) including optional live sources.
To use the Recruiter Key API, the regular API endpoint is used (`https://api.pipl.com/search`), but a special key issued to your organization will tell the system that you're doing a recruiter search.
The data returned in the response will be structured the same as any regular key, but not all the fields will be included as well as some sub types as will be detailed below.
## Practical Applications
The Recruiter key is intended for applications in which the response is used in order to provide only the relevant data fields to customers in the recruiting business . In case more data is needed than is provided in the Recruiter response, one can opt to use a regular Business key using the initial data or a [search-pointer](/reference/search-pointer) as the search base.
The response, although partial, is designed to provide enough information to reliably identify the individual, and get a good overview of a person.
## Main Characteristics
**Billing** – The Recruiter key, like any regular API key, is a Pay-Per-Match key.
**Data Coverage** – Responses return data from Pipl's premium indexes, including optional live sources.
**Data Types** – Not all data types are returned and not all data subtypes are returned. The meta data tags such as @match, @valid_since and @last_seen are returned.
**Available Data** - The available data summary returned is a reflection of what is available when running on a Business key. The actual counts for data fields returned in the response may differ.
**Configuration parameters** - All configuration parameters are supported according to the data that's available. The valid match_requirements fields that can be used are: name, address, phone (or phone.mobile), email.personal, images, education and job.
Please note that if using email with the match requirements parameter, you must use the email.personal type. Using a match_requirement of just email (without the personal type) may return inconsistent results since the Recruiter key only returns personal emails.
## Field obfuscation behavior
### Gender
> ❗️ Not shown
### Language
> ❗️ Not shown
### Name
> 👍 Always shown
### Relationship
> ❗️ Not shown
### Address
> 🚧 Partialy shown
The city, state and country will always show. Street, house, apartment and zip code will not show, nor will there be an indication of their existence.
```json
"addresses": [
{
"@type": "work",
"country": "US",
"state": "TX",
"city": "Austin",
"display": "Austin, Texas"
}
```
### DOB
> ❗️ Not shown
### Phone
> 👍 Always shown
### Username
> ❗️ Not shown
### UserID
> 🚧 Partally shown
If available, only LinkedIn user-id's will appear.
### Email
> 🚧 Patially shown
Only personal emails will be shown. Emails that do not have a subtype "personal" will not appear.
### Images
> 👍 Always shown
### Education
> 👍 Always shown
### Job
> 👍 Always shown
### URL
> 🚧 Partially shown
If available, only Linkedin URLs will show
---
## Summary API Key
The Pipl Summary API response is similar to a regular API response, however only the [header information](/reference/response) from the response is returned with no person nor possible_persons included. The information returned from a Summary API response includes:
- The available_data summary - see [field count](/reference/field-count)
- @persons_count
- @available_sources
- query
Data coverage is similar to [Business Premium](http://pipl.com/api/pricing) key excluding live sources.
To use the Summary API, the regular API endpoint is used (`https://api.pipl.com/search`), but a specialized key issued to your organization will tell the system that you're doing a summary search.
## Practical Applications
The summary key is a way to discover the availability of data, but does not include the actual data returned in a full API response. This information is used to inform/tease a user of the availability of data which is then followed up by a Premium key call.
## Summary Key Example
Below is an example of a SUMMARY key response after sending a request with the email [clark.kent@example.com](mailto:clark.kent@example.com) as the search query:
```json
{
"@http_status_code": 200,
"@visible_sources": 0,
"@available_sources": 3,
"@persons_count": 1,
"@search_id": "0",
"query": {
"emails": [
{
"address": "clark.kent@example.com",
"address_md5": "2610ee49440fe757e3cc4e46e5b40819"
}
]
},
"available_data": {
"premium": {
"relationships": 6,
"usernames": 2,
"jobs": 3,
"addresses": 2,
"ethnicities": 3,
"phones": 1,
"landline_phones": 1,
"educations": 2,
"languages": 1,
"user_ids": 1,
"social_profiles": 2,
"names": 3,
"dobs": 1,
"images": 2,
"genders": 1,
"emails": 4,
"work_emails": 2,
"personal_emails": 1,
"origin_countries": 1
}
}
}
```
## Main Characteristics
**Billing** - The API is billed per call (not per match).
**Data Types**
- @visible_sources will always be 0 as these are not revealed in the Summary API
- If no information was found based on your search criteria, the available_data section will not appear in the JSON response.
- The persons_count field will let you know if you received no match (persons_count = 0), a person result (persons_count = 1), or several possible persons in the result (persons_count >= 1).
**Match criteria** - The _minimum_match_ and [top_match](/reference/top_match-configuration-parameter) configuration parameters may be used as a filter. The \_match_requirements \_and \_source_category_requirements \_parameters are not supported.
**Data Coverage** – Responses return data from Pipl's index, but not from live sources.
---
## Teaser API Key
The Pipl Teaser API response is similar to a regular API response, with some parts of the data obfuscated. Data coverage is similar to [Business Premium](https://pipl.com/api/pricing) excluding live sources.
To use the Teaser API, the regular API endpoint is used (`https://api.pipl.com/search`), but a specialized key issued to your organization will tell the system that you're doing a teaser search.
The data returned in the response can be obfuscated in 4 different visibility modes: Fully shown, masked, mentioned, and completely hidden. Each data field in the response is obfuscated differently, depending on the input provided in the search request.
## Practical Applications
The Teaser key is intended for applications in which the response is used in order to provide a preview of the data to end users, usually before conversion. Following conversion, a regular API request can be made to retrieve the full response.
The response, although obfuscated, is designed to provide enough information to reliably identify the individual, and get an overview of what can be retrieved from a full API request.
Once a person from the teaser response is identified, it is straightforward to use the [Search pointer](/reference/search-pointer) to run a follow up full API request.
## Main Characteristics
**Billing** – The Teaser key, unlike regular API keys, is a Pay-Per-Call key.
**Data Coverage** – Responses return data from Pipl's basic and premium indexes, but not from live sources.
**Data Types** – All data types may be returned (same as a Business key). The meta data tags such as @match, @valid_since and @last_seen are not returned in the Teaser response.
**Obfuscation** - The search input data is _always_ fully visible in the response. Other data fields are shown based on the kind of search that has been executed (details below).
**Configuration parameters** - No match criteria parameters are available except for _minimum_match_ which is used as a filter. Neither the _match_requirements_ nor _source_category_requirements_ parameters are supported. Additionally, the _show_sources_ parameter is not supported.
## Obfuscation
The obfuscation model has 4 visibility modes:
**Shown** – Data field is fully shown, as in the regular API response.
**Masked** – Partial information is shown:
Strings are fully or partially masked with "\*"
With numbers, the last four digits of the number are replaced with 0.
**Mention** – Availability of field is shown, but no actual information is given. Strings are converted to "value available in full api response".
**Hidden** – The field is not displayed at all.
Note that some fields are obfuscated differently depending on the query input.
## Field obfuscation behavior
### Gender
> 👍 Always shown
### Language
> 👍 Always shown
### Name
> 📘 Shown or masked
Name and relationship fields behave differently depending on the data sent in the request:
Shown only when name is sent in the request. In all other cases it is masked. Masking is done by showing only the first letter of a first and middle name followed by 4 asterisks'. The last name is completely masked (i.e. all asterisks').
```json
"names": [
{
"first": "H****",
"last": "****",
"display": "H**** ****"
}
```
### Relationship
> 📘 Shown, masked or mentioned
Shown only when name is sent in the request. When address is sent in the request all data in the relationship field is masked. In all other cases data in the relationship field is mentioned. Masking is done the same way name is masked (see above).
```json
"relationships": [
{
"@type": "value available in full api response",
"names": [
{
"first": "value available in full api response",
"last": "value available in full api response",
"display": "value available in full api response"
}
```
### Address
> 🚧 Always masked
The city, state and country will always show. Street, house, apartment and zip code will be mentioned.
```json
"addresses": [
{
"@type": "work",
"country": "US",
"state": "TX",
"city": "Austin",
"street": "value available in full api response",
"house": "value available in full api response",
"apartment": "value available in full api response",
"zip_code": "value available in full api response",
"display": "Austin, Texas"
}
```
### DOB
> 🚧 Always masked
Age is displayed. Exact date is not shown.
```json
"dob": {
"display": "36 years old"
}
```
### Phone
> 🚧 Always masked
The last 3 digits of phone are replaced with 000. If there is an extension, it will be removed.
```json
"phones": [
{
"type": "home_phone",
"country_code": 1,
"number": 9785556000,
"display": "978-555-6000",
"display_international": "978-555-6000"
}
```
### Username
> 🚧 Always masked
The first two characters of the username are shown followed by 4 asterisks.
```json
"usernames": [
{
"content": "ab****"
}
```
### UserID
> 🚧 Always masked
The first two characters of the user id are shown followed by 4 asterisks. The domain of the service will always show.
```json
"user_ids": [
{
"content": "12****@facebook"
}
```
### Email
> 🚧 Always masked
The first two letters of the local-part are shown followed by 4 asterisks. The domain will show only the first letter of the domain followed by 4 asterisks.
```json
"emails": [
{
"@type": "work",
"@email_provider": false,
"address": "cl****@h****.com",
"address_md5": "eb3e11de3c9cefc2d9d70972350e2b28"
}
```
### Vehicles
> 🚧 Always masked
Make, model year and type are always shown. Vin will be mentioned.
```json
"vehicles":
[
{
"vin": "value available in full api response",
"year": "2002",
"make": "ford",
"model": "f150",
"type": "pickup",
"display": "value available in full api response"
}
]
```
### Images
> 🚧 Always masked
The textual results that are returned in the Teaser's json response can be easily parsed and displayed. To get the image you will need to call [Pipl's thumbnail server](/docs/thumbnails) with the image token from the Teaser's json response. The returned image will be a 100x100 pixels blurred image.
```json
"images": [
{
"thumbnail_token": "AE2861B242686E7BD0CB4D9049298EB7D18FEF66D950E8AB78BCD3F484345CE74536C19A85D0BA3D32DC9E7D1878CD4D341254E7AD129255C6983E6E154C4530A0DAAF665EA325FC0206F8B1D7E0B6A3AC92AD25ACB21DDC6CD20BE7D82734DAE4C8B5"
}
],
```
#### Regular image vs. Teaser image
 
### Education
> ❗️ Always mentioned
```json
"educations": [
{
"school": "value available in full api response",
"display": "value available in full api response"
},
{
"degree": "value available in full api response",
"school": "value available in full api response",
"display": "value available in full api response"
}
```
### Job
> ❗️ Always mentioned
```json
"jobs": [
{
"title": "value available in full api response",
"organization": "value available in full api response",
"industry": "value available in full api response",
"display": "value available in full api response"
}
```
### URL
> ❗️ Always mentioned
All the details of the URL are shown except for the actual URL.
```json
"urls": [
{
"@source_id": "edc6aa8fa3f211cfad7c12a0ba5b32f4",
"@domain": "linkedin.com",
"@name": "LinkedIn",
"@category": "professional_and_business"
}
```
---
## How to Manage API Keys
## Creating new keys
As an administrator you can create additional Contact, Social and/or Business keys on your [API keys page](https://search.pipl.com/api/manage/keys/). Simply navigate to the bottom of the page, and click on the "+ New Search Key" button to add a new key.

- The "+ New Search Key" button will only be available if you have a working credit card on the account or alternate arrangement with Pipl billing.
- If you are contracted to any other type of key besides a standard Contact, Social or Business key, such as a package key, these keys cannot be created on this page. Please reach out to [Pipl support](https://pipl.com/contact-us) and/or your Account Manager.
## Deactivating a Key
To deactivate an API key, simply hover over the key, click the three lines to the right of the key and select "Deactivate" from the popup menu. This will disable any use to the API key and result in HTTP status 403 errors being returned for any subsequent queries on the key.

Pipl recommends that you disable an API key if you suspect any misuse or exposure of the key to anyone unauthorized to use it. See our [API key security best practices](/docs/api-key-security-best-practices).
## Other Relevant Topics
- [API key security best practices](/docs/api-key-security-best-practices) to learn how to keep your keys safe
- [Setting quotas on your API keys](/docs/monitoring-usage-and-spend) to help monitor your usage and spend
- [Monitoring package key usage and spend](/docs/monitoring-package-key-usage-and-spend)
---
## Linking Social Username, User ID and URL
In this short tutorial we’ll help you to determine the link between a [user ID](/reference/user-id), [username](/reference/username) and [URL](/reference/url) by activating and using the sources layer.
Switching on [the sources layer](/reference/know-your-sources) with the configuration parameter “show_sources=matching” will allow you to see the sources used to build the profile. This layer lets you know where the data was sourced, and helps you determine the linkage between a user-id, username and URL. To connect the data fields of a single social profile, search the sources layer for the source that includes one of the data points of interest, such as a username. The other data fields (user ID and url) under this same source will be the fields that are connected together for this social profile.
## Example
In the example below, we’ve highlighted the user-id, username and URL from a “Facebook” source which we acquired when we queried the Pipl API by email address [clark.kent@example.com.](mailto:clark.kent@example.com.) We were able to link the following data:
- User-id: 11231@facebook
- Username:clarkkent@facebook
- URL: [http://facebook.com/clarkkent](http://facebook.com/clarkkent)
```text
"@id": "5d836a4acc55922e49fc709c7a39e233",
"@category": "personal_profiles",
"@name": "Facebook",
"@origin_url": "**http://facebook.com/clarkkent**",
"@domain": "facebook.com",
"@person_id": "9182cf87-5fd8-499a-91e5-3bf876405da8",
"@match": 1.0,
"names": [
{
"first": "Clark",
"last": "Kent",
"display": "Clark Kent"
}
],
"usernames": [
{
"content": "clarkkent@facebook"
}
],
"user_ids": [
{
"content": "11231@facebook"
}
],
"phones": [
{
"@type": "home_phone",
"country_code": 1,
"number": 9785550145,
"display": "978-555-0145",
"display_international": "+1 978-555-0145"
}
],
"gender": {
"content": "male"
}
"tags": [
{
"@valid_since": "2020-10-06",
"@last_seen": "2020-10-06",
"@classification": "followers",
"content": "1957"
},
{
"@valid_since": "2020-10-06",
"@last_seen": "2020-10-06",
"@classification": "following",
"content": "1735"
}
]
```
---
## Q3 2022 - Index Update
Guess what? We've added a new update to the Pipl Search Identity Index with hundreds of millions of new data elements.
- 210 million new international phone numbers
- 110 million new international email addresses
- Over 90 million new U.S. addresses with homeowners' information
- 118 million updated international career profiles
- Also included in these numbers is a big bump in Brazil—30 million new Brazilian profiles, bringing us to 242 million updated profiles with 30 million new CPFs, over 140 million new phone numbers and over 60 million new email addresses.
_July 17, 2022_
---
## Q4 2022 - Index Update
Drumroll, please! Introducing our latest Pipl Search Identity Index update with the following content:
- 127 million new international phone numbers
- 111 million updated career profiles
- 89 million new U.S. addresses with an additional 14 million properties with homeowner data
- 18 million new US email addresses
- 49 million new unique Brazilian CPFs
- NEW! 113 million records updated with indication of being deceased
_Oct 23, 2022_
---
## Q1 2023 - Index Update
Take a look! The Pipl Search Identity Index has been updated with the following content:
- 68 million new international phone numbers (7.8 million U.S.)
- 70 million new international email addresses
- 145 million updated international career information records, including 21 million new Profiles and 52 million new Jobs
- Improved international name quality
_Jan 11, 2023_
---
## Q2 2023 - Index Update
It's time to unveil our latest index update for Q2 2023. It will include the following content:
- 57 million new phone numbers (1.6 million U.S.)
- 20 million new email addresses (15 million U.S.)
- 111 million updated career information records, including 30 million new records
- NEW! 4.5 million marriage and divorce records in the U.S.
- 76 million U.S. records with updated residential, deceased, and home owner information.
- improved address quality and ordering
_April 14, 2023_
---
## Q3 2023 - Index Update
Summer is here and so is our latest index update for Q3 2023. It will include the following content:
- 54 million new phone numbers (~2.5 million in the U.S.)
- 21 million new email addresses (~14 million in the U.S.)
- 118 million updated career information records, including 40 million new records
- 11 million new vehicle information records
- 97 million U.S. records with updated residential, deceased, and homeowner information
_July 4 2023_
---
## Q3 2023 - New Features and SDK Update
We're bursting with excitement to share some incredible news that's about to level up your Pipl Search API experience! 🚀
Introducing our latest feature release which includes a new vehicle field, a VoIP indicator for phone numbers, an expanded available data section, and new updates to our SDKs.
## New Vehicle Field
[Vehicles](/reference/vehicle) are being added as a new field in the Search API response. Vehicles in the response can include the VIN, make, model, year and type.
**Example Vehicle Object**
```json
{
"@valid_since": "2008-01-01",
"vin": "1ftrx18wx2nb71717",
"year": "2002",
"make": "ford",
"model": "f150",
"type": "pickup",
"display": "1ftrx18wx2nb71717-2002-ford-f150-pickup"
}
```
The new field has a dedicated array in the response and is included in the available data section.
```json
"available_data": {
"premium": {
"relationships": 22,
"usernames": 4,
"jobs": 19,
"addresses": 15,
"phones": 10,
"mobile_phones": 1,
"landline_phones": 9,
"educations": 2,
"languages": 1,
"user_ids": 9,
"social_profiles": 10,
"vehicles": 2, // <----------- Here is the new field count
"names": 2,
"dobs": 1,
"images": 4,
"genders": 1,
"emails": 6,
"work_emails": 4,
"personal_emails": 2
}
```
If you have already been getting vehicles from the tag layer, you can continue using this method.
### Searching by VIN
Search using a VIN number by using the new `vin` query parameter. VIN can be included together with other query parameters or in a full person search.
**Example VIN query**
```
https://api.pipl.com/search/?key=YOUR_KEY&vin=JNKBV61EX7M710824
```
You can also continue using VIN search using the username parameter.
## Expanded Available Data Section
The available data section of a response will now give you increased insight into the types and sub-types of fields in a response. We have added indicators for the following:
- vehicles
- work emails
- personal emails
- voip phones
**Example available data**
```json
"available_data": {
"premium": {
"usernames": 2,
"jobs": 9,
"addresses": 2,
"emails": 3,
"work_emails": 2, // New!
"personal_emails": 1, // New!
"educations": 3,
"user_ids": 3,
"phones": 4,
"mobile_phones": 1,
"voip_phones": 1, // New!
"landline_phones": 2,
"vehicles": 1, // New!
"social_profiles": 2,
"names": 1,
"genders": 1
}
}
```
## VoIP Phones Indicator
Phone numbers that are VoIP (voice-over-IP) will now include an indicator in the metadata using the field `@voip`.
**Example VoIP phone**
```json
{
"country_code": 1,
"number": 9785550145,
"@voip": true,
"display": "(512) 555-0123",
"display_international": "+1 512-555-0123"
}
```
### VoIP Match Requirements
You can add VoIP phones as a match requirement for your API queries. You can combine this with other criteria or use it on its own:
- `match_requirements=phone.voip`
- `match_requirements=phone.voip OR social_profiles`
## SDK/Code Library Updates
The Search API SDKs have been updated. In addition to adding support for new features, we have also updated our software version supports.
### New Features
- Added support for the new `vehicle` field
- Add option to search with VIN
- Add option to search with match requirements of VoIP phones - `match_requirements=phone.voip`
### Updated Software Support
The Search API Code Libraries have been updated to support new software versions:
- Python from 3.7 and above
- Ruby from 3.0 and above
- PHP from 8.0 and above
- DotNet (C#) from v6.0 and above
- Java from 8 and above
_Sept 27, 2023_
---
## Q4 2023 - Index Update
It's a great day to use Pipl! Gearing up for 2024 we've added a lot more data to the Pipl Identity Index.
**Index Update:**
- 220 million updated career information records, including 37 million new records
- 80 million U.S. records with updated residential, deceased, marriage, divorce and homeowner information
- 52 million new phone numbers (~1.5 million in the U.S.)
- 18 million new email addresses (~14 million in the U.S.)
- 11 million new U.S. vehicle information records
---
## Q1 2024 - Index Update
New year, new data! We're excited to release a new index update with a lot of new data:
- 70 Million new phone numbers (~7 million in the U.S.)
- 55 Million new email addresses (~44 million in the U.S.)
- 3 Million new vehicles
- 170 Million New Career information
- 160 Million US records with updated residential, deceased, marriage, divorce, and homeowner information
---
## Q2 2024 - Index Update
We're excited to release a new index update with a lot of new data:
- 110 Million new phone numbers (~4 million in the U.S.)
- 15 Million new email addresses (~6 million in the U.S.)
- 3 Million new vehicles
- 220 Million Updated Career information
- 40 Million US records with updated residential, deceased, marriage, divorce and homeowner information
---
## Q3 2024 - Index Update
We're excited to release a new index update with a lot of new data:
- +81 Million new phone numbers (~4 million in the U.S.)
- +10 Million new email addresses (~3.8 million in the U.S.)
- +1 Million new US vehicles
- +207 Million Updated Career information
- +12 Million US records with updated residential address, deceased, marriage, divorce, and homeowner information
The current stats of the new index are:
- Over 4.5 Billion Unique Phone numbers
- Over 2.1 Billion Unique Email addresses
---
## Q4 2024 - Index Update
We're excited to release a new index update with a lot of new data:
- +150 Million new phone numbers (~4.6 million in the U.S.)
- +16 Million new email addresses (~9 million in the U.S.)
- +3 Million new US vehicles
- +150 Million Updated Career information
- +96 Million US records with updated residential address, deceased, marriage, divorce, and homeowner information
The current stats of the new index are:
- Over 4.7 Billion Unique Phone numbers
- Over 2.2 Billion Unique Email addresses
---
## 2025 - Year-End Data Highlights
In taking a moment to reflect on the incredible strides made in 2025 to strengthen your ability to uncover and trust identity information. This past year, we focused on one goal: giving you most accurate, complete, and current data to help you move faster and make better-informed decisions.
That effort resulted in an incredible year of growth and coverage enhancements to Pipl Search, updates you're already benefiting from today.
2025 Data Enhancements:
- 490 million NEW phone numbers (49 million in the U.S.)
- 141 million NEW email addresses (63 million in the U.S.)
- 110 million NEW career records
- 54 million NEW U.S. vehicle records
- 1.2 million NEW Brazilian CPF records
- 238 million UPDATED career records
- 194 million UPDATED U.S. records (residential, deceased, marriage, divorce, and homeowner data)
Our current global index now includes:
- over 5.3 billion phones, and
- over 2.3 billion emails
---
## Q1 2025 - Index Update
It's a new year, and we're excited to release a new index update with a lot of new data:
- +151 Million new phone numbers (~4 million in the U.S.)
- +98 Million new email addresses (~23 million in the U.S.)
- +98 Million newly added U.S. vehicles
- +264 Million updated career records
- +18 Million U.S. records updated – including residential addresses, deceased status, marriage/divorce data, and homeowner information
Our current index now includes:
- Over 4.9 Billion unique phone numbers
- Over 2.2 Billion unique email addresses
---
## Q2 2025 - Index Update
We're excited to release a new index update with a lot of new data:
- +158 million new phone numbers (~3.5M in the U.S.)
- +40 million new email addresses (~2.6M in the U.S.)
- +30 million newly added U.S. vehicles
- +133 million updated career records
- +95 million refreshed U.S. identity records (including address, deceased status, marital, and homeowner details)
Our current index now includes:
- Over 5 Billion unique phone numbers
- Over 2.2 Billion unique email addresses
---
## Q3 2025 - New Feature Update
We're excited to release a new metadata feature to [phone numbers](/reference/phone).
The @carrier component of a phone will return name of the telecommunications carrier or service provider associated with the phone number. This can be for example a mobile carrier (e.g. "AT&T", "T-Mobile"), a landline provider, or a VoIP service.
---
## H1 2026 - Index Update
Here's a snapshot of what we've achieved in the first half of 2026:
- +166 million new phone numbers (~11.5M in the U.S.)
- +55 million new email addresses (~37M in the U.S.)
- +20 million new and +621 million updated career records
- +21 million U.S. records refreshed (residential address, deceased status, marriage, divorce, and homeowner details)
- +1 million new Brazilian CPFs
Our current index now includes:
- Over 5.4 billion unique phone numbers
- Over 2.4 billion unique email addresses
## New: Pipl Search API via MCP
The Pipl Search API is now available through a Model Context Protocol (MCP) server, enabling AI assistants and agentic applications to access Pipl's identity search capabilities through a standardized integration framework. This makes it easier than ever to bring trusted identity data into AI-powered workflows. See [MCP Server](/docs/mcp-server) to get started.
---
## Q3 2026 - Index Update
As we wrap up Q3, we're excited to share our latest data coverage enhancements, now live across the Pipl index.
This release marks another step in our ongoing effort to provide accurate, comprehensive, and up-to-date identity data globally. Over the past quarter, we've continued to expand our coverage with new data while refreshing hundreds of millions of existing records to keep our results current and relevant.
Here's a snapshot of the latest enhancements:
- +97 million new phone numbers (~3M in the U.S.)
- +62 million new email addresses (~23M in the U.S.)
- +20 million new career records
- +500 million updated career records
- +16 million U.S. records refreshed, including updates to residential addresses, deceased status, marriage, divorce, and homeowner details
- +500K new Brazilian CPFs
With this release, the Pipl index now includes:
- 📱 More than 5.6 billion unique phone numbers globally
- 📧 More than 2.45 billion unique email addresses globally
---
## Using Tags
# What are tags?
[Tags](/reference/tag) hold additional information about a person and their attributes. Examples of tags associated with a given person include:
- Information about a their holdings such as auto models (auto make, VIN)
- Skills and interests
- Domains they own
- Number of Twitter followers / users they follow
Tags returned in the Pipl API response contain data that do not fit into the [person object](/reference/person) model. Tags are classified based on the type of information they contain, and the content may be unstructured free text.
# How to Enable Tags
Tags may appear in individual source objects in the [source array](/reference/source). To see tags in the response, make sure that the sources layer is enabled by using the codeshow_sources/code parameter in the search request (with the relevant value for your use case).
> 📘 NOTE
>
> You can't use tags as input into search queries, or with the **match requirement** field.
# Popular tag classifications
Use the following table to assist you in discovering popular tag classifications.
| **Tag Data** | **Source Name(s)** | **Tag classification(s)** | **Sample value(s)** |
| -------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | ------------------------------------------ | -------------------------------------------------------- |
| Professional credentials and accomplishments | LinkedIn | skill, course, group, volunteering | `Microsoft Office``Python developers unite` |
| Social media follower and following count | Twitter, Instagram, Pinterest, Tiktok, Soundcloud, Github, Vimeo, VK, Foursquare, Academia, Medium, Strava | following, followers | `212``44` |
| Vehicle information | Auto Owner\* | auto year, auto make, auto model, auto vin | `2013``FORD``MONDEO``1ABC21Z39EF90123` |
| Website ownership information | Domain Owner\* | associated domain | `[www.thiscoolwebsite.com](http://www.thiscoolwebsite.com)` |
| Death information | Deceased Residents, FindAGrave | death_date, deceased, burial address | `2003-11-20``yes``Honolulu``Honolulu County``Hawaii``USA` |
| Home ownership information | Residential Property, Trust Property | last_sale_date, apn, type | `2020-05-25``12-07980-00G-009-00-00``estate` |
| NPI (National Provider Identifier) | NPPES NPI Registry | nppes_npi_license | `License Number: MD463765``Registered State: TN``Taxonomy Classification: Allopathic & Osteopathic Physicians``Taxonomy Specialization: Pediatrics` |
| Marriage and divorce data | US Marriage Records, US Divorce Records | marriage_date, divorce_date | `2019-03` |
> 📘 NOTE
>
> \* For certain sources, the source name may not be exactly as specified in the table above, but may be similarly named. Check that the string contains the content, and do a case insensitive comparison.
# Example
This example illustrates how tags may appear in a source object in the sources array. This includes different classifications of tags such as codeskill/code, codegroup/code and codeauto make/code.
```json
"sources": [
{
"@id": "4275e03c9c99953245c426dd74cd61c5",
"@category": "professional_and_business",
"@name": "LinkedIn",
"@origin_url": "http://www.linkedin.com/in/theman",
"@domain": "linkedin.com",
"@person_id": "a0f13c3c-bcd9-4133-979c-9f2ba05decf8",
"@match": 1.0,
"names": [...
],
"usernames": [...
],
"tags": [
{
"@valid_since": "2015-09-01",
"@last_seen": "2016-08-26",
"@classification": "skill",
"content": "Microsoft Office"
},
{
"@valid_since": "2015-09-01",
"@last_seen": "2016-08-26",
"@classification": "skill",
"content": "Python"
},
{
"@valid_since": "2015-09-01",
"@last_seen": "2016-08-26",
"@classification": "group",
"content": "Python developers unite"
},
{
"@valid_since": "2016-01-22",
"@last_seen": "2016-08-26",
"@classification": "volunteering",
"content": "Chef at Home for the Homeless"
},
{
"@valid_since": "2016-07-22",
"@last_seen": "2016-08-26",
"@classification": "course",
"content": "Python for pros"
},
{
"@valid_since": "2017-06-01",
"@last_seen": "2017-06-01",
"@classification": "auto make",
"content": "FORD"
},
{
"@valid_since": "2017-06-01",
"@last_seen": "2017-06-01",
"@classification": "auto model",
"content": "MONDEO"
},
{
"@valid_since": "2017-06-01",
"@last_seen": "2017-06-01",
"@classification": "auto vin",
"content": "1ABC21Z39EF90123"
},
{
"@valid_since": "2018-04-15",
"@classification": "marriage_date",
"content": "2018-04"
}
{
"@valid_since": "2015-02-05",
"@classification": "home_owner_lives_in_property",
"content": "True"
},
{
"@valid_since": "2015-02-05",
"@classification": "last_sale_date",
"content": "2015-02-05"
},
{
"@valid_since": "2015-02-05",
"@classification": "apn",
"content": "0500667"
}
]
```
---
## Advanced Search Queries
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Below are some examples for running some more advanced queries
### Multiple Phones, emails or Addresses
Using multiple instances of a particular data field in a search query requires using a [full person search](/reference/full-person)
```text
person=
{
"names": [
{
"first": "Clark",
"last": "Kent"
}
],
"addresses": [
{
"city": "Metropolis",
"state": "IL",
"country": "US"
},
{
"city": "Wichita",
"state": "KS",
"country": "US"
}
],
"emails": [
{
"address": "clark.kent@example.com"
},
{
"address": "ckent@hotmail.com"
}
],
"phones": [
{
"raw": "+1(312) 684-5000"
},
{
"raw": "(312) 352-9327"
}
]
}
```
```http
https://api.pipl.com/search/?key=YOUR_KEY&show_sources=matching&person={ "names": [ { "first": "Clark", "last": "Kent" } ], "addresses": [ { "city": "Chicago", "state": "IL", "country": "US" }, { "city": "Wichita", "state": "KS", "country": "US" } ], "emails": [ { "address": "clark.kent@example.com" }, { "address": "ckent@hotmail.com" } ], "phones": [ { "raw": "+1(312) 684-5000" }, { "raw": "(312) 352-9327" } ] }
```
```python
from piplapis.data import Person, Name, Address, Email, Phone
from piplapis.search import SearchAPIRequest
fields = [
Name(first=u'Clark', last=u'Kent'),
Address(city=u'Chicago', state=u'IL', country=u'US'),
Address(city=u'Wichita', state=u'KS', country=u'US'),
Email(address=u'clark.kent@example.com'),
Email(address=u'ckent@hotmail.com'),
Phone(raw=u'+1(312) 684-5000'),
Phone(raw=u'(312) 352-9327')
]
request = SearchAPIRequest(person=Person(fields=fields), api_key='YOUR_KEY', show_sources='matching')
response = request.send()
```
```ruby
require 'pipl'
person = Pipl::Person.new
person.add_field Pipl::Name.new(first: 'Clark', last: 'Kent')
person.add_field Pipl::Address.new(city: 'Chicago', state: 'IL', country: 'US')
person.add_field Pipl::Address.new(city: 'Wichita', state: 'KS', country: 'US')
person.add_field Pipl::Email.new(address: 'clark.kent@example.com')
person.add_field Pipl::Email.new(address: 'ckent@hotmail.com')
person.add_field Pipl::Phone.new(raw: '+1(312) 684-5000')
person.add_field Pipl::Phone.new(raw: '(312) 352-9327')
response = Pipl::client.search person: person, api_key: 'YOUR_KEY', show_sources: 'matching'
```
```java
import java.util.ArrayList;
import java.util.List;
import com.pipl.api.search.SearchAPIRequest;
import com.pipl.api.data.containers.Person;
import com.pipl.api.data.fields.*;
import com.pipl.api.search.SearchConfiguration;
SearchConfiguration configuration = new SearchConfiguration();
configuration.setProtocol("https");
configuration.apiKey = "YOUR_KEY";
configuration.showSources = "matching";
List fields = new ArrayList();
fields.add(new Name.Builder().first("Clark").last("Kent").build());
fields.add(new Address.Builder().city("Chicago").state("IL").country("US").build());
fields.add(new Address.Builder().city("Wichita").state("KS").country("US").build());
fields.add(new Email.Builder().address("clark.kent@example.com").build());
fields.add(new Email.Builder().address("ckent@hotmail.com").build());
fields.add(new Phone.Builder().raw("+1(312) 684-5000").build());
fields.add(new Phone.Builder().raw("(312) 352-9327").build());
Person person = new Person(fields);
SearchAPIRequest request = new SearchAPIRequest(person, configuration);
SearchAPIResponse response = request.send();
```
```php
use_https = true;
$configuration->api_key = 'YOUR_KEY';
$configuration->show_sources = 'matching';
$fields = array(
new PiplApi_Name(array("first" => "Clark", "last" => "Kent")),
new PiplApi_Address(array("city" => "Chicago", "state" => "IL", "country" => "US")),
new PiplApi_Address(array("city" => "Wichita", "state" => "KS", "country" => "US")),
new PiplApi_Email(array("address" => "clark.kent@example.com")),
new PiplApi_Email(array("address" => "ckent@hotmail.com")),
new PiplApi_Phone(array("raw" => "+1(312) 684-5000")),
new PiplApi_Phone(array("raw" => "(312) 352-9327"))
);
$person = new PiplApi_Person($fields);
$request = new PiplApi_SearchAPIRequest(array('person' => $person), $configuration);
$response = $request->send();
?>
```
```csharp
using Pipl.APIs.Search;
using System.Collections.Generic;
SearchConfiguration searchConfiguration = new SearchConfiguration(
apiKey: "YOUR_KEY",
url: "api.pipl.com/search/",
useHttps: true
);
searchConfiguration.ShowSources = "matching";
List fields = new List()
{
new Name(first: "Clark", last: "Kent"),
new Address(city: "Chicago", state: "IL", country: "US"),
new Address(city: "Wichita", state: "KS", country: "US"),
new Email(address: "clark.kent@example.com"),
new Email(address: "ckent@hotmail.com"),
new Phone(raw: "+1(312) 684-5000"),
new Phone(raw: "(312) 352-9327")
};
var person = new Person(fields);
SearchAPIRequest request = new SearchAPIRequest(
person: person,
requestConfiguration: searchConfiguration
);
var response = await request.SendAsync();
```
### Social Profiles (Facebook, LinkedIn and others)
You can search Pipl by social services by the username, userID or even a profile URL. For the complete list of supported services, such as GitHub, Tiktok and others, please see [the list of supported services](/reference/user-id#list-of-supported-services) .
```text
username=clark.kent@twitter
OR
userid=1234567@facebook
OR
url = https://linkedIn.com/in/ClarkKent
```
```http
https://api.pipl.com/search/?key=YOUR_KEY&show_sources=matching&username=clark.kent@linkedin
```
```python
from piplapis.search import SearchAPIRequest
# Using username
request = SearchAPIRequest(username=u'clark.kent@linkedin', api_key='YOUR_KEY', show_sources='matching')
response = request.send()
# Using userid
request = SearchAPIRequest(userid=u'1234567@facebook', api_key='YOUR_KEY', show_sources='matching')
response = request.send()
# Using url
request = SearchAPIRequest(url=u'https://linkedin.com/in/ClarkKent', api_key='YOUR_KEY', show_sources='matching')
response = request.send()
```
```ruby
require 'pipl'
# Using username
response = Pipl::client.search username: 'clark.kent@linkedin', api_key: 'YOUR_KEY', show_sources: 'matching'
# Using userid
response = Pipl::client.search userid: '1234567@facebook', api_key: 'YOUR_KEY', show_sources: 'matching'
# Using url
response = Pipl::client.search url: 'https://linkedin.com/in/ClarkKent', api_key: 'YOUR_KEY', show_sources: 'matching'
```
```java
import com.pipl.api.search.SearchAPIRequest;
import com.pipl.api.search.SearchAPIResponse;
import com.pipl.api.search.SearchConfiguration;
SearchConfiguration configuration = new SearchConfiguration();
configuration.setProtocol("https");
configuration.apiKey = "YOUR_KEY";
configuration.showSources = "matching";
// Using username
SearchAPIRequest request = new SearchAPIRequest.Builder()
.username("clark.kent@linkedin")
.configuration(configuration)
.build();
SearchAPIResponse response = request.send();
// Using userid
request = new SearchAPIRequest.Builder()
.userid("1234567@facebook")
.configuration(configuration)
.build();
response = request.send();
// Using url
request = new SearchAPIRequest.Builder()
.url("https://linkedin.com/in/ClarkKent")
.configuration(configuration)
.build();
response = request.send();
```
```php
use_https = true;
$configuration->api_key = 'YOUR_KEY';
$configuration->show_sources = 'matching';
// Using username
$request = new PiplApi_SearchAPIRequest(
array('username' => 'clark.kent@linkedin'),
$configuration
);
$response = $request->send();
// Using userid
$request = new PiplApi_SearchAPIRequest(
array('userid' => '1234567@facebook'),
$configuration
);
$response = $request->send();
// Using url
$request = new PiplApi_SearchAPIRequest(
array('url' => 'https://linkedin.com/in/ClarkKent'),
$configuration
);
$response = $request->send();
?>
```
```csharp
using Pipl.APIs.Search;
SearchConfiguration searchConfiguration = new SearchConfiguration(
apiKey: "YOUR_KEY",
url: "api.pipl.com/search/",
useHttps: true
);
searchConfiguration.ShowSources = "matching";
// Using username
SearchAPIRequest request = new SearchAPIRequest(
username: "clark.kent@linkedin",
requestConfiguration: searchConfiguration
);
var response = await request.SendAsync();
// Using userid
request = new SearchAPIRequest(
userid: "1234567@facebook",
requestConfiguration: searchConfiguration
);
response = await request.SendAsync();
// Using url
request = new SearchAPIRequest(
url: "https://linkedin.com/in/ClarkKent",
requestConfiguration: searchConfiguration
);
response = await request.SendAsync();
```
### US VIN (Vehicle Identification Number)
You can use 'vin' query parameter to run a search using a vehicle's VIN.
You can also use the codeusername/code parameter to search by a vehicle VIN using the format code########@vin/code
```text
vin=JNKBV61EX7M710824
username=JNKBV61EX7M710824@vin
```
```http
https://api.pipl.com/search/?key=YOUR_KEY&show_sources=matching&vin=JNKBV61EX7M710824
https://api.pipl.com/search/?key=YOUR_KEY&show_sources=matching&username=JNKBV61EX7M710824@vin
```
```python
from piplapis.search import SearchAPIRequest
# Using vin parameter
request = SearchAPIRequest(vin=u'JNKBV61EX7M710824', api_key='YOUR_KEY', show_sources='matching')
response = request.send()
# Using username with @vin format
request = SearchAPIRequest(username=u'JNKBV61EX7M710824@vin', api_key='YOUR_KEY', show_sources='matching')
response = request.send()
```
```ruby
require 'pipl'
# Using vin parameter
response = Pipl::client.search vin: 'JNKBV61EX7M710824', api_key: 'YOUR_KEY', show_sources: 'matching'
# Using username with @vin format
response = Pipl::client.search username: 'JNKBV61EX7M710824@vin', api_key: 'YOUR_KEY', show_sources: 'matching'
```
```java
import com.pipl.api.search.SearchAPIRequest;
import com.pipl.api.search.SearchAPIResponse;
import com.pipl.api.search.SearchConfiguration;
SearchConfiguration configuration = new SearchConfiguration();
configuration.setProtocol("https");
configuration.apiKey = "YOUR_KEY";
configuration.showSources = "matching";
// Using vin parameter
SearchAPIRequest request = new SearchAPIRequest.Builder()
.vin("JNKBV61EX7M710824")
.configuration(configuration)
.build();
SearchAPIResponse response = request.send();
// Using username with @vin format
request = new SearchAPIRequest.Builder()
.username("JNKBV61EX7M710824@vin")
.configuration(configuration)
.build();
response = request.send();
```
```php
use_https = true;
$configuration->api_key = 'YOUR_KEY';
$configuration->show_sources = 'matching';
// Using vin parameter
$request = new PiplApi_SearchAPIRequest(
array('vin' => 'JNKBV61EX7M710824'),
$configuration
);
$response = $request->send();
// Using username with @vin format
$request = new PiplApi_SearchAPIRequest(
array('username' => 'JNKBV61EX7M710824@vin'),
$configuration
);
$response = $request->send();
?>
```
```csharp
using Pipl.APIs.Search;
SearchConfiguration searchConfiguration = new SearchConfiguration(
apiKey: "YOUR_KEY",
url: "api.pipl.com/search/",
useHttps: true
);
searchConfiguration.ShowSources = "matching";
// Using vin parameter
SearchAPIRequest request = new SearchAPIRequest(
vin: "JNKBV61EX7M710824",
requestConfiguration: searchConfiguration
);
var response = await request.SendAsync();
// Using username with @vin format
request = new SearchAPIRequest(
username: "JNKBV61EX7M710824@vin",
requestConfiguration: searchConfiguration
);
response = await request.SendAsync();
```
### CPF (Brazilian Identification number)
The codeusername/code parameter is used to search by a CPF using the following format "###########@cpf"
```text
username=12345678901@cpf
```
```http
https://api.pipl.com/search/?key=YOUR_KEY&show_sources=matching&username=12345678901@cpf
```
```python
from piplapis.search import SearchAPIRequest
request = SearchAPIRequest(username=u'12345678901@cpf', api_key='YOUR_KEY', show_sources='matching')
response = request.send()
```
```ruby
require 'pipl'
response = Pipl::client.search username: '12345678901@cpf', api_key: 'YOUR_KEY', show_sources: 'matching'
```
```java
import com.pipl.api.search.SearchAPIRequest;
import com.pipl.api.search.SearchAPIResponse;
import com.pipl.api.search.SearchConfiguration;
SearchConfiguration configuration = new SearchConfiguration();
configuration.setProtocol("https");
configuration.apiKey = "YOUR_KEY";
configuration.showSources = "matching";
SearchAPIRequest request = new SearchAPIRequest.Builder()
.username("12345678901@cpf")
.configuration(configuration)
.build();
SearchAPIResponse response = request.send();
```
```php
use_https = true;
$configuration->api_key = 'YOUR_KEY';
$configuration->show_sources = 'matching';
$request = new PiplApi_SearchAPIRequest(
array('username' => '12345678901@cpf'),
$configuration
);
$response = $request->send();
?>
```
```csharp
using Pipl.APIs.Search;
SearchConfiguration searchConfiguration = new SearchConfiguration(
apiKey: "YOUR_KEY",
url: "api.pipl.com/search/",
useHttps: true
);
searchConfiguration.ShowSources = "matching";
SearchAPIRequest request = new SearchAPIRequest(
username: "12345678901@cpf",
requestConfiguration: searchConfiguration
);
var response = await request.SendAsync();
```
### NPI (US National Provider identifier - medical professionals)
The username parameter is used to search by an NPI using the following format "##########@npi"
```text
username=1234567890@npi
```
```http
https://api.pipl.com/search/?key=YOUR_KEY&show_sources=matching&username=1234567890@npi
```
```python
from piplapis.search import SearchAPIRequest
request = SearchAPIRequest(username=u'1234567890@npi', api_key='YOUR_KEY', show_sources='matching')
response = request.send()
```
```ruby
require 'pipl'
response = Pipl::client.search username: '1234567890@npi', api_key: 'YOUR_KEY', show_sources: 'matching'
```
```java
import com.pipl.api.search.SearchAPIRequest;
import com.pipl.api.search.SearchAPIResponse;
import com.pipl.api.search.SearchConfiguration;
SearchConfiguration configuration = new SearchConfiguration();
configuration.setProtocol("https");
configuration.apiKey = "YOUR_KEY";
configuration.showSources = "matching";
SearchAPIRequest request = new SearchAPIRequest.Builder()
.username("1234567890@npi")
.configuration(configuration)
.build();
SearchAPIResponse response = request.send();
```
```php
use_https = true;
$configuration->api_key = 'YOUR_KEY';
$configuration->show_sources = 'matching';
$request = new PiplApi_SearchAPIRequest(
array('username' => '1234567890@npi'),
$configuration
);
$response = $request->send();
?>
```
```csharp
using Pipl.APIs.Search;
SearchConfiguration searchConfiguration = new SearchConfiguration(
apiKey: "YOUR_KEY",
url: "api.pipl.com/search/",
useHttps: true
);
searchConfiguration.ShowSources = "matching";
SearchAPIRequest request = new SearchAPIRequest(
username: "1234567890@npi",
requestConfiguration: searchConfiguration
);
var response = await request.SendAsync();
```
### Job/Education
Searching by job or education in a search query requires using a [full person search](/reference/full-person)
```text
person=
{
"names": [{
"raw": "Clark Kent" }],
"educations": [ {"school": "Metropolis University"} ],
"jobs": [{"organization": "The Daily Planet"},
{"title": "Field Reporter"}]
}
```
```http
https://api.pipl.com/search/?key=YOUR_KEY&show_sources=matching&person={ "names": [{ "raw": "Clark Kent" }], "educations": [ {"school": "University of Chicago"} ], "jobs": [{"organization": "The Wallstreet Journal"}, {"title": "Field Reporter"}] }
```
```python
from piplapis.data import Person, Name, Education, Job
from piplapis.search import SearchAPIRequest
fields = [
Name(raw=u'Clark Kent'),
Education(school=u'Metropolis University'),
Job(organization=u'The Daily Planet'),
Job(title=u'Field Reporter')
]
request = SearchAPIRequest(person=Person(fields=fields), api_key='YOUR_KEY', show_sources='matching')
response = request.send()
```
```ruby
require 'pipl'
person = Pipl::Person.new
person.add_field Pipl::Name.new(raw: 'Clark Kent')
person.add_field Pipl::Education.new(school: 'Metropolis University')
person.add_field Pipl::Job.new(organization: 'The Daily Planet')
person.add_field Pipl::Job.new(title: 'Field Reporter')
response = Pipl::client.search person: person, api_key: 'YOUR_KEY', show_sources: 'matching'
```
```java
import java.util.ArrayList;
import java.util.List;
import com.pipl.api.search.SearchAPIRequest;
import com.pipl.api.data.containers.Person;
import com.pipl.api.data.fields.*;
import com.pipl.api.search.SearchConfiguration;
SearchConfiguration configuration = new SearchConfiguration();
configuration.setProtocol("https");
configuration.apiKey = "YOUR_KEY";
configuration.showSources = "matching";
List fields = new ArrayList();
fields.add(new Name.Builder().raw("Clark Kent").build());
fields.add(new Education.Builder().school("Metropolis University").build());
fields.add(new Job.Builder().organization("The Daily Planet").build());
fields.add(new Job.Builder().title("Field Reporter").build());
Person person = new Person(fields);
SearchAPIRequest request = new SearchAPIRequest(person, configuration);
SearchAPIResponse response = request.send();
```
```php
use_https = true;
$configuration->api_key = 'YOUR_KEY';
$configuration->show_sources = 'matching';
$fields = array(
new PiplApi_Name(array("raw" => "Clark Kent")),
new PiplApi_Education(array("school" => "Metropolis University")),
new PiplApi_Job(array("organization" => "The Daily Planet")),
new PiplApi_Job(array("title" => "Field Reporter"))
);
$person = new PiplApi_Person($fields);
$request = new PiplApi_SearchAPIRequest(array('person' => $person), $configuration);
$response = $request->send();
?>
```
```csharp
using Pipl.APIs.Search;
using System.Collections.Generic;
SearchConfiguration searchConfiguration = new SearchConfiguration(
apiKey: "YOUR_KEY",
url: "api.pipl.com/search/",
useHttps: true
);
searchConfiguration.ShowSources = "matching";
List fields = new List()
{
new Name(raw: "Clark Kent"),
new Education(school: "Metropolis University"),
new Job(organization: "The Daily Planet"),
new Job(title: "Field Reporter")
};
var person = new Person(fields);
SearchAPIRequest request = new SearchAPIRequest(
person: person,
requestConfiguration: searchConfiguration
);
var response = await request.SendAsync();
```
### Relationship
You can search for a person that has a connection to another. Note that in the relationship object only the name part will be used in the search.
```text
person=
{
"names": [
{
"first": "Clark",
"last": "Kent"
}
],
"relationships": [
{
"names": [
{
"first": "Lois",
"last": "Lane"
}
]
}
]
}
```
```http
https://api.pipl.com/search/?key=YOUR_KEY&show_sources=matching&person= { "names": [ { "first": "Clark", "last": "Kent" } ], "relationships": [ { "names": [ { "first": "Sam", "last": "Smith" } ] } ] }
```
```python
from piplapis.data import Person, Name, Relationship
from piplapis.search import SearchAPIRequest
fields = [
Name(first=u'Clark', last=u'Kent'),
Relationship(names=[Name(first=u'Lois', last=u'Lane')])
]
request = SearchAPIRequest(person=Person(fields=fields), api_key='YOUR_KEY', show_sources='matching')
response = request.send()
```
```ruby
require 'pipl'
person = Pipl::Person.new
person.add_field Pipl::Name.new(first: 'Clark', last: 'Kent')
relationship = Pipl::Relationship.new
relationship.add_field Pipl::Name.new(first: 'Lois', last: 'Lane')
person.add_field relationship
response = Pipl::client.search person: person, api_key: 'YOUR_KEY', show_sources: 'matching'
```
```java
import java.util.ArrayList;
import java.util.List;
import com.pipl.api.search.SearchAPIRequest;
import com.pipl.api.data.containers.Person;
import com.pipl.api.data.fields.*;
import com.pipl.api.search.SearchConfiguration;
SearchConfiguration configuration = new SearchConfiguration();
configuration.setProtocol("https");
configuration.apiKey = "YOUR_KEY";
configuration.showSources = "matching";
List fields = new ArrayList();
fields.add(new Name.Builder().first("Clark").last("Kent").build());
List relationshipFields = new ArrayList();
relationshipFields.add(new Name.Builder().first("Lois").last("Lane").build());
fields.add(new Relationship(relationshipFields));
Person person = new Person(fields);
SearchAPIRequest request = new SearchAPIRequest(person, configuration);
SearchAPIResponse response = request.send();
```
```php
use_https = true;
$configuration->api_key = 'YOUR_KEY';
$configuration->show_sources = 'matching';
$fields = array(
new PiplApi_Name(array("first" => "Clark", "last" => "Kent")),
new PiplApi_Relationship(array(
"names" => array(
new PiplApi_Name(array("first" => "Lois", "last" => "Lane"))
)
))
);
$person = new PiplApi_Person($fields);
$request = new PiplApi_SearchAPIRequest(array('person' => $person), $configuration);
$response = $request->send();
?>
```
```csharp
using Pipl.APIs.Search;
using System.Collections.Generic;
SearchConfiguration searchConfiguration = new SearchConfiguration(
apiKey: "YOUR_KEY",
url: "api.pipl.com/search/",
useHttps: true
);
searchConfiguration.ShowSources = "matching";
List fields = new List()
{
new Name(first: "Clark", last: "Kent"),
new Relationship(names: new List() { new Name(first: "Lois", last: "Lane") })
};
var person = new Person(fields);
SearchAPIRequest request = new SearchAPIRequest(
person: person,
requestConfiguration: searchConfiguration
);
var response = await request.SendAsync();
```
### Email in MD5 format
You can search for an MD5 as follows. Please be sure to normalize your email address following [the MD5 Calculation guidelines](/reference/email#md5-calculation-guidelines) before applying the MD5 hash.
```text
person=
{
"emails": [
{
"address_md5": "b095275aa233df8e857dbca662512ca4"
}
]
}
```
```http
https://api.pipl.com/search/?key=YOUR_KEY&show_sources=matching&person= { "emails": [ { "address_md5": "b095275aa233df8e857dbca662512ca4" } ] }
```
```python
from piplapis.data import Person, Email
from piplapis.search import SearchAPIRequest
fields = [
Email(address_md5=u'b095275aa233df8e857dbca662512ca4')
]
request = SearchAPIRequest(person=Person(fields=fields), api_key='YOUR_KEY', show_sources='matching')
response = request.send()
```
```ruby
require 'pipl'
person = Pipl::Person.new
person.add_field Pipl::Email.new(address_md5: 'b095275aa233df8e857dbca662512ca4')
response = Pipl::client.search person: person, api_key: 'YOUR_KEY', show_sources: 'matching'
```
```java
import java.util.ArrayList;
import java.util.List;
import com.pipl.api.search.SearchAPIRequest;
import com.pipl.api.data.containers.Person;
import com.pipl.api.data.fields.*;
import com.pipl.api.search.SearchConfiguration;
SearchConfiguration configuration = new SearchConfiguration();
configuration.setProtocol("https");
configuration.apiKey = "YOUR_KEY";
configuration.showSources = "matching";
List fields = new ArrayList();
fields.add(new Email.Builder().addressMd5("b095275aa233df8e857dbca662512ca4").build());
Person person = new Person(fields);
SearchAPIRequest request = new SearchAPIRequest(person, configuration);
SearchAPIResponse response = request.send();
```
```php
use_https = true;
$configuration->api_key = 'YOUR_KEY';
$configuration->show_sources = 'matching';
$fields = array(
new PiplApi_Email(array("address_md5" => "b095275aa233df8e857dbca662512ca4"))
);
$person = new PiplApi_Person($fields);
$request = new PiplApi_SearchAPIRequest(array('person' => $person), $configuration);
$response = $request->send();
?>
```
```csharp
using Pipl.APIs.Search;
using System.Collections.Generic;
SearchConfiguration searchConfiguration = new SearchConfiguration(
apiKey: "YOUR_KEY",
url: "api.pipl.com/search/",
useHttps: true
);
searchConfiguration.ShowSources = "matching";
List fields = new List()
{
new Email(addressMd5: "b095275aa233df8e857dbca662512ca4")
};
var person = new Person(fields);
SearchAPIRequest request = new SearchAPIRequest(
person: person,
requestConfiguration: searchConfiguration
);
var response = await request.SendAsync();
```
---
## Pipl Thumbnails API
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
# Pipl Thumbnails API
As an API subscriber, you also enjoy complimentary access to our Thumbnail API. The Thumbnail API saves you the hassle of dealing with profile pictures by providing built-in features for:
- Cropping images to the right dimensions
- Zooming in on faces with advanced face detection
- Attributing sources by adding favicons to images
- Image redundancy—specify a fallback image

## How does it work?
Each image field in our API responses includes a special token that can be sent to our thumbnail servers. You can specify the exact parameters depending on your needs.
```json
{
"url": "http://vignette3.wikia.nocookie.net/smallville/images/5/55/S10E18-Booster21.jpg",
"thumbnail_token": "AE2861B242686E7BD0CB4D9049298EB7D18FEF66D950E8AB78BCD3F484345CE74536C19A85D0BA3D32DC9E7D1878CD4D341254E7AD129255C6983E6E154C4530A0DAAF665EA325FC0206F8B1D7E0B6B7AD9EBF71FCF610D57D"
}
```
## Creating a thumbnail URL
The base URL of our thumbnail server is: _[https://thumb.pipl.com/image](https://thumb.pipl.com/image)_. An example of a complete url would be:
```
http://thumb.pipl.com/image?height=250&width=250&favicon=true&zoom_face=true&tokens=AE2861B242686E7BD0CB4D9049298EB7D18FEF66D950E8AB78BCD3F484345CE74536C19A85D0BA3D32DC9E7D1878CD4D341254E7AD129255C6983E6E154C4530A0DAAF665EA325FC0206F8B1D7E0B6B7AD9EBF71FCF610D57D
```
## A redundant thumbnail URL
Sometimes, images will no longer be available on the web. To help you create robust thumbnail URLs, our thumbnail API allows specifying a fallback token.
To use this option, send two tokens to the API separated by a comma, like this:
```
http://thumb.pipl.com/image?height=250&width=250&favicon=true&zoom_face=true&tokens=FIRST_TOKEN,SECOND_TOKEN
```
## Allowed parameters:
| **Parameter** | **Description** |
| -------------- | ---------------- |
| **tokens** _required_ | Required. One or two thumbnail tokens, separated by a comma. If the image referenced by the first thumbnail token is no longer available on the web, the second token will be used. |
| **height** _required_ | Height in pixels. Integer between 100-500. |
| **width** _required_ | Width in pixels. Integer between 100-500. |
| **favicon** | Boolean. Whether to show favicon. |
| **zoom_face** | Boolean. Whether to enable face zoom. |
## Using the client libraries
If you use our client libraries, we’ll handle all of the boilerplate for you.
```python
# Creating a thumbnail URL
thumbnail_url = image.get_thumbnail_url(200, 100, zoom_face=True, favicon=True)
# Creating a redundant image URL
redundant_url = Image.generate_redundant_thumbnail_url(first_image, fallback_image, 100, 100)
```
```ruby
# Creating a thumbnail URL
thumbnail_url = image.thumbnail_url width: 200, height: 100, favicon: true, zoom_face: true
# Creating a redundant image URL
image = Pipl::Image.new(thumbnail_token: 'TOKEN')
fallback = Pipl::Image.new(thumbnail_token: 'FALLBACK_TOKEN')
url = image.thumbnail_url width: 200, height: 100, favicon: true, zoom_face: true, fallback: fallback
```
```java
# Creating a thumbnail URL
String thumbUrl = image.getThumbnailUrl(200, 100, true, true, false);
# Creating a redundant image URL
String url = Image.generateRedundantThumbnailUrl(250, 250, true, true, false, resp.person.images.get(0), resp.person.images.get(1));
```
```php
# Creating a thumbnail URL
$thumbUrl = $image->get_thumbnail_url(200, 100, true, true);
# Creating a redundant image URL
$thumbUrl = PiplApi_Image::generate_redundant_thumbnail_url($first_image, $second_image, 100, 100);
```
```csharp
# Creating a thumbnail image URL
var thumbUrl = _image.GetThumbnailUrl(200, 100, true, true);
# Creating a redundant image URL
var thumbnail_url = Pipl.APIs.Data.Fields.Image.GenerateRedundantThumbnailUrl(image1, image2, 200, 100, true,true,true);
```
## Special cases
In some cases, both of your tokens will reference an image no longer available online, or they might contain a default placeholder image and not a real image of the person.
In those cases, the thumbnail server will return 404.
---
## Working with Images
## Introduction
Images are available with the SOCIAL key and up. You can display an image in your application by using the images in the API response. Simply utilize the free to use Pipl thumbnail API with the thumbnail token returned with the image.
This tutorial is to help you to determine the source of an image from the Pipl API response, and address the case when an image is no longer accessible.
## Where is the image from?
Some of Pipl Search users wish to only display images that originated from certain data sources. For example, they may want to display a professional Linkedin image over a personal Twitter image in their applications.
The list of images returned from Pipl's API is vendor neutral. If you activate the sources layer with `show_sources=matching` (see configuration parameters), you will be able to see source attribution for data fields in a person's profile. For each image returned for a person, there is a corresponding source in the sources array, indicating the origin with the `@name` metadata tag (e.g. LinkedIn, Twitter, etc). By searching for the URL of the image in each source, you will be able to cross reference the origin of the image.
For example, let's search for the email address: [email protected]. This is our query:
`https://api.pipl.com/search/?email=[email protected]&key=YOURKEY&show_sources=matching`
Note that we appended `show_sources=matching` which shows only sources that were used to build the Person profile.
## Working with the response
There are three important sections to note from the JSON response in order to determine the source of each image:
- available data
- images array
- sources array
Below is an example from a Person response, showing only the information relevant to images.
```json
{
"@http_status_code": 200,
...
"available_data": {
"premium": {
"images": 2,
}
},
"person": {
...
"images": [
],
...
},
"sources": [
{
,
"@name": "xxx",
"images": [
{
"url": "",
"thumbnail_token": ""
}
],
},
...
{...}
]
}
```
From the `available_data` we determine the number of images returned in the response:
```json
"available_data": {
"premium": {
"relationships": 6,
...
"names": 2,
"dobs": 1,
"images": 2,
"genders": 1,
"emails": 4,
"origin_countries": 1
}
},
```
From the images array in each person object, we can see the source URL for each image, and the `thumbnail_token` that can be used with Pipl's thumbnail API.
```json
"images": [
{
"url": "http://vignette1.wikia.nocookie.net/smallville/images/e/ea/Buddies_forever.jpg",
"thumbnail_token": "AE2861B242686E7BD0CB4D9049298EB7D18FEF66D950E8AB78BCD3F484345CE74536C19A85D0BA3D32DC9E7D1878CD4D341254E7AD129255C6983E6E154C4530A0DAAF665EA325FC0206F8B1D7E0B6B7AD9EBF71FCF610D57D"
},
{
"url": "http://vignette3.wikia.nocookie.net/smallville/images/5/55/S10E18-Booster21.jpg",
"thumbnail_token": "AE2861B242686E7BD0CB4D9049298EB5D18FEF66D950E8AB78BCD3F484345CE74536C19A85D0BA3D32DC9E7D1878CD4D341254E7AD12C25596CC3E7F51186468FD84B26F5EA234EF1546E7F5CDF7F7F5BA84B228F4F013DD7281"
}
],
```
In the sources array we can see the origin of each image. To determine the origin of an image, search through the source array for a source that includes the URL of the image in the 'images' field. In the example below, we can determine the image is from the Facebook data source (please note that images from Facebook are no longer publicly available, and the below example is for illustrative purposes only).
```json
"sources": [
...
{
"@id": "5d836a4acc55922e49fc709c7a39e233",
"@category": "personal_profiles",
"@name": "Facebook",
"@origin_url": "http://facebook.com/superman",
"@domain": "facebook.com",
"@person_id": "cdb74980-718a-4277-82bf-cdd2b30781c8",
"@match": 1.0,
...
"images": [
{
"url": "http://vignette1.wikia.nocookie.net/smallville/images/e/ea/Buddies_forever.jpg",
"thumbnail_token": "AE2861B242686E7BD0CB4D9049298EB7D18FEF66D950E8AB78BCD3F484345CE74536C19A85D0BA3D32DC9E7D1878CD4D341254E7AD129255C6983E6E154C4530A0DAAF665EA325FC0206F8B1D7E0B6B7AD9EBF71FCF610D57D"
},
{
"url": "http://vignette3.wikia.nocookie.net/smallville/images/5/55/S10E18-Booster21.jpg",
"thumbnail_token": "AE2861B242686E7BD0CB4D9049298EB5D18FEF66D950E8AB78BCD3F484345CE74536C19A85D0BA3D32DC9E7D1878CD4D341254E7AD12C25596CC3E7F51186468FD84B26F5EA234EF1546E7F5CDF7F7F5BA84B228F4F013DD7281"
}
],
...
},
...
]
```
When working with possible person responses, you will need to use `show_sources=all` in order to see the source layer for possible persons. Besides this change, the same approach is used as with a person response.
## Dealing with images that are no longer accessible
Pipl aims to return only URLs to images that are active, however, sometimes due to issues with the image source, the image may no longer be accessible or even exist. These issues may include one or more of the following:
* A profile may have been public at a certain stage, however a user changed their privacy settings, so the public profile image is no longer available
* A person may have removed the image from their profile or closed down their profile
* The website may have removed the image
* The social network or URL no longer exists, the entire website is down or the profile was taken down
* The social network no longer serves images as public, and requires a special access token to access the image
* A website may have changed the way they internally reference images, and the image URL Pipl has a record of becomes invalidated
If the image is no longer accessible when directly using the image URL to retrieve the image, you could get a 403, 404 or 400 HTTP status error response.
The Pipl thumbnail API allows you to select a fallback API token that is used if the first token is not available. If none of the tokens provided to the Pipl thumbnail API are accessible, then a 404 HTTP status code will be returned, and a default Pipl avatar image will be returned.
It is recommended to retrieve the HEAD of the image in your server side application to check if the image is available before displaying this to the user.
To improve your application's user experience, you may choose to replace Pipl's thumbnail default avatar with one of your own.
---
## Don't log my query data
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
# Do not log API queries with Pipl
## What is the no_log feature?
By using the no_log parameter in your Pipl API queries, no input query information will be stored by Pipl servers. Query data will only be used to perform a search, and a record of the transaction will be logged for billing purposes with no query data being stored.
Please note that when using the no_log feature, your Customer Success expert will not have visibility of your queries to help you debug and optimize. For this reason, we recommend logging your own queries made to the Pipl API and including any [errors](/reference/errors) and [warnings](/reference/warnings) returned.
## Using the no_log feature with the Pipl API code libraries
If you’re using one of [Pipl’s API code libraries]code-libraries), you can easily enable the no_log feature with your queries. (For **Ruby** please contact your Customer Success expert.)
Instructions for activating this feature in Java, Python and PHP are shown below.
```java
//Update the default configuration on init, which will be used.
//Use the extraParams variable of the defaultConfiguration. See example below:
SearchConfiguration defaultConfiguration = SearchAPIRequest.getDefaultConfiguration();
defaultConfiguration.extraParams = "&no_log=True";
```
```python
# Extend the BASE_URL before making an API request.
SearchAPIRequest.BASE_URL += "&no_log=true"
request = SearchAPIRequest(email="clark.kent@example.com")
```
```php
/* Please see the source code on GitHub for the code library for reference (base_url definition - https://github.com/piplcom/piplapis-php/blob/master/src/piplapis/search.php#L84).
Once you construct a PiplApi_SearchAPIRequest object, you will need to change the base_url from:
*/
public static $base_url = 'api.pipl.com/search/?';
/* to the following to execute a request */
$base_url = 'api.pipl.com/search/?no_log=true&';
```
```csharp
#Use reflection to modify the Url property of your SearchAPIRequest object instance
typeof(SearchAPIRequest).GetProperty("Url")
.SetValue(yourSearchAPIRequest, "https://api.pipl.com/search/?no_log=true&");
```
## Using the no_log feature without the Pipl API code libraries
Simply add &no_log=true to your API queries with the Pipl API to activate this feature.
## Disabling logging within the pipl.com portal
In addition to server-side API logs, Pipl also maintains [1 week of transaction logs on the pipl.com portal](https://search.pipl.com/api/manage/queries) for customers with auditing needs they can't satisfy on their own. For customers who **do not** want this functionality, it can be disabled by setting the 'Errors Only' toggle on the same page.