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.


❗️

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 size parameter 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 query

Use Field Filters for standard filtering by company, title, location, salary, dates, and activity status.

Use query when you need logic that Field Filters do not support well, such as OR, 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_website is the most commonly used identifier in practice for specifying a company.

company_name is cleaner-backed and convenient when you only know the company by name.

company_id is 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 location filter 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



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

  • title uses cleaned match_phrase behavior.
  • description uses match_phrase behavior on the cleaned text description.
  • inferred_skills uses match, which is broader than match_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

Use 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 query when you need OR, must_not, exists, or other custom Elasticsearch logic.
  • If you provide both Field Filters and query, the query takes precedence and the Field Filters are ignored.

OR logic



OR Logic: Data Engineer or Machine Learning Engineer

Show 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

Use 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-DD strings or integer timestamps in milliseconds. The example below uses YYYY-MM-DD strings 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 a terms array) has a hard limit of 100 elements. If your request goes over this limit, it will fail.

See query limitations 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

📘

Quick Decision Guide

  • Start with Field Filters when you want simple filtering by documented input parameters.
  • Use query when you need OR, must_not, exists, or other custom Elasticsearch logic.
  • If you provide both Field Filters and query, the query takes precedence and the Field Filters are ignored.