Paylocity Jobs API.
Cloud-based HR and payroll platform with integrated recruiting for mid-market employers.
Try the API.
Test Jobs, Feed, and Auto-Apply endpoints against https://connect.jobo.world with live request/response examples, then copy ready-to-use curl commands.
What's in every response.
Data fields, real-world applications, and the companies already running on Paylocity.
- HR and payroll integration
- Embedded JSON job data
- Server-side rendering
- Applicant tracking
- Multi-location support
- GUID-based company identification
- 01Mid-market employer tracking
- 02HR platform job monitoring
- 03Payroll-integrated recruiting analysis
- 04Multi-location workforce monitoring
How to scrape Paylocity.
Step-by-step guide to extracting jobs from Paylocity-powered career pages—endpoints, authentication, and working code.
import re
# Paylocity URL patterns
listing_url = "https://recruiting.paylocity.com/recruiting/jobs/All/b181f77f-0432-453f-b229-869d786bb46c/Available-Positions"
detail_url = "https://recruiting.paylocity.com/Recruiting/Jobs/Details/3898273"
# Extract tenant GUID from URL
guid_pattern = r'[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}'
guid_match = re.search(guid_pattern, listing_url)
tenant_guid = guid_match.group(0) if guid_match else None
print(f"Tenant GUID: {tenant_guid}")import requests
import re
import json
tenant_guid = "b181f77f-0432-453f-b229-869d786bb46c"
listing_url = f"https://recruiting.paylocity.com/recruiting/jobs/All/{tenant_guid}/Available-Positions"
response = requests.get(listing_url, timeout=30)
html = response.text
# Extract window.pageData JSON from the HTML
pattern = r'window\.pageData\s*=\s*(\{.*?\});\s*</script>'
match = re.search(pattern, html, re.DOTALL)
if match:
json_str = match.group(1)
page_data = json.loads(json_str)
jobs = page_data.get("Jobs", [])
print(f"Found {len(jobs)} jobs in embedded JSON")
else:
print("No embedded pageData found - may need HTML parsing fallback")import json
# Assuming page_data was extracted from the previous step
jobs = page_data.get("Jobs", [])
for job in jobs[:3]: # Show first 3 jobs
job_info = {
"job_id": job.get("JobId"),
"title": job.get("JobTitle"),
"location": job.get("LocationName"),
"is_remote": job.get("IsRemote", False),
"published_date": job.get("PublishedDate"),
"department": job.get("HiringDepartment"),
"is_internal": job.get("IsInternal", False),
}
# Full location details
location = job.get("JobLocation", {})
if location:
job_info["address"] = location.get("Address")
job_info["city"] = location.get("City")
job_info["state"] = location.get("State")
job_info["zip"] = location.get("Zip")
job_info["country"] = location.get("Country")
print(json.dumps(job_info, indent=2))import requests
from bs4 import BeautifulSoup
job_id = 3898273
detail_url = f"https://recruiting.paylocity.com/Recruiting/Jobs/Details/{job_id}"
response = requests.get(detail_url, timeout=30)
soup = BeautifulSoup(response.text, 'html.parser')
# Extract job details from HTML
title = soup.find('h1')
description = soup.find('main') or soup.find(class_='description')
# Look for location link (Google Maps)
location_link = soup.find('a', href=lambda x: x and 'maps.google.com' in x)
# Look for apply button
apply_link = soup.find('a', href=lambda x: x and '/Recruiting/Jobs/Apply/' in x)
job_details = {
"job_id": job_id,
"title": title.get_text(strip=True) if title else None,
"location": location_link.get_text(strip=True) if location_link else None,
"apply_url": apply_link['href'] if apply_link else None,
"description_length": len(description.get_text()) if description else 0,
}
print(job_details)import requests
import time
import json
import re
def fetch_paylocity_jobs(tenant_guid: str, max_retries: int = 3) -> list:
listing_url = f"https://recruiting.paylocity.com/recruiting/jobs/All/{tenant_guid}/Available-Positions"
for attempt in range(max_retries):
try:
response = requests.get(
listing_url,
timeout=30,
headers={"User-Agent": "Mozilla/5.0 (compatible; JobBot/1.0)"}
)
response.raise_for_status()
# Extract embedded JSON
pattern = r'window\.pageData\s*=\s*(\{.*?\});\s*</script>'
match = re.search(pattern, response.text, re.DOTALL)
if match:
page_data = json.loads(match.group(1))
return page_data.get("Jobs", [])
return []
except requests.RequestException as e:
print(f"Attempt {attempt + 1} failed: {e}")
if attempt < max_retries - 1:
time.sleep(2 ** attempt) # Exponential backoff
else:
raise
return []
# Usage with rate limiting
tenant_guids = ["b181f77f-0432-453f-b229-869d786bb46c"]
for guid in tenant_guids:
jobs = fetch_paylocity_jobs(guid)
print(f"Retrieved {len(jobs)} jobs for tenant {guid}")
time.sleep(1.5) # Conservative delay between requestsJob detail URLs only contain numeric job IDs. You must discover listing URLs through search engines (site:recruiting.paylocity.com), third-party databases like TheirStack, or existing company records.
The regex pattern may vary across Paylocity versions. Try alternative patterns like window.pageData = ({.*?}); or fall back to HTML parsing using CSS selectors for job links.
The embedded JSON only contains basic job metadata. For full descriptions, fetch each /Recruiting/Jobs/Details/{jobId} page and parse the HTML content.
Paylocity rate limits are undocumented. Add 1-2 second delays between requests and implement exponential backoff for retries. Use a consistent session with cookies.
Paylocity shows all jobs on one page (up to 99+). No pagination handling is needed, but large job boards may take longer to render.
Tenant GUIDs may change if a company migrates or reconfigures their Paylocity account. Verify the GUID is current by checking if the listing URL returns a 200 status.
- 1Extract window.pageData JSON for structured job data instead of HTML parsing
- 2Cache company GUIDs - they are essential for accessing job listings
- 3Use 1-2 second delays between requests to avoid rate limiting
- 4Fetch detail pages only when you need full job descriptions
- 5Maintain session cookies across requests for consistent behavior
- 6Use search engines or TheirStack for company discovery - no public directory exists
One endpoint. All Paylocity jobs. No scraping, no sessions, no maintenance.
Get API accesscurl "https://enterprise.jobo.world/api/jobs?sources=paylocity" \
-H "X-Api-Key: YOUR_KEY" Access Paylocity
job data today.
One API call. Structured data. No scraping infrastructure to build or maintain — start with the free tier and scale as you grow.