Person Search API
curl --request POST \
--url https://api.peoplecontext.com/v1/person/search \
--header 'Authorization: <authorization>' \
--header 'Content-Type: application/json' \
--data '
{
"query": {},
"size": 123,
"cursor": "<string>",
"sort": [
{}
],
"_source": {}
}
'import requests
url = "https://api.peoplecontext.com/v1/person/search"
payload = {
"query": {},
"size": 123,
"cursor": "<string>",
"sort": [{}],
"_source": {}
}
headers = {
"Authorization": "<authorization>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<authorization>', 'Content-Type': 'application/json'},
body: JSON.stringify({query: {}, size: 123, cursor: '<string>', sort: [{}], _source: {}})
};
fetch('https://api.peoplecontext.com/v1/person/search', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.peoplecontext.com/v1/person/search",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'query' => [
],
'size' => 123,
'cursor' => '<string>',
'sort' => [
[
]
],
'_source' => [
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: <authorization>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.peoplecontext.com/v1/person/search"
payload := strings.NewReader("{\n \"query\": {},\n \"size\": 123,\n \"cursor\": \"<string>\",\n \"sort\": [\n {}\n ],\n \"_source\": {}\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<authorization>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.peoplecontext.com/v1/person/search")
.header("Authorization", "<authorization>")
.header("Content-Type", "application/json")
.body("{\n \"query\": {},\n \"size\": 123,\n \"cursor\": \"<string>\",\n \"sort\": [\n {}\n ],\n \"_source\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.peoplecontext.com/v1/person/search")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<authorization>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"query\": {},\n \"size\": 123,\n \"cursor\": \"<string>\",\n \"sort\": [\n {}\n ],\n \"_source\": {}\n}"
response = http.request(request)
puts response.read_body{
"total": 123,
"results": [
{
"linkedin_url": "<string>",
"linkedin_username": "<string>",
"profile_id": "<string>",
"updated_at": "<string>",
"profile": {},
"experience": [
{}
],
"education": [
{}
],
"certifications": [
{}
],
"languages": [
{}
]
}
],
"next_cursor": {},
"credits_charged": 123
}Person Endpoints
Person Search API
Search for people in the LinkedIn index using Elasticsearch Query DSL
POST
/
v1
/
person
/
search
Person Search API
curl --request POST \
--url https://api.peoplecontext.com/v1/person/search \
--header 'Authorization: <authorization>' \
--header 'Content-Type: application/json' \
--data '
{
"query": {},
"size": 123,
"cursor": "<string>",
"sort": [
{}
],
"_source": {}
}
'import requests
url = "https://api.peoplecontext.com/v1/person/search"
payload = {
"query": {},
"size": 123,
"cursor": "<string>",
"sort": [{}],
"_source": {}
}
headers = {
"Authorization": "<authorization>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<authorization>', 'Content-Type': 'application/json'},
body: JSON.stringify({query: {}, size: 123, cursor: '<string>', sort: [{}], _source: {}})
};
fetch('https://api.peoplecontext.com/v1/person/search', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.peoplecontext.com/v1/person/search",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'query' => [
],
'size' => 123,
'cursor' => '<string>',
'sort' => [
[
]
],
'_source' => [
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: <authorization>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.peoplecontext.com/v1/person/search"
payload := strings.NewReader("{\n \"query\": {},\n \"size\": 123,\n \"cursor\": \"<string>\",\n \"sort\": [\n {}\n ],\n \"_source\": {}\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<authorization>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.peoplecontext.com/v1/person/search")
.header("Authorization", "<authorization>")
.header("Content-Type", "application/json")
.body("{\n \"query\": {},\n \"size\": 123,\n \"cursor\": \"<string>\",\n \"sort\": [\n {}\n ],\n \"_source\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.peoplecontext.com/v1/person/search")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<authorization>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"query\": {},\n \"size\": 123,\n \"cursor\": \"<string>\",\n \"sort\": [\n {}\n ],\n \"_source\": {}\n}"
response = http.request(request)
puts response.read_body{
"total": 123,
"results": [
{
"linkedin_url": "<string>",
"linkedin_username": "<string>",
"profile_id": "<string>",
"updated_at": "<string>",
"profile": {},
"experience": [
{}
],
"education": [
{}
],
"certifications": [
{}
],
"languages": [
{}
]
}
],
"next_cursor": {},
"credits_charged": 123
}Endpoint
POST /v1/person/search
Authentication
string
required
Bearer token with your API key:
Bearer YOUR_API_KEYBilling
Per-Result Billing: This endpoint charges 1 credit per result returned, not per request. If you request 10 results and get 10 back, you’re charged 10 credits. If only 3 match, you’re charged 3 credits.
credits_charged to show exactly how many credits were used, and response headers provide quota information:
X-Quota-Used: 110
X-Quota-Limit: 1000
X-Quota-Remaining: 890
X-Credits-Charged: 10
Pagination
This endpoint uses cursor-based pagination for efficient deep pagination through large result sets.- First request: Omit the
cursorparameter - Subsequent requests: Use the
next_cursorvalue from the previous response - Last page: When
next_cursorisnull, there are no more results
Request Parameters
Request Body (JSON)
object
required
Elasticsearch Query DSL object. Supports all standard Elasticsearch queries including
match, term, bool, range, and more.Example:{"match": {"profile.full_name": "John Doe"}}
integer
default:"10"
Number of results to return per page. Maximum 100.Example:
20string
Pagination cursor from a previous response’s
next_cursor field. Omit for the first page.Example: "eyJ2IjoxLCJzb3J0IjpbMS4wLCJqb2huZG9lIl19"array
Sort criteria as an array of sort objects. If omitted, results are sorted by relevance (
_score descending).Example:[{"profile.connections": "desc"}, {"profile.full_name.keyword": "asc"}]
array | boolean
Fields to include or exclude from the response. Use an array of field names to include only those fields, or
false to exclude _source entirely.Example: ["profile.full_name", "profile.headline", "linkedin_url"]Response
Success Response (200 OK)
integer
Total number of matching documents in the index.
array
Array of LinkedIn person profiles matching the query.
string
Full LinkedIn profile URL
string
LinkedIn username (profile slug)
string
LinkedIn internal profile ID
string
When the profile was last updated
object
Core profile information including
first_name, last_name, full_name, headline, summary, image_url, connections, followers, location, and personal_emailarray
Array of work experience entries with
title, company_name, company_id, company_url, location, description, start_date, end_date, and is_currentarray
Array of education entries with
school_name, school_id, school_url, degree, field_of_study, start_date, and end_datearray
Array of certifications with
name, issuer, and issue_datearray
Array of languages with
language and proficiencystring | null
Cursor for the next page of results.
null if there are no more results.integer
Number of credits charged for this request (1 per result returned).
Error Responses
Error Status Codes:- 400 Bad Request - Invalid query syntax or invalid cursor
- 401 Unauthorized - Missing or invalid API key
- 403 Forbidden - Organization is inactive
- 429 Too Many Requests - Rate limit exceeded or insufficient credits
{
"detail": "Insufficient credits. Have 5, need up to 10. Reduce 'size' parameter or upgrade your plan."
}
Examples
# Simple name search
curl -X POST "https://api.peoplecontext.com/v1/person/search" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": {"match": {"profile.full_name": "John Doe"}},
"size": 10
}'
# Search with filters
curl -X POST "https://api.peoplecontext.com/v1/person/search" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": {
"bool": {
"must": [{"match": {"profile.headline": "software engineer"}}],
"filter": [{"term": {"profile.location.country.keyword": "united states"}}]
}
},
"size": 20
}'
# Paginate with cursor
curl -X POST "https://api.peoplecontext.com/v1/person/search" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": {"match": {"profile.headline": "software engineer"}},
"size": 10,
"cursor": "eyJ2IjoxLCJzb3J0IjpbMS4wLCJqb2huZG9lIl19"
}'
import requests
url = "https://api.peoplecontext.com/v1/person/search"
headers = {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
}
# Search for software engineers in the US
payload = {
"query": {
"bool": {
"must": [{"match": {"profile.headline": "software engineer"}}],
"filter": [{"term": {"profile.location.country.keyword": "united states"}}]
}
},
"size": 20
}
response = requests.post(url, headers=headers, json=payload)
data = response.json()
print(f"Total matches: {data['total']}")
print(f"Credits charged: {data['credits_charged']}")
for person in data["results"]:
profile = person.get("profile", {})
print(f"- {profile.get('full_name')} | {profile.get('headline')}")
# Paginate through all results
while data.get("next_cursor"):
payload["cursor"] = data["next_cursor"]
response = requests.post(url, headers=headers, json=payload)
data = response.json()
for person in data["results"]:
profile = person.get("profile", {})
print(f"- {profile.get('full_name')} | {profile.get('headline')}")
const url = 'https://api.peoplecontext.com/v1/person/search';
const headers = {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
};
// Search for software engineers
const payload = {
query: {
bool: {
must: [{ match: { 'profile.headline': 'software engineer' } }],
filter: [{ term: { 'profile.location.country.keyword': 'united states' } }]
}
},
size: 20
};
const response = await fetch(url, {
method: 'POST',
headers,
body: JSON.stringify(payload)
});
const data = await response.json();
console.log(`Total matches: ${data.total}`);
console.log(`Credits charged: ${data.credits_charged}`);
data.results.forEach(person => {
const { full_name, headline } = person.profile || {};
console.log(`- ${full_name} | ${headline}`);
});
// Paginate with cursor
if (data.next_cursor) {
payload.cursor = data.next_cursor;
const nextResponse = await fetch(url, {
method: 'POST',
headers,
body: JSON.stringify(payload)
});
const nextData = await nextResponse.json();
// Process next page...
}
Sample Response
{
"total": 15234,
"results": [
{
"linkedin_url": "https://www.linkedin.com/in/johndoe",
"linkedin_username": "johndoe",
"profile_id": "ABC123",
"updated_at": "2025-01-15T10:30:00Z",
"profile": {
"first_name": "John",
"last_name": "Doe",
"full_name": "John Doe",
"headline": "Senior Software Engineer at TechCorp",
"summary": "Passionate about building scalable systems...",
"image_url": "https://media.licdn.com/...",
"connections": 500,
"followers": 1200,
"location": {
"raw_address": "San Francisco Bay Area",
"country": "United States",
"country_code": "US"
}
},
"experience": [
{
"title": "Senior Software Engineer",
"company_name": "TechCorp",
"company_url": "https://www.linkedin.com/company/techcorp",
"location": "San Francisco, CA",
"start_date": "2022-01",
"end_date": null,
"is_current": true
}
],
"education": [
{
"school_name": "Stanford University",
"degree": "Bachelor of Science",
"field_of_study": "Computer Science",
"start_date": "2014",
"end_date": "2018"
}
],
"certifications": [],
"languages": [
{"language": "English", "proficiency": "Native"},
{"language": "Spanish", "proficiency": "Professional"}
]
}
],
"next_cursor": "eyJ2IjoxLCJzb3J0IjpbOC41LCJqb2huZG9lIl19",
"credits_charged": 1
}
Query Examples
Search by Name
{
"query": {"match": {"profile.full_name": "John Doe"}}
}
Search by Company
{
"query": {"match": {"experience.company_name": "Google"}}
}
Search by Job Title (Current Only)
{
"query": {
"nested": {
"path": "experience",
"query": {
"bool": {
"must": [
{"match": {"experience.title": "Software Engineer"}},
{"term": {"experience.is_current": true}}
]
}
}
}
}
}
Search by Location
{
"query": {
"term": {"profile.location.country.keyword": "united states"}
}
}
Combined Search with Filters
{
"query": {
"bool": {
"must": [
{"match": {"profile.headline": "software engineer"}}
],
"filter": [
{"term": {"profile.location.country.keyword": "united states"}},
{"range": {"profile.connections": {"gte": 500}}}
]
}
},
"sort": [{"profile.connections": "desc"}],
"size": 50
}
Best Practices
Use Filters for Exact Matches: Use
term queries in a filter context for exact matches (like country codes). Filters are cached and faster than match queries.Limit Fields with _source: If you only need specific fields, use the
_source parameter to reduce response size and improve performance.Mind Your Credits: With per-result billing, requesting
size: 100 could charge up to 100 credits per request. Start with smaller page sizes and paginate as needed.Keyword Fields: For exact matching on text fields, use the
.keyword suffix (e.g., profile.location.country.keyword). Without it, text is analyzed and may not match exactly.Related
- LinkedIn Webset Guide - Overview of LinkedIn data
- Person Enrichment API - Enrich profiles by identifier
- Authentication Guide - API key setup