We found no public Hiring.cafe API or developer documentation. To get its jobs as JSON, use our Hiring.cafe API. One search call returns a page of 40 companies and their jobs, and the script below saved 632 jobs to CSV in 5 calls.
What we checked on Hiring.cafe
Hiring.cafe is a job search site that lists jobs from employers' own careers sites. When we checked, /developers, /api and /docs on its site returned a 404, and none of the 182 links on its home page or the entries in its sitemap index pointed to API documentation. Web searches turned up third-party scrapers only. A private arrangement wouldn't show up in those checks, so if you need an official feed, ask Hiring.cafe.
Hiring.cafe jobs with ToolzerHub
We make ToolzerHub. Our Hiring.cafe API reads the jobs a search on Hiring.cafe shows. It has two routes, each a GET with the x-api-key header at 1 credit a call:
/v1/hiringcafe/search?query=...returns one page withtotal,company_countand the jobs. Optional filters:location,workplace,commitment,seniority,posted_within,sort(relevance,newest,oldest,salary_highand others) andpage, up to page 250./v1/hiringcafe/job?job_id_or_url=...takes ajob_idor a hiringcafe.com job link and returns the description as the employer published it, pay, requirements, benefits mentioned, company facts and the link to apply on the employer's site.
export TOOLZERHUB_API_KEY=your_key
curl -G -H "x-api-key: $TOOLZERHUB_API_KEY" \
--data-urlencode "query=python developer" \
--data-urlencode "location=Austin, TX" \
"https://api.toolzerhub.com/v1/hiringcafe/search"
The first job in data.results, trimmed:
{
"job_id": "kbzr5bitoaxy7pu7",
"title": "Senior Python Developer",
"company": { "name": "Charles Schwab" },
"location": "Austin, Texas, United States",
"workplace": "onsite",
"commitment": ["full_time"],
"seniority": "senior",
"salary": { "min": 135000, "max": 162000, "currency": "USD", "period": "yearly" },
"skills": ["Python", "Google Cloud Platform (GCP)", "Cloud Run", "Docker"],
"posted_at": "2026-09-02T12:00:00.000Z"
}
page_size counts companies, not jobs, and each company brings up to 4 jobs.
Save Hiring.cafe jobs to CSV
The script pages through one search, keeps each job once and writes one row per job with company, place, workplace type, seniority, pay and posting time. Save it as hiringcafe_jobs.py and install requests (pip install requests). Pass - as the location to search every country.
import csv
import os
import sys
import requests
API = "https://api.toolzerhub.com/v1/hiringcafe/search"
HEADERS = {"x-api-key": os.environ["TOOLZERHUB_API_KEY"]}
def search(query, location=None, pages=3, sort="newest"):
seen = set()
for page in range(1, pages + 1):
params = {"query": query, "sort": sort, "page": page}
if location:
params["location"] = location
response = requests.get(API, headers=HEADERS, params=params, timeout=60)
response.raise_for_status()
body = response.json()["data"]
for job in body["results"]:
if job["job_id"] not in seen:
seen.add(job["job_id"])
yield job
if not body["has_more"]:
break
def main():
query = sys.argv[1]
location = sys.argv[2] if len(sys.argv) > 2 and sys.argv[2] != "-" else None
pages = int(sys.argv[3]) if len(sys.argv) > 3 else 3
fields = ["job_id", "title", "company", "location", "workplace", "commitment",
"seniority", "pay_min", "pay_max", "currency", "period", "posted_at",
"apply_url"]
with open("hiringcafe_jobs.csv", "w", newline="", encoding="utf-8") as out:
writer = csv.DictWriter(out, fieldnames=fields)
writer.writeheader()
count = 0
for job in search(query, location, pages):
salary = job["salary"]
writer.writerow({
"job_id": job["job_id"],
"title": job["title"],
"company": job["company"]["name"],
"location": job["location"],
"workplace": job["workplace"],
"commitment": "; ".join(job["commitment"]),
"seniority": job["seniority"],
"pay_min": salary["min"],
"pay_max": salary["max"],
"currency": salary["currency"],
"period": salary["period"],
"posted_at": job["posted_at"],
"apply_url": job["apply_url"],
})
count += 1
print(f"saved {count} jobs to hiringcafe_jobs.csv")
if __name__ == "__main__":
main()
python hiringcafe_jobs.py "python developer" - 5 saved 632 jobs in 5 calls, and python hiringcafe_jobs.py "python developer" "Austin, TX" 5 saved 450.
What the saved pages showed
A page holds a different number of jobs each time: six saved pages held 114, 101, 115, 137, 111 and 82, with page_size 40 on every one. In the default 3-month window, "python developer" matched 127,435 jobs at 15,433 companies worldwide and 2,396 for "Austin, TX".
Pay is only what a posting lists. A job counts below as having a pay figure when salary.min or salary.max is not null.
| Search, newest first, 5 calls | Jobs | With a pay figure | Hourly or monthly |
|---|---|---|---|
| python developer, worldwide | 632 | 375 | 33 |
| python developer, Austin, TX | 450 | 271 | 22 |
Check currency before comparing pay: of the 375 worldwide figures, 313 are yearly in USD. salary.yearly_min and yearly_max give each figure on a yearly basis.
sort changes what you get. On the first worldwide page, 80 of 114 titles sorted by relevance contain "python", against 0 of 137 sorted by newest, though Python is in the skills of all 137. The pay share differs too: 34 of 114 jobs on the relevance page, 98 of 137 on the newest page.
That first newest page is grouped by company, not strictly by date: 31 of its 40 companies hold jobs from more than one day, and its oldest job is 72 days old. These patterns come from this one search. Sort by posted_at yourself if you need strict order.
What it costs
The 632-job export took 5 credits, and a full posting is 1 more credit each. The 100 free credits a month cover 20 exports like it; $19 buys 10,000 credits that never expire, and plans for higher volume cover more searches. Set your key and the first search is a CSV in under a minute.
For other job boards, see Upwork freelance jobs and Naukri job data.
We are not affiliated with Hiring.cafe.