(Shortened — every job carries all 25 fields of the Field reference.)
The X-Jobs-Remaining response header tells you how many jobs are left in this month's
allowance.
3. Page through all jobs
Keep requesting with the next_cursor of the previous page until has_more is false.
Use limit=100 (the maximum) to make the fewest requests.
Python
Code
import osimport timeimport requestsBASE = "https://api.jobs-database.de"session = requests.Session()session.headers["X-API-Key"] = os.environ["JOBS_API_KEY"]def all_jobs(limit: int = 100): cursor = None while True: params = {"limit": limit} if cursor: params["cursor"] = cursor r = session.get(f"{BASE}/v1/jobs", params=params, timeout=30) if r.status_code == 429 and "Retry-After" in r.headers: time.sleep(int(r.headers["Retry-After"])) # per-minute rate limit continue r.raise_for_status() page = r.json() yield from page["items"] if not page["has_more"]: return cursor = page["next_cursor"]for job in all_jobs(): print(job["id"], job["title"], job["organization"])
JavaScript (Node.js 18+)
Code
const BASE = "https://api.jobs-database.de";const headers = { "X-API-Key": process.env.JOBS_API_KEY };async function* allJobs(limit = 100) { let cursor = null; while (true) { const url = new URL("/v1/jobs", BASE); url.searchParams.set("limit", String(limit)); if (cursor) url.searchParams.set("cursor", cursor); const res = await fetch(url, { headers }); if (res.status === 429 && res.headers.has("Retry-After")) { // per-minute rate limit await new Promise((r) => setTimeout(r, Number(res.headers.get("Retry-After")) * 1000)); continue; } if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`); const page = await res.json(); yield* page.items; if (!page.has_more) return; cursor = page.next_cursor; }}for await (const job of allJobs()) { console.log(job.id, job.title, job.organization);}
A 429withoutRetry-After means the monthly allowance is used up; waiting a minute will
not help. See Errors & limits.
Call the API from your server or script, not from JavaScript running in a web page: the API
does not send CORS headers, and a key in browser code is visible to every visitor.