All platforms

Recooty Jobs API.

Server-side rendered ATS platform for small businesses with HTML-based job boards and sitemap discovery support.

Recooty
Live
15K+jobs indexed monthly
<3haverage discovery time
1hrefresh interval
Companies using Recooty
Recooty Inc.Developer Bazaar TechnologiesProvanic
Developer tools

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 Recooty.

Data fields
  • SMB focus
  • Simple interface
  • HTML-based rendering
  • Sitemap discovery
  • JSON-LD structured data
  • Two domain support
Use cases
  1. 01SMB job monitoring
  2. 02Company discovery via sitemap
  3. 03HTML scraping workflows
  4. 04Structured data extraction
Trusted by
Recooty Inc.Developer Bazaar TechnologiesProvanic
DIY GUIDE

How to scrape Recooty.

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

HTMLbeginner~60 requests/minute recommended (Cloudflare protected)No auth

Discover companies from the sitemap

Recooty provides comprehensive sitemaps containing all job URLs across both domains. Use the sitemap to discover company slugs and active job listings efficiently.

Step 1: Discover companies from the sitemap
import requests
import xml.etree.ElementTree as ET
from urllib.parse import urlparse

def discover_companies_from_sitemap():
    """Extract unique company slugs from Recooty sitemap."""
    sitemap_url = "https://jobs.recooty.com/sitemap.xml"
    response = requests.get(sitemap_url, timeout=30)
    response.raise_for_status()

    root = ET.fromstring(response.content)
    companies = set()

    # Parse all URLs and extract company slugs
    for url in root.findall('.//{http://www.sitemaps.org/schemas/sitemap/0.9}loc'):
        path = urlparse(url.text).path
        parts = path.strip('/').split('/')
        if parts:
            companies.add(parts[0])

    print(f"Found {len(companies)} unique companies")
    return list(companies)

companies = discover_companies_from_sitemap()

Fetch the job listings page

Request the company's careers page to retrieve the HTML containing all job listings. Recooty uses server-side rendering with no API endpoints available.

Step 2: Fetch the job listings page
import requests
from bs4 import BeautifulSoup

def fetch_listings_page(company_slug: str, page: int = 1):
    """Fetch the HTML listings page for a company."""
    base_url = "https://careerspage.io"
    url = f"{base_url}/{company_slug}"

    if page > 1:
        url = f"{url}?page={page}"

    headers = {
        "User-Agent": "Mozilla/5.0 (compatible; JobScraper/1.0)"
    }

    response = requests.get(url, headers=headers, timeout=30)
    response.raise_for_status()

    return response.text

html = fetch_listings_page("recooty-inc")
print(f"Fetched {len(html)} bytes")

Parse job listings from HTML

Extract job data from the HTML using BeautifulSoup. Recooty structures jobs in card elements with semantic classes for title, location, and employment type.

Step 3: Parse job listings from HTML
from bs4 import BeautifulSoup

def parse_job_listings(html: str, company_slug: str):
    """Parse job listings from Recooty HTML."""
    soup = BeautifulSoup(html, 'html.parser')
    jobs = []

    # Find all job card containers
    job_cards = soup.select('div.pt-7.px-xl-9.bg-white.rounded')

    for card in job_cards:
        # Extract job title and URL
        title_link = card.select_one('h3 a.font-size-6.heading-default-color')
        if not title_link:
            continue

        title = title_link.get_text(strip=True)
        href = title_link.get('href', '')

        # Extract metadata from list items
        list_items = card.select('ul.list-unstyled li span')

        location = ""
        employment_type = ""
        experience = ""

        for i, item in enumerate(list_items):
            text = item.get_text(strip=True)
            if i == 0:
                location = text
            elif i == 1:
                employment_type = text
            elif i == 2:
                experience = text

        # Build full URL
        job_url = f"https://careerspage.io{href}" if href.startswith('/') else href

        jobs.append({
            'title': title,
            'location': location,
            'employment_type': employment_type,
            'experience_level': experience,
            'url': job_url,
        })

    return jobs

jobs = parse_job_listings(html, "recooty-inc")
print(f"Found {len(jobs)} jobs")

Extract job details and JSON-LD data

Fetch individual job pages to get full descriptions. Job detail pages include JSON-LD structured data following Google's JobPosting schema for reliable metadata extraction.

Step 4: Extract job details and JSON-LD data
import json
import requests
from bs4 import BeautifulSoup

def fetch_job_details(job_url: str):
    """Fetch and parse job details including JSON-LD structured data."""
    response = requests.get(job_url, timeout=30)
    response.raise_for_status()

    soup = BeautifulSoup(response.text, 'html.parser')

    # Extract JSON-LD structured data
    json_ld_data = None
    json_ld_script = soup.select_one('script[type="application/ld+json"]')

    if json_ld_script:
        try:
            json_ld_data = json.loads(json_ld_script.string)
        except json.JSONDecodeError:
            pass

    # Extract HTML description
    description_div = soup.select_one('div.company-profile')
    description = description_div.get_text(separator='\n', strip=True) if description_div else ""

    # Extract posted date from title attribute
    posted_date = None
    date_el = soup.select_one('p.font-size-4.text-gray[title]')
    if date_el:
        posted_date = date_el.get('title')

    job_details = {
        'title': json_ld_data.get('title') if json_ld_data else None,
        'description': description,
        'date_posted': json_ld_data.get('datePosted') or posted_date if json_ld_data else posted_date,
        'employment_type': json_ld_data.get('employmentType') if json_ld_data else None,
        'valid_through': json_ld_data.get('validThrough') if json_ld_data else None,
        'company': json_ld_data.get('hiringOrganization', {}).get('name') if json_ld_data else None,
        'apply_url': f"{job_url}/apply",
    }

    return job_details

details = fetch_job_details(jobs[0]['url'])
print(details)

Handle pagination

Recooty uses URL-based pagination with a query parameter. Check for pagination links to retrieve all jobs across multiple pages.

Step 5: Handle pagination
import requests
from bs4 import BeautifulSoup
import time

def scrape_all_jobs(company_slug: str, delay: float = 1.0):
    """Scrape all jobs from a company, handling pagination."""
    all_jobs = []
    page = 1

    while True:
        html = fetch_listings_page(company_slug, page)
        jobs = parse_job_listings(html, company_slug)

        if not jobs:
            break

        all_jobs.extend(jobs)

        # Check for next page
        soup = BeautifulSoup(html, 'html.parser')
        next_link = soup.select_one(f'a[href*="page={page + 1}"]')

        if not next_link:
            break

        page += 1
        time.sleep(delay)  # Rate limiting

    return all_jobs

def fetch_listings_page(company_slug: str, page: int = 1):
    base_url = "https://careerspage.io"
    url = f"{base_url}/{company_slug}"
    if page > 1:
        url = f"{url}?page={page}"

    response = requests.get(url, timeout=30)
    response.raise_for_status()
    return response.text

all_jobs = scrape_all_jobs("recooty-inc")
print(f"Total jobs found: {len(all_jobs)}")
Common issues
criticalNo API endpoints available

Recooty has no public JSON API. All data must be extracted via HTML scraping using BeautifulSoup or similar parsers. Use JSON-LD structured data when available for more reliable metadata extraction.

highSelectors break when templates change

Build parsers with multiple fallback selectors and monitor for failures. The JSON-LD structured data on detail pages is more stable than HTML selectors.

mediumCompany identifier discovery is manual

Use the sitemap at jobs.recooty.com/sitemap.xml to discover all company slugs. Parse URLs to extract unique company identifiers from the path structure.

lowURLs may contain query parameters

Strip query parameters when extracting job IDs or comparing URLs. Some sitemap URLs include tracking parameters like ?src=28 that should be removed.

mediumCloudflare protection may trigger

Implement delays between requests (1-2 seconds), use proper User-Agent headers, and handle 403/429 errors gracefully with exponential backoff.

lowEmpty job boards return no data

Handle companies with no active jobs gracefully. Check for empty results before processing and log these cases for monitoring.

Best practices
  1. 1Use sitemap parsing for efficient company discovery
  2. 2Parse JSON-LD structured data for reliable metadata on detail pages
  3. 3Implement 1-2 second delays between requests to avoid rate limiting
  4. 4Handle both jobs.recooty.com and careerspage.io domains
  5. 5Strip query parameters from URLs before extracting job IDs
  6. 6Use icon-based selectors (fa-location-dot, fa-briefcase) for sidebar metadata
Or skip the complexity

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

Get API access
cURL
curl "https://enterprise.jobo.world/api/jobs?sources=recooty" \
  -H "X-Api-Key: YOUR_KEY"
Ready to integrate

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

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