Access millions of job listings, geocode locations, and automate job applications — all from a single API.
| Sub-client | Property | Description |
|---|---|---|
| Jobs Feed | client.feed |
Bulk job feed with cursor-based pagination (45+ ATS) |
| Jobs Search | client.search |
Full-text search with location, remote, and source filters |
| Locations | client.locations |
Geocode location strings into structured coordinates |
| Auto Apply | client.auto_apply |
Automate job applications with form field discovery |
Both sync (JoboClient) and async (AsyncJoboClient) are included.
Get your API key → enterprise.jobo.world/api-keys
pip install jobo-enterprisefrom jobo_enterprise import JoboClient
with JoboClient(api_key="your-api-key") as client:
# Search for jobs
results = client.search.search(q="software engineer", location="San Francisco")
for job in results.jobs:
print(f"{job.title} at {job.company.name}")
# Geocode a location
geo = client.locations.geocode("London, UK")
print(f"{geo.locations[0].display_name}: {geo.locations[0].latitude}, {geo.locations[0].longitude}")client = JoboClient(api_key="your-api-key")Bulk-sync millions of active jobs using cursor-based pagination.
from jobo_enterprise import LocationFilter
response = client.feed.get_jobs(
locations=[
LocationFilter(country="US", region="California"),
LocationFilter(country="US", city="New York"),
],
sources=["greenhouse", "workday"],
is_remote=True,
batch_size=1000,
)
print(f"Got {len(response.jobs)} jobs, has_more={response.has_more}")for job in client.feed.iter_jobs(batch_size=1000, sources=["greenhouse"]):
save_to_database(job)from datetime import datetime, timedelta
expired_since = datetime.utcnow() - timedelta(days=1)
for job_id in client.feed.iter_expired_job_ids(expired_since=expired_since):
mark_as_expired(job_id)Full-text search with filters and page-based pagination.
results = client.search.search(
q="data scientist",
location="New York",
sources="greenhouse,lever",
remote=True,
page_size=50,
)
print(f"Found {results.total} jobs across {results.total_pages} pages")results = client.search.search_advanced(
queries=["machine learning engineer", "ML engineer", "AI engineer"],
locations=["San Francisco", "New York", "Remote"],
sources=["greenhouse", "lever", "ashby"],
is_remote=True,
page_size=100,
)for job in client.search.iter_jobs(
queries=["backend engineer"],
locations=["London"],
page_size=100,
):
print(f"{job.title} — {job.company.name}")Geocode location strings into structured data with coordinates.
result = client.locations.geocode("San Francisco, CA")
for location in result.locations:
print(f"{location.display_name}: {location.latitude}, {location.longitude}")Automate job applications with form field discovery and filling.
from jobo_enterprise import FieldAnswer
# Start a session
session = client.auto_apply.start_session(job.apply_url)
print(f"Provider: {session.provider_display_name}")
print(f"Fields: {len(session.fields)}")
# Fill in fields
answers = [
FieldAnswer(field_id="first_name", value="John"),
FieldAnswer(field_id="last_name", value="Doe"),
FieldAnswer(field_id="email", value="john@example.com"),
]
result = client.auto_apply.set_answers(session.session_id, answers)
if result.is_terminal:
print("Application submitted!")
# Clean up
client.auto_apply.end_session(session.session_id)Every sub-client has an async equivalent via AsyncJoboClient:
import asyncio
from jobo_enterprise import AsyncJoboClient
async def main():
async with AsyncJoboClient(api_key="your-api-key") as client:
# Search
results = await client.search.search(q="frontend developer")
# Auto-paginated feed
async for job in client.feed.iter_jobs(batch_size=500):
await process_job(job)
# Geocode
geo = await client.locations.geocode("Berlin, DE")
asyncio.run(main())from jobo_enterprise import (
JoboAuthenticationError,
JoboRateLimitError,
JoboValidationError,
JoboServerError,
JoboError,
)
try:
results = client.search.search(q="engineer")
except JoboAuthenticationError:
print("Invalid API key")
except JoboRateLimitError as e:
print(f"Rate limited. Retry after {e.retry_after}s")
except JoboValidationError as e:
print(f"Bad request: {e.detail}")
except JoboServerError:
print("Server error — try again later")| Category | Sources |
|---|---|
| Enterprise ATS | workday, smartrecruiters, icims, successfactors, oraclecloud, taleo, dayforce, csod, adp, ultipro, paycom |
| Tech & Startup | greenhouse, lever_co, ashby, workable, workable_jobs, rippling, polymer, gem, pinpoint, homerun |
| Mid-Market | bamboohr, breezy, jazzhr, recruitee, personio, jobvite, teamtailor, comeet, trakstar, zoho |
| SMB & Niche | gohire, recooty, applicantpro, hiringthing, careerplug, hirehive, kula, careerpuck, talnet, jobscore |
| Specialized | freshteam, isolved, joincom, eightfold, phenompeople |
| Parameter | Default | Description |
|---|---|---|
api_key |
required | Your API key |
base_url |
https://jobs-api.jobo.world |
API base URL |
timeout |
30.0 |
Request timeout (seconds) |
httpx_client |
None |
Custom httpx client |
- Build a job board — Search and display jobs from 45+ ATS platforms
- Job aggregator — Bulk-sync millions of listings with the feed endpoint
- ATS data pipeline — Pull jobs from Greenhouse, Lever, Workday, etc. into your data warehouse
- Recruitment tools — Power candidate-facing job search experiences
- Auto-apply automation — Automate job applications at scale
- Location intelligence — Geocode and normalize job locations
- Website — jobo.world/enterprise
- Get API Key — enterprise.jobo.world/api-keys
- GitHub — github.com/Prakkie91/jobo-python
- PyPI — pypi.org/project/jobo-enterprise
MIT — see LICENSE.
