Apploi Jobs API.

Apploi is a hiring platform for healthcare and senior-living employers. Its public company boards render every job link server-side, and each detail page carries canonical JobPosting JSON-LD — no key required.

Get API access

What's in every response.

Data fields, real-world applications, and the companies already running on Apploi.

Data fields

  • Full Job Descriptions
  • JobPosting JSON-LD
  • Employment Type
  • Facility Locations
  • Posted Dates
  • Direct Apply URLs

Use cases

  1. 01Healthcare Job Aggregation
  2. 02Senior Living Hiring Trackers
  3. 03Nursing Recruitment Feeds
  4. 04Local Labour Market Research
DIY GUIDE

How to scrape Apploi.

Step-by-step guide to extracting jobs from Apploi-powered career pages—endpoints, authentication, and working code.

API type
HTML
Difficulty
beginner
Rate limit
No published limit; 403/429 under load — ~250ms between requests, max 3 concurrent detail fetches
Authentication
No auth

Resolve the company board token

Public Apploi boards live at apply-jobs.apploi.com/jobs/{companyToken}. Job links on the same host use /job/{jobId}/{companyToken}/{slug}, so a single detail URL is enough to recover the board it belongs to. Short jobs.apploi.com/view/{id} links redirect onto the canonical shape.

Step 1: Resolve the company board token
from urllib.parse import urlparse

HOST = "apply-jobs.apploi.com"

def parse_apploi(url: str):
    """Return (company_token, job_id) from any canonical Apploi URL."""
    parsed = urlparse(url)
    if parsed.netloc.lower() != HOST:
        return None
    segments = [s for s in parsed.path.split("/") if s]

    if len(segments) >= 2 and segments[0] == "jobs":
        return segments[1].lower(), None
    if len(segments) >= 4 and segments[0] == "job":
        # /job/{jobId}/{companyToken}/{slug}
        return segments[2].lower(), segments[1]
    return None

print(parse_apploi("https://apply-jobs.apploi.com/job/531470/lincoln-park/dietary-porter"))
# ('lincoln-park', '531470')

Collect every job link from the board

The board is a single server-rendered page with no pagination — every open vacancy is already in the HTML. Walk the anchors, keep only /job/ links whose company segment matches the board you asked for, and deduplicate on the numeric job ID.

Step 2: Collect every job link from the board
import requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin

def fetch_board(session, company_token: str) -> list[dict]:
    board_url = f"https://{HOST}/jobs/{company_token}"
    resp = session.get(board_url, headers={"Accept": "text/html"}, timeout=30)
    resp.raise_for_status()

    soup = BeautifulSoup(resp.text, "html.parser")
    listings, seen = [], set()
    for anchor in soup.select("a[href]"):
        parsed = parse_apploi(urljoin(f"https://{HOST}", anchor["href"]))
        if not parsed:
            continue
        token, job_id = parsed
        if job_id is None or token != company_token or job_id in seen:
            continue
        seen.add(job_id)
        listings.append({
            "id": job_id,
            "title": " ".join(anchor.get_text().split()),
            "url": urljoin(f"https://{HOST}", anchor["href"]).split("?")[0],
        })
    return listings

session = requests.Session()
listings = fetch_board(session, "lincoln-park")
print(f"{len(listings)} open jobs")

Read JobPosting JSON-LD from each detail page

Every Apploi detail page carries one application/ld+json JobPosting block holding the title, full description, employment type, posting dates and the facility address. That block is the canonical record — prefer it over scraping the rendered markup, which changes with theming.

Step 3: Read JobPosting JSON-LD from each detail page
import json
import time

def find_job_posting(html: str) -> dict | None:
    soup = BeautifulSoup(html, "html.parser")
    for tag in soup.find_all("script", type="application/ld+json"):
        try:
            data = json.loads(tag.string or "")
        except (json.JSONDecodeError, TypeError):
            continue
        for node in (data if isinstance(data, list) else [data]):
            if isinstance(node, dict) and node.get("@type") == "JobPosting":
                return node
    return None

def fetch_detail(session, listing: dict) -> dict | None:
    resp = session.get(listing["url"], headers={"Accept": "text/html"}, timeout=30)
    if resp.status_code in (404, 410):
        return None  # posting removed
    resp.raise_for_status()

    posting = find_job_posting(resp.text)
    if not posting:
        return None

    address = ((posting.get("jobLocation") or {}).get("address")) or {}
    return {
        "id": listing["id"],
        "title": posting.get("title") or listing["title"],
        "description_html": posting.get("description"),
        "employment_type": posting.get("employmentType"),
        "posted_at": posting.get("datePosted"),
        "closes_at": posting.get("validThrough"),
        "city": address.get("addressLocality"),
        "state": address.get("addressRegion"),
        "country": address.get("addressCountry"),
        "url": listing["url"],
        "apply_url": listing["url"],
    }

for listing in listings[:3]:
    print(fetch_detail(session, listing))
    time.sleep(0.25)

Resolve short jobs.apploi.com links

Apploi shares jobs.apploi.com/view/{jobId} links in job-board syndication and adverts. These carry no company token, so follow the redirect and read the company from the final canonical URL, keeping the original numeric ID as the external identifier.

Step 4: Resolve short jobs.apploi.com links
def resolve_short_link(session, url: str) -> dict | None:
    """Turn https://jobs.apploi.com/view/531470 into a board + job identity."""
    resp = session.get(url, headers={"Accept": "text/html"}, timeout=30,
                       allow_redirects=True)
    if not resp.ok:
        return None

    parsed = parse_apploi(str(resp.url))
    if not parsed:
        return None
    company_token, job_id = parsed
    original_id = [s for s in url.split("/") if s][-1]
    return {
        "company_token": company_token,
        "job_id": job_id or original_id,
        "board_url": f"https://{HOST}/jobs/{company_token}",
    }

print(resolve_short_link(session, "https://jobs.apploi.com/view/531470"))
Common issues
highThe board returns links belonging to a different company
Apploi boards can carry cross-promoted anchors from sibling facilities under the same operator. Always compare the company segment of /job/{jobId}/{companyToken}/{slug} against the board token you requested and drop anything that does not match, or one facility's snapshot will absorb another's jobs.
mediumA detail page has no JobPosting JSON-LD
Draft, expired or partially configured postings render the page shell without the structured block. Treat a missing JobPosting as a parse failure for that job rather than a removal, and retry it on the next run before deciding the vacancy is gone.
mediumThe public board and Apploi's partner API are not the same thing
Apploi's documented jobs API requires a vendor-issued x-api-key and is not open to the public. Everything shown here reads the same anonymous pages a candidate sees; do not expect key-only fields such as pipeline status or applicant data to appear in the JSON-LD.
lowShort /view/ links break tenant attribution
jobs.apploi.com/view/{id} URLs contain no company token, so a naive parse assigns the job to no board at all. Follow the redirect to apply-jobs.apploi.com and take the company from the final URL before writing the record.
Best practices
  1. 1Deduplicate on the numeric job ID from /job/{jobId}/ — titles repeat across shifts
  2. 2Reject any anchor whose company segment differs from the board you requested
  3. 3Read the JobPosting JSON-LD rather than the themed markup, which varies per employer
  4. 4Follow jobs.apploi.com/view/ redirects to recover the owning company board
  5. 5Throttle to ~250ms between requests and keep concurrent detail fetches at three
  6. 6Re-check a missing JSON-LD block on the next run before marking a job closed
Or skip the complexity

One endpoint. All Apploi jobs. No scraping, no sessions, no maintenance.

Get API access
cURL
curl "https://connect.jobo.world/api/jobs?sources=apploi" \
  -H "X-Api-Key: YOUR_KEY"
Developer tools

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.

Ready to integrate

Access Apploi
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.

99.9%API uptime
<200msAvg response
50M+Jobs processed