Examples - Job Posting Search API
This page is a library of copy-pasteable examples for the Job Posting Search API.
Each example is designed to be easy to adapt for your own workflow. Replace YOUR_API_KEY with your API key, then modify the request payload as needed.
If you want a more guided first walkthrough, start with the Quickstart.
🔍 Browse Examples
Click to see the full list of examples on this page
Exact ID Lookup
Company Filters
- Basic Search: Company + Title
- Search by Company ID
- Search by Company Name
- Search by LinkedIn Profile
Title & Role Filters
Location Filters
Date & Activity Filters
Compensation Filters
- Filter by Salary Range + Currency + Period
- Filter by Remote Work Policy
- Combined Multi-Filter Search
Text & Content Filters
Bulk Retrieval
Elasticsearch Query Examples
Heads Up! Credit Usage
Job Posting Search API calls cost 1 credit for each job posting record returned.
If you are making a search that could have a large number of results, make sure to use the
sizeparameter to control the maximum number of records returned per request and cap your credit usage.
Found a bug? Is there an example you'd like to see that's not listed here?
Head over to the public roadmap and submit a bug ticket or a feature request and receive automatic notifications as your bug is resolved or your request is implemented.
Field Filter Examples
Use Field Filters when the request can be expressed using supported fields. Multiple Field Filters are combined with AND logic.
Choosing Between Field Filters and
queryUse Field Filters for standard filtering by company, title, location, salary, dates, and activity status.
Use
querywhen you need logic that Field Filters do not support well, such asOR,must_not,exists, or searching across lists of values.
Exact ID lookup
Search by Exact Job Posting ID
Use this when you already know the specific PDL job posting ID you want to retrieve.
Give me the job posting with this exact PDL job posting ID.
import requests
API_KEY = "YOUR_API_KEY"
API_ENDPOINT = "https://api.peopledatalabs.com/v5/job_posting/search"
payload = {
"id": "yjwkKHukr18",
"pretty": True
}
response = requests.post(API_ENDPOINT, json={**payload, "api_key": API_KEY})
response.raise_for_status()
print(response.text)Company filters
Basic Search: Company + Title
Use this when you want a simple company + job title search using built-in field filters.
Show me open job postings at OpenAI with "engineer" in the title.
import requests
API_KEY = "YOUR_API_KEY"
API_ENDPOINT = "https://api.peopledatalabs.com/v5/job_posting/search"
payload = {
"company_website": "openai.com",
"title": "engineer",
"is_active": True,
"size": 10,
"pretty": True
}
response = requests.post(API_ENDPOINT, json={**payload, "api_key": API_KEY})
response.raise_for_status()
print(response.text)Company Filter Tips
company_websiteis the most commonly used identifier in practice for specifying a company.
company_nameis cleaner-backed and convenient when you only know the company by name.
company_idis the most precise company filter when you already have the PDL company ID.For additional details see our FAQs: What is the most precise way to search for a company?
Search by Company ID
Use this when you know the PDL company_id and want the most precise company filter. Typically a PDL company_id will come from using our Company Search API or Company Enrichment API.
Show me open engineering job postings for this exact PDL company.
import requests
API_KEY = "YOUR_API_KEY"
API_ENDPOINT = "https://api.peopledatalabs.com/v5/job_posting/search"
payload = {
"company_id": "30x8wUj6MNfspLBBgNqOawgOLDP9", # OpenAI's PDL ID
"title_role": "engineering",
"is_active": True,
"size": 10,
"pretty": True
}
response = requests.post(API_ENDPOINT, json={**payload, "api_key": API_KEY})
response.raise_for_status()
print(response.text)Search by Company Name
Use this when you don't have a unique identifier for a company and want cleaner-backed fuzzy matching on company_name.
Show me open engineering job postings for Open AI.
import requests
API_KEY = "YOUR_API_KEY"
API_ENDPOINT = "https://api.peopledatalabs.com/v5/job_posting/search"
payload = {
"company_name": "Open AI",
"title_role": "engineering",
"is_active": True,
"size": 10,
"pretty": True
}
response = requests.post(API_ENDPOINT, json={**payload, "api_key": API_KEY})
response.raise_for_status()
print(response.text)Search by Company LinkedIn Profile
Use this when you want to search job postings for a company using its LinkedIn company URL.
Show me open job postings for OpenAI.
import requests
API_KEY = "YOUR_API_KEY"
API_ENDPOINT = "https://api.peopledatalabs.com/v5/job_posting/search"
payload = {
"company_profile": "linkedin.com/company/openai",
"size": 10,
"is_active": True,
"pretty": True
}
response = requests.post(API_ENDPOINT, json={**payload, "api_key": API_KEY})
response.raise_for_status()
print(response.text)Search by Title Taxonomy
Use PDL's normalized title fields when you want structured title filters instead of free-text title matching.
Show me open senior data engineering jobs in the research and development title class.
import requests
API_KEY = "YOUR_API_KEY"
API_ENDPOINT = "https://api.peopledatalabs.com/v5/job_posting/search"
payload = {
"title_sub_role": "data_engineering",
"title_levels": "senior",
"size": 10,
"is_active": True,
"pretty": True
}
response = requests.post(API_ENDPOINT, json={**payload, "api_key": API_KEY})
response.raise_for_status()
print(response.text)This example combines thetitle_sub_role, and title_levels.
Show me open vp-level finance jobs class.
import requests
API_KEY = "YOUR_API_KEY"
API_ENDPOINT = "https://api.peopledatalabs.com/v5/job_posting/search"
payload = {
"title_role": "finance",
"title_levels": "vp",
"is_active": True,
"size": 10,
"pretty": True
}
response = requests.post(API_ENDPOINT, json={**payload, "api_key": API_KEY})
response.raise_for_status()
print(response.text)This example combines thetitle_role, and title_levels.
Search by Multiple Title Taxonomy Values
Use this when you want to provide multiple comma-separated values for canonical taxonomy fields like title_class, title_role, title_sub_role, and title_levels.
Show me open jobs that are senior OR manager roles in data engineering OR data science
import requests
API_KEY = "YOUR_API_KEY"
API_ENDPOINT = "https://api.peopledatalabs.com/v5/job_posting/search"
payload = {
"title_role": "engineering",
"title_sub_role": "data_engineering,data_science",
"title_levels": "senior,manager",
"is_active": True,
"size": 10,
"pretty": True
}
response = requests.post(API_ENDPOINT, json={**payload, "api_key": API_KEY})
response.raise_for_status()
print(response.text)Location filters
The location input is flexible and can match countries, continents, regions, cities, and more.
Job Posts with Multiple Locations
Just a reminder that PDL job posting records can contain multiple locations. As a result, using the
locationfilter will return job posts where at least one of the posted locations matches the provided input.
Country-level location
Show me open sales jobs in Germany.
import requests
API_KEY = "YOUR_API_KEY"
API_ENDPOINT = "https://api.peopledatalabs.com/v5/job_posting/search"
payload = {
"title_role": "sales",
"location": "germany",
"is_active": True,
"size": 10,
"pretty": True
}
response = requests.post(API_ENDPOINT, json={**payload, "api_key": API_KEY})
response.raise_for_status()
print(response.text)City-level location
Show me open engineering jobs in Seattle.
import requests
API_KEY = "YOUR_API_KEY"
API_ENDPOINT = "https://api.peopledatalabs.com/v5/job_posting/search"
payload = {
"title_role": "engineering",
"location": "seattle, washington",
"is_active": True,
"size": 10,
"pretty": True
}
response = requests.post(API_ENDPOINT, json={**payload, "api_key": API_KEY})
response.raise_for_status()
print(response.text)Region-level location
Show me open engineering jobs in Ontario, Canada.
import requests
API_KEY = "YOUR_API_KEY"
API_ENDPOINT = "https://api.peopledatalabs.com/v5/job_posting/search"
payload = {
"title_role": "engineering",
"location": "ontario, canada",
"is_active": True,
"size": 10,
"pretty": True
}
response = requests.post(API_ENDPOINT, json={**payload, "api_key": API_KEY})
response.raise_for_status()
print(response.text)Continent-level location
Show me open marketing jobs in Europe.
import requests
API_KEY = "YOUR_API_KEY"
API_ENDPOINT = "https://api.peopledatalabs.com/v5/job_posting/search"
payload = {
"title_role": "marketing",
"location": "europe",
"is_active": True,
"size": 10,
"pretty": True
}
response = requests.post(API_ENDPOINT, json={**payload, "api_key": API_KEY})
response.raise_for_status()
print(response.text)Date and activity filters
Date Filter Cheat Sheet
- Use
first_seen_min,deactivated_date_min, orlast_verified_minfor inclusive lower bounds.- Use
is_activeto filter to active jobs- Use the corresponding
*_maxfields for inclusive upper bounds.- To match a single day exactly, set the
*_minand*_maxfields to the sameYYYY-MM-DDdate.
Search by Exact Date
Use parameterized date fields when you want to match a date range.
Show me all job postings posted between January 1, 2026 and January 15, 2026.
import requests
API_KEY = "YOUR_API_KEY"
API_ENDPOINT = "https://api.peopledatalabs.com/v5/job_posting/search"
payload = {
"first_seen_min": "2026-01-01",
"first_seen_max": "2026-01-15",
"size": 10,
"pretty": True
}
response = requests.post(API_ENDPOINT, json={**payload, "api_key": API_KEY})
response.raise_for_status()
print(response.text)Search by Last Verified Date
Use this when you want job postings that were verified recently by PDL.
Show me open job postings that PDL verified within the last two days.
import requests
from datetime import date, timedelta
API_KEY = "YOUR_API_KEY"
API_ENDPOINT = "https://api.peopledatalabs.com/v5/job_posting/search"
_two_days_ago = str(date.today()-timedelta(days=2))
payload = {
"last_verified_min": _two_days_ago,
"is_active": True,
"size": 10,
"pretty": True
}
response = requests.post(API_ENDPOINT, json={**payload, "api_key": API_KEY})
response.raise_for_status()
print(response.text)Recently Deactivated Jobs
Use this when you want historical job postings that were deactivated within a specific date range.
Show me jobs that were deactivated during March 2026.
import requests
API_KEY = "YOUR_API_KEY"
API_ENDPOINT = "https://api.peopledatalabs.com/v5/job_posting/search"
payload = {
"deactivated_date_min": "2026-03-01",
"deactivated_date_max": "2026-03-31",
"size": 10,
"pretty": True
}
response = requests.post(API_ENDPOINT, json={**payload, "api_key": API_KEY})
response.raise_for_status()
print(response.text)Active Jobs Only
Use the built-in is_active field filter when you want only active job postings. If is_active is not included, it is defaulted to False
Show me only true job postings for engineers.
import requests
API_KEY = "YOUR_API_KEY"
API_ENDPOINT = "https://api.peopledatalabs.com/v5/job_posting/search"
payload = {
"title_role": "engineering",
"is_active": True,
"size": 10,
"pretty": True
}
response = requests.post(API_ENDPOINT, json={**payload, "api_key": API_KEY})
response.raise_for_status()
print(response.text)Compensation filters
Filter by Salary Range + Currency + Period
Use this when you want compensation filters with explicit salary units.
Show me engineering jobs with annual salaries between $150,000 and $300,000 USD.
import requests
API_KEY = "YOUR_API_KEY"
API_ENDPOINT = "https://api.peopledatalabs.com/v5/job_posting/search"
payload = {
"title_role": "engineering",
"salary_range_min": 150000,
"salary_range_max": 300000,
"salary_currency": "usd",
"salary_period": "annual",
"size": 10,
"pretty": True
}
response = requests.post(API_ENDPOINT, json={**payload, "api_key": API_KEY})
response.raise_for_status()
print(response.text)Filter by Remote Work Policy
Use this when you want jobs with a specific remote work policy value.
Show me active remote engineering jobs.
import requests
API_KEY = "YOUR_API_KEY"
API_ENDPOINT = "https://api.peopledatalabs.com/v5/job_posting/search"
payload = {
"title_role": "engineering",
"remote_work_policy": "Remote",
"is_active": True,
"size": 10,
"pretty": True
}
response = requests.post(API_ENDPOINT, json={**payload, "api_key": API_KEY})
response.raise_for_status()
print(response.text)Combined Multi-Filter Search
Use this when you want to combine multiple field filters with built-in AND behavior.
Show me active remote jobs in the United States with annual salaries of at least $150,000 USD.
import requests
API_KEY = "YOUR_API_KEY"
API_ENDPOINT = "https://api.peopledatalabs.com/v5/job_posting/search"
payload = {
"location": "united states",
"remote_work_policy": "Remote",
"salary_range_min": 150000,
"salary_currency": "usd",
"salary_period": "annual",
"is_active": True,
"size": 10,
"pretty": True
}
response = requests.post(API_ENDPOINT, json={**payload, "api_key": API_KEY})
response.raise_for_status()
print(response.text)Text and content filters
Text Matching Behavior
titleuses cleanedmatch_phrasebehavior.descriptionusesmatch_phrasebehavior on the cleaned text description.inferred_skillsusesmatch, which is broader thanmatch_phrase.
Search by Description Text
Use this when you want to find jobs whose descriptions contain a specific phrase.
Show me active job postings whose descriptions mention "unlimited PTO".
import requests
API_KEY = "YOUR_API_KEY"
API_ENDPOINT = "https://api.peopledatalabs.com/v5/job_posting/search"
payload = {
"description": "unlimited PTO",
"is_active": True,
"size": 10,
"pretty": True
}
response = requests.post(API_ENDPOINT, json={**payload, "api_key": API_KEY})
response.raise_for_status()
print(response.text)Search by Inferred Skills
Use this when you want to search the skills extracted from the job posting description.
Show me active job postings that mention or imply requiring JavaScript skills.
import requests
API_KEY = "YOUR_API_KEY"
API_ENDPOINT = "https://api.peopledatalabs.com/v5/job_posting/search"
payload = {
"inferred_skills": "javascript",
"is_active": True,
"size": 10,
"pretty": True
}
response = requests.post(API_ENDPOINT, json={**payload, "api_key": API_KEY})
response.raise_for_status()
print(response.text)Bulk Retrieval Examples
Paginate with scroll_token
scroll_tokenUse this when a query matches more records than you want to retrieve in a single response.
Give me the 10 results for the same search over two pages.
import requests
API_KEY = "YOUR_API_KEY"
API_ENDPOINT = "https://api.peopledatalabs.com/v5/job_posting/search"
base_payload = {
"location": "united states",
"title_role": "engineering",
"size": 5 # Sets the number of records returned per request (max: 100)
}
first_response = requests.post(API_ENDPOINT, json={**base_payload, "api_key": API_KEY})
first_response.raise_for_status()
first_page = first_response.json()
print(f"First page returned {len(first_page['data'])} records")
print(f"Total matches: {first_page['total']}")
next_payload = {
**base_payload,
"scroll_token": first_page["scroll_token"]
}
second_response = requests.post(API_ENDPOINT, json={**next_payload, "api_key": API_KEY})
second_response.raise_for_status()
second_page = second_response.json()
print(f"Second page returned {len(second_page['data'])} records")Save Results to a JSON File
Run this search and save the full API response to a local JSON file.
import json
import requests
API_KEY = "YOUR_API_KEY"
API_ENDPOINT = "https://api.peopledatalabs.com/v5/job_posting/search"
payload = {
"company_name": "openai",
"title_role": "engineering",
"size": 10
}
response = requests.post(API_ENDPOINT, json={**payload, "api_key": API_KEY})
response.raise_for_status()
with open("job_posting_results.json", "w") as f:
json.dump(response.json(), f, indent=2)
print("Saved response to job_posting_results.json")Elasticsearch Query Examples
Use the query field when you need search logic that Field Filters do not support, such as OR conditions, exists queries, or multi-company searches.
Choosing Between Field Filters and
query
- Start with Field Filters when you want simple filtering by documented input parameters.
- Use
querywhen you needOR,must_not,exists, or other custom Elasticsearch logic.- If you provide both Field Filters and
query, thequerytakes precedence and the Field Filters are ignored.
OR logic
OR Logic: Data Engineer or Machine Learning Engineer
OR Logic: Data Engineer or Machine Learning EngineerShow me jobs for either data engineers or machine learning engineers.
import requests
API_KEY = "YOUR_API_KEY"
API_ENDPOINT = "https://api.peopledatalabs.com/v5/job_posting/search"
payload = {
"query": {
"bool": {
"should": [
{"match_phrase": {"title": "data engineer"}},
{"match_phrase": {"title": "machine learning engineer"}}
],
"minimum_should_match": 1
}
},
"size": 10,
"pretty": True
}
response = requests.post(API_ENDPOINT, json={**payload, "api_key": API_KEY})
response.raise_for_status()
print(response.text)must + should: One of Several Titles Plus a Seniority Constraint
must + should: One of Several Titles Plus a Seniority ConstraintUse this when you want to require one condition and allow multiple title alternatives.
Show me senior jobs for either data engineers or analytics engineers.
import requests
API_KEY = "YOUR_API_KEY"
API_ENDPOINT = "https://api.peopledatalabs.com/v5/job_posting/search"
payload = {
"query": {
"bool": {
"must": [
{"term": {"title_levels": "senior"}}
],
"should": [
{"match_phrase": {"title": "data engineer"}},
{"match_phrase": {"title": "analytics engineer"}}
],
"minimum_should_match": 1
}
},
"size": 10,
"pretty": True
}
response = requests.post(API_ENDPOINT, json={**payload, "api_key": API_KEY})
response.raise_for_status()
print(response.text)Range logic
Date Range Query
Use this when you want a custom Elasticsearch date range query, or when you need date logic beyond the built-in field filters.
Show me jobs first seen during January 2026.
Dates in Elasticsearch
In Elasticsearch date queries, you can use either
YYYY-MM-DDstrings or integer timestamps in milliseconds. The example below usesYYYY-MM-DDstrings for readability.
import requests
API_KEY = "YOUR_API_KEY"
API_ENDPOINT = "https://api.peopledatalabs.com/v5/job_posting/search"
# Pick the exact date range you want to search.
start_date = "2026-01-01"
end_date = "2026-02-01"
payload = {
"query": {
"bool": {
"must": [
{
"range": {
"first_seen": {
"gte": start_date,
"lt": end_date
}
}
}
]
}
},
"size": 10,
"pretty": True
}
response = requests.post(API_ENDPOINT, json={**payload, "api_key": API_KEY})
response.raise_for_status()
print(response.text)This example finds job postings first seen on or after 2026-01-01 and before 2026-02-01.
Existence and exclusion logic
Only Jobs with Salary Data
Use this when you want job postings where salary information is present.
Show me only job postings that include salary data.
import requests
API_KEY = "YOUR_API_KEY"
API_ENDPOINT = "https://api.peopledatalabs.com/v5/job_posting/search"
payload = {
"query": {
"bool": {
"must": [
{"exists": {"field": "salary_min"}}
]
}
},
"size": 10,
"pretty": True
}
response = requests.post(API_ENDPOINT, json={**payload, "api_key": API_KEY})
response.raise_for_status()
print(response.text)Exclude Internship Roles
Use this when you want to remove a class of jobs from the results with must_not.
Show me engineering jobs, but leave out internship roles.
import requests
API_KEY = "YOUR_API_KEY"
API_ENDPOINT = "https://api.peopledatalabs.com/v5/job_posting/search"
payload = {
"query": {
"bool": {
"must": [
{"term": {"title_role": "engineering"}}
],
"must_not": [
{"match_phrase": {"title": "intern"}}
]
}
},
"size": 10,
"pretty": True
}
response = requests.post(API_ENDPOINT, json={**payload, "api_key": API_KEY})
response.raise_for_status()
print(response.text)Combined advanced queries
Search Across Multiple Companies
Use a terms query when you want to search across a list of company IDs.
Show me job postings across this list of companies.
Query Array Limit
Any array in an Elasticsearch
query(such as atermsarray) has a hard limit of100elements. If your request goes over this limit, it will fail.See
querylimitations for the full details.
import requests
API_KEY = "YOUR_API_KEY"
API_ENDPOINT = "https://api.peopledatalabs.com/v5/job_posting/search"
payload = {
"query": {
"terms": {
"company_id": [
"30x8wUj6MNfspLBBgNqOawgOLDP9",
"LGrXE14x4Kvzj2cbaeRUngOCTuJA"
]
}
},
"size": 10,
"pretty": True
}
response = requests.post(API_ENDPOINT, json={**payload, "api_key": API_KEY})
response.raise_for_status()
print(response.text)Combined Query: Company List + Date Range + Title Match
Use this when you want to combine multiple company IDs, title matching, and a first_seen cutoff date in one Elasticsearch query.
Show me engineer jobs at these companies that were first seen on or after January 1, 2026.
import requests
API_KEY = "YOUR_API_KEY"
API_ENDPOINT = "https://api.peopledatalabs.com/v5/job_posting/search"
payload = {
"query": {
"bool": {
"must": [
{
"terms": {
"company_id": [
"30x8wUj6MNfspLBBgNqOawgOLDP9",
"LGrXE14x4Kvzj2cbaeRUngOCTuJA"
]
}
},
{
"match": {
"title": "engineer"
}
},
{
"range": {
"first_seen": {
"gte": "2026-01-01"
}
}
}
]
}
},
"size": 10,
"pretty": True
}
response = requests.post(API_ENDPOINT, json={**payload, "api_key": API_KEY})
response.raise_for_status()
print(response.text)Choosing Between Field Filters and query
queryQuick Decision Guide
- Start with Field Filters when you want simple filtering by documented input parameters.
- Use
querywhen you needOR,must_not,exists, or other custom Elasticsearch logic.- If you provide both Field Filters and
query, thequerytakes precedence and the Field Filters are ignored.
Updated about 5 hours ago
