CareerPlug Jobs API
Query jobs from CareerPlug boards through one API with ?source=careerplug — plus how CareerPlug's paginated board really behaves.
CareerPlug is hiring software for US franchises and small businesses — Meineke,
Nothing Bundt Cakes, Mathnasium and several thousand independent operators like
them. Every posting page carries schema.org JobPosting JSON-LD, and it's the
richest structured markup in the small-business pool. There are 15,133 CareerPlug
postings in this dataset, 100% of them with a real description — counts move
hourly, so read them from /v1/meta rather than
trusting this sentence.
Try it#
curl -G https://api.hyperjobs.io/v1/jobs \
-H "Authorization: Bearer $HYPERJOBS_KEY" \
--data-urlencode "source=careerplug" \
--data-urlencode "time_frame=7d" \
--data-urlencode "limit=2"{
"data": [
{
"id": "careerplug:360clean-columbia_419257",
"title": "Cleaning Technician, Day Shifts",
"company": {
"slug": "360clean-columbia",
"name": "360clean of Columbia - 2765",
"domain": "360clean.com",
"website": "https://360clean.com",
"logo": "https://media.licdn.com/dms/image/…",
"industry": "Facilities Services",
"employee_count": 24
},
"location": {
"remote": false,
"countries": ["United States"],
"cities": ["Lexington"],
"regions": ["SC"],
"raw": ["Lexington, SC, US"]
},
"employment_type": ["PART_TIME"],
"work_arrangement": null,
"seniority": null,
"salary": null,
"skills": ["cleaning", "sanitation"],
"taxonomies": ["Facilities"],
"apply_url": "https://360clean-columbia.careerplug.com/jobs/419257/apps/new",
"url": "https://360clean-columbia.careerplug.com/jobs/419257/apps/new",
"source": "careerplug",
"posted_at": "2026-06-19T16:27:17.000Z",
"expires_at": null,
"updated_at": "2026-07-14T09:03:44.000Z"
}
],
"total": 2,
"limit": 2,
"offset": 0
}How CareerPlug boards actually work#
An HTML list, then a page per posting:
# 1. List — 30 postings per page, ids in the hrefs
curl -L "https://<tenant>.careerplug.com/jobs?page=1"
# 2. Detail — JobPosting JSON-LD on the application page
curl -L "https://<tenant>.careerplug.com/jobs/<id>/apps/new"<tenant> is the subdomain. The list is markup, so the ids come out of the
/jobs/<id> hrefs; everything worth having comes from the detail page's JSON-LD.
The pagination is real, which is rarer than it sounds#
Half this pool ships a page parameter that the server ignores, so you learn to
distrust them. CareerPlug's is genuine, and it was verified the only way that
settles it: by crawling a board to exhaustion. On meineke-careers, 30 ids per
page with zero overlap through page 12, 4 on page 13, 0 on page 14 — 364
distinct postings.
So you page. But you page until a page contributes nothing new, rather than trusting a total, because the board exposes no count and a fixed page ceiling would quietly truncate exactly the big franchise tenants you most wanted.
The JSON-LD is the best in this pool#
| JSON-LD field | Gives you |
|---|---|
description | The full body |
datePosted | A real publish date, ISO with a zone |
validThrough | A declared expiry when the employer set one |
baseSalary | Structured pay, min/max with unitText |
jobLocation.address | A full PostalAddress, not a string |
employmentType | Standard schema.org values |
hiringOrganization.sameAs | The franchisee's own website |
That last row is the one to notice. sameAs is the franchisee's real site, which
makes CareerPlug one of the few platforms in this segment where a posting arrives
already pointing at the company that posted it. Identity, for free, from the
source.
What bites you#
The brand tenant is empty on purpose. applebees-careers and
burger-king-careers return 200 with zero jobs, and that is not a block, a
throttle or a broken parse. Hiring on this platform routes to per-franchisee
tenants, so the brand-level board is genuinely empty. An empty CareerPlug board
means empty. Retrying it, escalating it to a proxy tier or flagging it as failed
all burn budget on a board that is working exactly as designed.
The tenant name is a brand slug, not the employer. Derive a company name from
the board token and meineke-careers becomes "Meineke-Careers" — a brand, when
the entity actually hiring is one franchisee in one town. The JSON-LD's
hiringOrganization is the real employing entity, and on this platform they are
routinely different things.
Proxying this platform is a waste of money. The list pages are HTML and each detail page is a full ~190KB document from which a small JSON-LD block is kept. A single board runs 7–17MB. It works direct, so residential GB spent here buys nothing at all. Ours is pinned to never proxy.
Salary is in the markup, not on every posting. baseSalary is structured and
parsed when the employer published it. Plenty of franchise postings simply don't.
Or use ours#
The shape is friendly. The volume is the tax: 30 postings per page, a ~190KB detail fetch per posting, paged to exhaustion, across the 505 CareerPlug boards in our queue — and the tenants worth having are the long tail of individual franchisees, not the brands you'd think to look up.
You get every board crawled to its real end rather than to a guessed page count,
the JSON-LD parsed into the same Job shape as every other
source, the franchisee's real name and site preferred over the brand slug, empty
brand tenants understood as empty instead of retried, structured addresses and
dates carried through, CareerPlug rows deduplicated against the same job on
LinkedIn or elsewhere, expiry by board diffing, and the
company join — which CareerPlug, unusually, helps with.
Query it with ?source=careerplug.
Quickstart, then pricing.
Every source above normalises onto the same schema, with the hiring company already joined onto each posting.
Get an API key