- mediumLegacy api.peoplematter.com apply URLs redirect to my.peoplematter.com and appear broken if redirects are disabled.
- Send requests with allow_redirects=True and treat the final my.peoplematter.com/mja/{tenant}/jobapp/GetStarted URL as the canonical job page.
- highThere is no stable anonymous listing JSON endpoint; the organization /hire route is a multi-step location-then-job workflow.
- Seed enumeration from known apply URLs (jobOpeningId UUIDs) rather than a directory feed, and stop discovery when no new UUIDs surface. Use Jobo's maintained tenant coverage to avoid rebuilding the hire workflow.
- mediumPeopleMatter was historically fronted by Cloudflare with country/ASN filtering that returned 403s from some networks.
- The block no longer reproduces on plain HTTP, but keep a descriptive User-Agent and retry-with-backoff on transient 403s in case filtering recurs from datacenter egress.
- lowTenant aliases vary widely in format (e.g. mattiaciogroup vs KFCPPP0001225) and the job id lives in the query string, not the path.
- Treat the first path segment as an opaque tenant token and read the UUID from the jobOpeningId query parameter; strip the query before glob/path matching.
PeopleMatter (Snagajob) Jobs API.
Reach high-volume hourly and frontline job listings from the restaurant, retail, and hospitality brands that hire through Snagajob's enterprise platform. Jobo turns tenant apply pages into clean, structured job data.
What's in every response.
Data fields, real-world applications, and the companies already running on PeopleMatter (Snagajob).
Data fields
- Job Titles & Roles
- Store & Site Locations
- Employer / Brand Name
- Full Job Descriptions
- Stable Job UUIDs
- Hourly & Frontline Positions
Use cases
- 01Hourly Job Aggregation
- 02Restaurant & Retail Hiring Feeds
- 03Frontline Labor Market Data
- 04Franchise Location Tracking
How to scrape PeopleMatter (Snagajob).
Step-by-step guide to extracting jobs from PeopleMatter (Snagajob)-powered career pages—endpoints, authentication, and working code.
import re
from urllib.parse import urlparse, parse_qs
APPLY_RE = re.compile(
r"^https://api\.peoplematter\.com/(?P<tenant>[^/]+)/Hire/Recruiting/Application/Index",
re.IGNORECASE,
)
def parse_apply_url(url: str):
"""Return {tenant, job_opening_id} for a PeopleMatter apply URL, else None."""
match = APPLY_RE.match(url)
if not match:
return None
query = parse_qs(urlparse(url).query)
return {
"tenant": match.group("tenant"), # e.g. "mattiaciogroup", "KFCPPP0001225"
"job_opening_id": query.get("jobOpeningId", [None])[0], # UUID
}
print(parse_apply_url(
"https://api.peoplematter.com/mattiaciogroup/Hire/Recruiting/Application/Index"
"?jobOpeningId=d7944c9c-c189-421d-8b02-a9540112218d"
))import requests
UA = "Mozilla/5.0 (compatible; JoboBot/1.0; +https://jobo.world)"
def resolve_job_page(apply_url: str) -> requests.Response:
resp = requests.get(
apply_url,
headers={"User-Agent": UA},
allow_redirects=True, # api.peoplematter.com -> my.peoplematter.com/mja/...
timeout=30,
)
resp.raise_for_status()
return resp
resp = resolve_job_page(
"https://api.peoplematter.com/mattiaciogroup/Hire/Recruiting/Application/Index"
"?jobOpeningId=d7944c9c-c189-421d-8b02-a9540112218d"
)
print(resp.url) # final my.peoplematter.com application URLfrom bs4 import BeautifulSoup
def extract_job(resp: requests.Response, parsed: dict) -> dict:
soup = BeautifulSoup(resp.text, "html.parser")
title_el = soup.find("h1") or soup.find(attrs={"class": re.compile("title", re.I)})
desc_el = soup.select_one("[class*='description'], [id*='description']")
return {
"job_opening_id": parsed["job_opening_id"], # stable UUID key
"tenant": parsed["tenant"],
"url": resp.url,
"title": title_el.get_text(strip=True) if title_el else None,
"description_html": str(desc_el) if desc_el else None,
}def hire_landing(business_alias: str) -> str:
# Documented org route; selection is a multi-step location -> job workflow.
return f"https://my.peoplematter.com/{business_alias}/hire"
def collect(apply_urls: list[str]) -> list[dict]:
seen: set[str] = set()
jobs: list[dict] = []
for url in apply_urls:
parsed = parse_apply_url(url)
if not parsed or parsed["job_opening_id"] in seen:
continue # skip malformed or duplicate UUIDs across tenants
seen.add(parsed["job_opening_id"])
jobs.append(extract_job(resolve_job_page(url), parsed))
return jobs- 1Follow HTTP redirects and treat the final my.peoplematter.com URL as the canonical job page.
- 2Extract the tenant from the first path segment and the jobOpeningId UUID from the query string; treat both as opaque.
- 3Pace requests around 500ms apart and cap concurrency near 2 detail fetches to stay polite.
- 4Send a descriptive User-Agent and retry on transient 403s in case Cloudflare filtering recurs.
- 5Deduplicate jobs by their jobOpeningId UUID, since the same role can surface across franchise tenants.
- 6Fall back to Jobo's normalized feed instead of reconstructing the multi-step hire workflow yourself.
One endpoint. All PeopleMatter (Snagajob) jobs. No scraping, no sessions, no maintenance.
Get API accesscurl "https://connect.jobo.world/api/jobs?sources=peoplematter (snagajob)" \
-H "X-Api-Key: YOUR_KEY"Try the API.
Test Jobs and Feed endpoints against https://connect.jobo.world with live request/response examples, then copy ready-to-use curl commands.
Access PeopleMatter (Snagajob)
job data today.
One API call. Structured data. No scraping infrastructure to build or maintain — start with the $5 free starting balance and scale as you grow.