The job object and its id
Every endpoint that returns jobs — search, feed, company jobs — returns the same shape. id is a stable UUID assigned once and never reused, even as the rest of the posting changes underneath it. It’s the correct primary key for an upsert: write on id, and an edited posting updates your row instead of creating a duplicate.
See The job object for the full field reference rather than restating it here.
Two ways to read jobs
Search and feed cover different jobs-to-be-done. Picking the wrong one for your use case is the most common integration mistake.
If a person is reading the results on a screen, use search. If you’re mirroring the corpus into your own database, use the feed — it’s cheaper per job and, paired with a stable-scan cursor, immune to records shifting between pages as the underlying data changes mid-export. Deep page-based pagination over a moving dataset can skip or repeat records; cursor pagination can’t.
Freshness
Data refreshes continuously. For an incremental sync against the feed, 15–60 minutes is a healthy schedule — more frequent runs spend wallet credits without turning up much new data. Two timestamps matter, and they mean different things:created_at— when Jobo first ingested the job.updated_at— when the posting last changed.
updated_at per job and skip the write when the incoming value hasn’t moved. That turns a sync loop into a no-op for the vast majority of jobs on any given run.
created_at is exact ingestion time on the managed feed described below, under Global inventory vs. managed sources. On the main feed, it reports indexing time for jobs under 24 hours old, which can lag true ingestion slightly.Expiry
Detect removals with a separate call:GET /api/jobs/expired — see Pagination for its cursor mechanics. It enforces a maximum 7-day lookback — expired_since cannot be older than 7 days, and when omitted it defaults to just the last 24 hours.
The consequence is mechanical: a sync that runs less often than weekly, or that stalls for more than 7 days, will silently accumulate dead rows that this endpoint can no longer help you find. There’s no way to ask “what expired 3 weeks ago.”
Recovery is a full re-sync against /feed: page through the whole feed again, and treat any id still in your store that no longer appears as expired. See Sync a database for the sweep pattern and how to run it on the same schedule as your incremental sync so you never hit the 7-day wall.
Sources
Jobs are normalized from 106 ATS and job-board platforms into the one schema described above.source on every job is the platform’s provider_id — greenhouse, workday, lever, and so on. See Sources for the catalogue; it isn’t reproduced here because it changes as coverage expands.
Global inventory vs. managed sources
POST /api/jobs/feed draws from Jobo’s whole corpus — every job across all 106 sources. POST /api/jobs/feed/managed is a private, narrower feed scoped to a set of employers you nominate in the Jobo portal, rather than everything Jobo indexes. Same batch shape and cursor semantics as the main feed, different scope. See Sync a database for how the two interact in a sync loop.
Metering, briefly
Search and feed meter per delivered job, not per request — a page of 5 results costs less than a page of 100. Geocode is a flat per-lookup charge, refunded automatically on error.GET /api/jobs/{id}, GET /api/jobs/expired, and GET /api/companies/{id} are free.
This page won’t restate prices or the request lifecycle — see Billing for both.
Developing without spending
There’s no separate sandbox host for the main API — everything above runs againsthttps://connect.jobo.world. To build and test without running up a bill:
- Call the free endpoints while you’re wiring up the integration:
GET /api/jobs/{id},GET /api/jobs/expired,GET /api/companies/{id}. GET /api/companies/{id}needs no API key at all, so it’s the cheapest possible smoke test for connectivity.- When you do need search or feed, keep
page_sizeandbatch_sizesmall — metering is per delivered job, so apage_size=5request during development costs a fraction of a production-sized page.

