Official Python client for the Jobo Enterprise API. Access millions of job listings from 45+ ATS platforms, geocode locations, and automate job applications. Organized by feature area: Feed, Search, Locations, and Auto Apply.
Project description
Jobo Enterprise — Python Client
Access millions of job listings, geocode locations, and automate job applications — all from a single API.
Features
| 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
Installation
pip install jobo-enterprise
Quick Start
from 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}")
Authentication
client = JoboClient(api_key="your-api-key")
Jobs Feed — client.feed
Bulk-sync millions of active jobs using cursor-based pagination.
Fetch a batch
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"],
work_models=["remote", "hybrid"],
batch_size=1000,
)
print(f"Got {len(response.jobs)} jobs, has_more={response.has_more}")
Auto-paginate all jobs
for job in client.feed.iter_jobs(batch_size=1000, sources=["greenhouse"]):
save_to_database(job)
Expired job IDs
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)
Jobs Search — client.search
Full-text search with filters and page-based pagination.
Simple search
from jobo_enterprise import WorkModel
results = client.search.search(
q="data scientist",
location="New York",
sources="greenhouse,lever",
work_model=WorkModel.REMOTE, # or just "remote"
min_salary_usd=120000,
page_size=50,
)
print(f"Found {results.total} jobs across {results.total_pages} pages")
Closed value sets. Parameters with a fixed set of accepted values ship as enums for discoverability —
WorkModel,EmploymentType,ExperienceLevel,CompensationPeriod, andSkillType. Each member subclassesstr, so passing the equivalent literal (e.g."remote") is always valid too.
Advanced search (typed filters & facets)
from jobo_enterprise import InclusionExclusionFilter, RangeFilter
results = client.search.search_advanced(
queries=["machine learning engineer", "ML engineer", "AI engineer"],
locations=["San Francisco", "New York"],
sources=["greenhouse", "lever", "ashby"],
work_models=["remote", "hybrid"],
skills=InclusionExclusionFilter(include=["python"], exclude=["php"]),
salary_usd=RangeFilter(min=150000),
include_facets=["work_model", "experience_level"],
page_size=100,
)
for facet, buckets in results.facets.items():
print(facet, [(b.key, b.count) for b in buckets])
Auto-paginate all results
for job in client.search.iter_jobs(
queries=["backend engineer"],
locations=["London"],
page_size=100,
):
print(f"{job.title} — {job.company.name}")
Companies — client.companies
Fetch fully enriched company profiles and list jobs scoped to a company.
company = client.companies.get(job.company.id)
print(company.name, company.website, company.industries)
# Jobs for a single company (paginated)
jobs = client.companies.get_jobs(job.company.id, page_size=50)
print(f"{jobs.total} jobs at {company.name}")
Locations — client.locations
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}")
Auto Apply — client.auto_apply
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 — `type` mirrors the FormFieldInfo.type of each field
answers = [
FieldAnswer(field_id="first_name", type="text", value="John"),
FieldAnswer(field_id="last_name", type="text", value="Doe"),
FieldAnswer(field_id="email", type="text", 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)
Profiles & one-shot run
from jobo_enterprise import AutoApplyProfileRequest
profile = client.auto_apply.create_profile(
AutoApplyProfileRequest(
name="Default",
first_name="John",
last_name="Doe",
email="john@example.com",
phone="+1-555-0100",
)
)
# Run the full flow end-to-end against the stored profile
run = client.auto_apply.run(profile.id, job.apply_url)
print(run.status, run.steps_completed, run.fields_filled)
Async Support
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())
Error Handling
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")
Supported ATS Sources (45+)
| 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 |
Configuration
| Parameter | Default | Description |
|---|---|---|
api_key |
required | Your API key |
base_url |
https://connect.jobo.world |
API base URL |
timeout |
30.0 |
Request timeout (seconds) |
httpx_client |
None |
Custom httpx client |
Use Cases
- 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
Links
- Website — jobo.world/enterprise
- Get API Key — enterprise.jobo.world/api-keys
- GitHub — github.com/Prakkie91/jobo-python
- PyPI — pypi.org/project/jobo-enterprise
License
MIT — see LICENSE.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file jobo_enterprise-3.0.0.tar.gz.
File metadata
- Download URL: jobo_enterprise-3.0.0.tar.gz
- Upload date:
- Size: 24.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c961e7c5fee8697e1a67d100bc3abdcf8f1bdbca12f24157823a77ba84c26b58
|
|
| MD5 |
54bd7f4cb03fe4b793da79ab971cea4c
|
|
| BLAKE2b-256 |
d1ac82b3f4e57fbf80d8ac2eb4e8a073d623d19e4365409e6fc9ce6cb2981a97
|
File details
Details for the file jobo_enterprise-3.0.0-py3-none-any.whl.
File metadata
- Download URL: jobo_enterprise-3.0.0-py3-none-any.whl
- Upload date:
- Size: 22.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
09bc662b8103e063d2daea3f8dd5488b81a6faf4da312249118b545792df617e
|
|
| MD5 |
84b731f600d265812fc89be0dcb86e94
|
|
| BLAKE2b-256 |
b7b051359be737d1fec3758c0c4ead12629ce3e662772f126630aca716ad03b4
|