HireHive Jobs API.
Pull every open role from small and international employers in a single JSON call, complete with multilingual descriptions, structured pay tiers, and country data, no HTML parsing required.
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.
What's in every response.
Data fields, real-world applications, and the companies already running on HireHive.
- Full HTML & Plain-Text Descriptions
- Structured Compensation Tiers
- Department & Category
- Employment & Experience Type
- Language & Locale Codes
- Country, City & Apply URL
- 01International Talent Sourcing
- 02Multilingual Job Boards
- 03SMB Hiring Trend Analysis
- 04Pay-Range Benchmarking
- 05Job Board Aggregation
How to scrape HireHive.
Step-by-step guide to extracting jobs from HireHive-powered career pages—endpoints, authentication, and working code.
# HireHive URL patterns:
# Job board: https://{company}.hirehive.com
# Jobs API v2: https://{company}.hirehive.com/api/v2/jobs
company = "jungle"
api_url = f"https://{company}.hirehive.com/api/v2/jobs"import requests
company = "jungle"
url = f"https://{company}.hirehive.com/api/v2/jobs"
response = requests.get(url, params={"page_size": 100}, timeout=10)
response.raise_for_status()
data = response.json()
meta = data.get("meta", {})
print(f"Found {meta.get('total_items')} jobs across {meta.get('total_pages')} pages")for job in data["items"]:
hosted_url = job.get("hosted_url") or f"https://hirehive.com/jobs/{job['id']}"
country = (job.get("country") or {}).get("name")
print({
"id": job["id"],
"title": job.get("title"),
"location": job.get("location"),
"country": country,
"category": (job.get("category") or {}).get("name"),
"employment_type": (job.get("type") or {}).get("name"),
"description_html": (job.get("description") or {}).get("html", "")[:200],
"description_text": (job.get("description") or {}).get("text", "")[:200],
"apply_url": hosted_url,
"published_date": job.get("published_date"),
})import requests
import time
def fetch_all_hirehive_jobs(company: str, page_size: int = 100) -> list:
base_url = f"https://{company}.hirehive.com/api/v2/jobs"
all_jobs = []
page = 1
while True:
params = {"page": page, "page_size": page_size}
response = requests.get(base_url, params=params, timeout=10)
response.raise_for_status()
data = response.json()
all_jobs.extend(data.get("items", []))
if not data.get("meta", {}).get("has_next_page"):
break
page += 1
time.sleep(0.2) # ~200ms between requests, one at a time
return all_jobs
jobs = fetch_all_hirehive_jobs("jungle")
print(f"Total jobs fetched: {len(jobs)}")for job in data["items"]:
tier = (job.get("compensation_tiers") or [{}])[0]
record = {
"external_id": job["id"],
"title": job.get("title"),
"department": (job.get("category") or {}).get("name"),
"employment_type": (job.get("type") or {}).get("type"), # e.g. "FullTime"
"experience": (job.get("experience") or {}).get("name"),
"language": (job.get("language") or {}).get("code"), # e.g. "es-ES"
"salary": job.get("salary"), # free-text, often null
"pay_min": tier.get("min_value"),
"pay_max": tier.get("max_value"),
"currency": tier.get("currency_code"),
}
print(record)HireHive publishes no public directory of boards. Discover subdomains by following 'hirehive.com' links from company careers pages, job aggregators, and postings, then reuse the subdomain as the company identifier.
A subdomain that is not a live HireHive board returns 404. Treat a 404 from /api/v2/jobs as 'company not found' and skip it rather than retrying.
Boards can return 401 (auth required), 403 (blocked), or 429 (too many requests). Back off and retry with a delay on 403/429, and keep to a single request at a time.
A few jobs omit hosted_url. Fall back to constructing a link from the id (https://hirehive.com/jobs/{id}) so every record keeps a working apply URL.
Titles, descriptions, and category names are returned in the board's own language. Read language.code (e.g. 'es-ES') to detect and route non-English postings before downstream processing.
The salary field is free-text and often null, and compensation_tiers can be empty. Default these to null and read pay from the first tier's min_value/max_value/currency_code when present.
- 1Call /api/v2/jobs once per company — it returns full descriptions, so no per-job detail fetch is needed
- 2Page with page_size=100 and stop when meta.has_next_page is false
- 3Pace requests ~200ms apart and keep concurrency to a single request per board
- 4Use description.html for formatted content and description.text for plain text
- 5Treat HTTP 404 as an inactive board and skip it instead of retrying
- 6Read language.code to detect non-English postings before downstream processing
One endpoint. All HireHive jobs. No scraping, no sessions, no maintenance.
Get API accesscurl "https://connect.jobo.world/api/jobs?sources=hirehive" \
-H "X-Api-Key: YOUR_KEY" Access HireHive
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.