Skip to main content

The job object and its id

Search, the feeds, and company jobs all return the same job object. Its id is a stable UUID, assigned once and never reused. Upsert on id, and an edited posting updates your row instead of creating a duplicate. external_id, the posting’s ID on its source ATS or job board, is not globally unique, so don’t key on it (External ID). occupation places the job in a category › subcategory › occupation taxonomy, such as Healthcare › Nursing › Registered Nurse. It is null for unclassified jobs. Search can filter and facet on it; see Filter by occupation.

Two ways to read jobs

Page-based paging over a moving dataset can skip or repeat records; the feed’s cursor keeps records from shifting between pages mid-export.
See Pagination for both models and Sync a database for the end-to-end pattern. To pick filters from lists and see how many jobs they match before you write code, use the public Search Builder or Feed Builder page: each writes the request body and curl for you.

Freshness

Jobo checks every tracked career site daily for new and expired listings. The checks are spread across the day, so new jobs arrive continuously rather than in one batch. Run an incremental feed sync every 15–60 minutes; more often usually returns nothing new. For an incremental sync, send updated_after set to when your last successful run started, minus 15 minutes: the feed returns jobs created, updated, or re-indexed since then (Incremental sync). Store updated_at per job and skip the write when it hasn’t moved.

Expiry

POST /api/jobs/feed returns only active jobs. An expired job is not flagged; it stops appearing. If you only ever call the feed, you never see a removal.
Detect removals with GET /api/jobs/expired. It is free and returns job IDs only:
A sync that runs less often than weekly, or stalls for more than 7 days, silently accumulates dead rows that this endpoint can no longer report. There’s no way to ask “what expired 3 weeks ago.” Run the sweep on the same schedule as your incremental sync, with expired_since set to the start of your last successful run; see Handling deletions. If you miss the window, recover with a full re-sync: page through the whole feed again and treat any stored id that no longer appears as expired.

Sources

source on every job is the platform’s provider_id, such as greenhouse, workday or lever. Sources lists all 200+ ATS and job-board platforms. New ones are added regularly, so treat source as an open set.

Global inventory vs. managed job sources

Three feeds share the same batch shape and cursor semantics and differ in scope: A saved feed narrows its starting set by company and job conditions (occupation among them) and can exclude companies. See Managed job sources and Saved feeds for each feed’s filters and limits. To have Jobo write the jobs into your own database or search index instead, set up an outbound feed under Data Platform → Outbound Feed. It delivers All jobs or one saved feed, with no filters of its own.

Metering, briefly

Search and the feeds bill per delivered job, not per request. A page of 5 results costs less than a page of 100, and an empty page costs nothing. Plans, the shared pool of included jobs, the Unlimited plan, and the free endpoints are on Billing.

Developing without spending

Live and sandbox keys use the same host, https://connect.jobo.world; the key picks the environment.
  • A sandbox key (jbe_test_…) returns fictional jobs and companies in the real response shapes, never billed. It serves search, job and company lookups, and Auto Apply; the feeds, geocoding, and everything else need a live key.
  • With a live key, wire up against the free endpoints first. GET /api/companies/{id} needs no API key, so it is the cheapest connectivity check.
  • When you need live search or feed data, keep page_size and batch_size small: a page_size=5 request bills at most 5 jobs.

Next steps

Sync a database

Backfill, then incremental sync with expiry sweeps.

Search recipes

Working filter combinations, facets, and field selection.

Sandbox

Fictional jobs in the real response shapes, never billed.

Client libraries

Official Python, Node.js, and .NET clients.