Ats Jobs Feed
Pricing
from $1.00 / 1,000 jobs
Ats Jobs Feed
Bulk fetch jobs from 75+ ATS platforms with cursor-based pagination. Up to 1000 jobs per batch. Perfect for data pipelines, job boards & incremental syncs.
Pricing
from $1.00 / 1,000 jobs
Rating
5.0
(1)
Developer
Enrico
Maintained by CommunityActor stats
3
Bookmarked
46
Total users
7
Monthly active users
6 days ago
Last modified
Categories
Share
ATS Jobs Feed API — the bulk firehose for data pipelines: stream Jobo's entire index of 3.9 million+ live jobs across 100+ ATS platforms with cursor pagination, at up to 1,000 jobs per batch and 100,000 jobs per run. This is not a keyword-search tool (that's ATS Jobs API) — it's the fastest way to get the whole normalized, daily-verified inventory into your warehouse. Open the actor, hit Try for free, and run the default input (one 500-job batch) — no code or API key required.
What does ATS Jobs Feed do?
- Streams up to 1,000 jobs per batch with cursor pagination — versus 100 per page on the search actors
- Pulls up to 100,000 jobs in a single run (
batch_size×max_batches), looping batches automatically and stopping early when the feed is exhausted - Covers all 100+ ATS platforms in one feed — or scope with
sources, structuredlocations, andwork_models - Resumable: every completed run writes its final cursor to the
FEED_METADATAkey-value record, so the next run picks up exactly where this one stopped - Built for incremental syncs — schedule it daily with
posted_after: "1 day ago"for cheap deltas instead of full re-exports - Returns the same normalized, AI-enriched job records as every Jobo actor: de-duplicated, geocoded locations, USD-normalized salaries, typed skills, work-authorization signals
- Optionally attaches the full company profile with
include_company_details— a cross-batch cache fetches each unique company once per run - Exports to JSON, CSV, or Excel, and plugs into schedules, webhooks, Zapier, Make, and the Apify API
Which ATS platforms are covered?
The provider catalog is maintained by Jobo's scraper registry, so newly supported
platforms appear without an actor schema update. Leave sources empty to stream
all indexed jobs, or pass canonical provider IDs such as
["greenhouse", "lever", "ashby"] to scope a run.
Authentication and source visibility
You never need to provide a Jobo API key. When you run the actor in the Apify
Console, Apify handles authentication for you. When you call it through the
Apify API or an Apify client, supply only your own Apify token in the normal
token parameter or client configuration.
The actor's source files are not published. Its publisher-managed Jobo
credential is stored as an encrypted Apify Secret and injected only while the
actor runs. The credential value is absent from actor inputs, dataset output,
FEED_METADATA, source definitions, public build metadata, and logs. It is not
a customer credential and there is no Jobo key to copy, configure, or rotate.
How does cursor pagination work?
The feed uses opaque cursors. The first call omits cursor; each response returns next_cursor and has_more — pass next_cursor back to fetch the next batch:
Request → {batch_size: 1000}Response → {jobs: [...1000 rows], next_cursor: "abc123...", has_more: true}Request → {batch_size: 1000, cursor: "abc123..."}Response → {jobs: [...300 rows], next_cursor: null, has_more: false}
The actor runs this loop for you — up to max_batches times per run, stopping early when has_more comes back false — and writes the final cursor to the FEED_METADATA key in the run's key-value store so a follow-up run can resume.
After a run completes in the Apify Console, open the run and select Output →
Feed Metadata. Copy last_cursor into the next run's Pagination Cursor
input. Also check has_more: when it is false, the feed is exhausted and
last_cursor is null.
For API-driven runs, fetch the same run-specific record directly (replace
<RUN_ID> with the id returned when you started the run):
GET https://api.apify.com/v2/actor-runs/<RUN_ID>/key-value-store/records/FEED_METADATA?token=<YOUR_APIFY_TOKEN>
The synchronous run-sync-get-dataset-items endpoint returns dataset items —
the jobs — only. It does not include FEED_METADATA or the next cursor in its
JSON response. Use a normal actor run plus the endpoint above when you need to
continue into another run.
How much does it cost?
This actor uses pay-per-result pricing: you pay a fixed rate per job record returned — the current rate is in the pricing box on this page. There are no separate compute, proxy, or storage charges, and a run never returns more than batch_size × max_batches rows, so spend is fully predictable. Apify's free plan includes enough credit to pull thousands of jobs, so you can evaluate the full dataset before paying anything.
How do I run a full export?
- Open the actor and click Try for free — you'll need a free Apify account.
- Smoke-test with the defaults — one batch of 500 jobs (
batch_size: 500,max_batches: 1) lets you inspect the record shape cheaply. - Scope the feed (optional): pick
sources, structuredlocations,work_models, or aposted_afterwindow. Rememberbatch_size×max_batchesis your spend ceiling. - Scale up and Start —
batch_size: 1000,max_batches: 100pulls up to 100,000 jobs in one run; the actor loops batches automatically and stops when the feed reports no more pages. - Export or resume — download JSON, CSV, or Excel from the Output tab, then open Output → Feed Metadata and copy
last_cursorinto the next run's Pagination Cursor field.
⬇️ Input
| Parameter | Type | Description |
|---|---|---|
batch_size | integer | Jobs per batch, 1–1,000 (default 500). |
max_batches | integer | Batches to pull this run, 1–100 (default 1). |
cursor | string | Opaque cursor from a previous run's FEED_METADATA. Omit to start from the beginning. |
locations | array | Structured location filters — {country, region?, city?} objects; jobs match ANY entry. A bare string is treated as a country. |
sources | array | ATS slugs to include (e.g. ["greenhouse", "lever"]). Empty = all 100+. |
work_models | array | remote, hybrid, onsite. |
posted_after | string | ISO 8601 (2026-01-01) or relative (1 day ago) — the key to incremental syncs. |
include_company_details | boolean | Attach the full enriched company profile; a cross-batch cache fetches each unique company once per run (default false). |
Note the locations format: unlike the search actors, which take free-text location strings and geocode them server-side, the feed takes structured objects so filtering stays exact at bulk scale:
"locations": [{ "country": "United States" },{ "country": "Germany", "region": "Bavaria" },{ "country": "United Kingdom", "city": "London" }]
The full input schema with defaults is on this page's Input schema tab.
⬆️ Output example
Results land in the dataset under two views: Job Feed (all sources) (one row per job) and Company details (populated when include_company_details is on). Every row is the same normalized record shape as ATS Jobs API and the single-ATS actors — the source field carries the slug of the ATS each job came from (here "greenhouse"; a feed batch mixes all the platforms you include). A typical record:
{"id": "f0f6a7d0-c667-48f7-95bc-a91f172e2d6d","title": "Software Engineer","normalized_title": "Software Engineer","summary": "Design and develop software for capital equipment and medical devices used by cardiac surgeons and electrophysiologists…","company": {"id": "6647fb14-d420-434a-a332-9c972016b9b0","name": "AtriCure","website": "https://atricure.com","logo_url": "https://images.jobo.world/logos/atricure.jpg","industries": ["Medical Devices & Equipment"],"details_url": "https://connect.jobo.world/api/companies/6647fb14-d420-434a-a332-9c972016b9b0"},"locations": [{"location": "Minneapolis, MN","city": "Minneapolis","region": "Minnesota","country": "United States","latitude": 44.9772995,"longitude": -93.2654692}],"compensation": { "min": 71036, "max": 104186, "currency": "USD", "period": "yearly" },"employment_type": "Full-time","workplace_type": "On-site","experience_level": "Mid Level","qualifications": {"must_have": {"education": ["Bachelor's degree in Systems Engineering, Electrical Engineering, or Computer Engineering"],"skills": [{ "name": "C", "type": "hard" },{ "name": "C++", "type": "hard" },{ "name": "Software Development Methodologies", "type": "hard" }]},"preferred": {"skills": [{ "name": "Rust", "type": "hard" },{ "name": "Python", "type": "hard" }]}},"is_work_auth_required": true,"listing_url": "https://job-boards.greenhouse.io/atricure/jobs/4309998009","apply_url": "https://job-boards.greenhouse.io/atricure/jobs/4309998009#app","source": "greenhouse","date_posted": "2026-07-09T13:47:14Z","description": "…full job description, HTML stripped…"}
How do I resume and sync incrementally?
Every successful run writes a FEED_METADATA record to its key-value store.
In the Console, open the completed run and choose Output → Feed Metadata:
{"total_jobs": 100000,"batches_processed": 100,"last_cursor": "eyJsYXN0X2lkIjoi…","has_more": true}
last_cursor is only set while has_more is true; once the feed is exhausted it's null and you're done.
From the Apify API, read the same record without first resolving a key-value store ID:
GET https://api.apify.com/v2/actor-runs/<RUN_ID>/key-value-store/records/FEED_METADATA?token=<YOUR_APIFY_TOKEN>
Worked example — a multi-run full export. Run 1 starts from the top:
{ "batch_size": 1000, "max_batches": 100 }
Run 1 finishes with has_more: true and a last_cursor in FEED_METADATA. Run 2 carries that cursor over:
{"batch_size": 1000,"max_batches": 100,"cursor": "eyJsYXN0X2lkIjoi…"}
Repeat until has_more comes back false.
Daily incremental sync. Create an Apify Schedule that runs this actor every 24 hours with:
{"batch_size": 1000,"max_batches": 100,"posted_after": "1 day ago"}
Each scheduled run then pulls only jobs posted since the previous one — far cheaper than re-paginating the full feed.
What can you expect from a run?
- Hard ceiling: 100,000 jobs per run — 100
max_batches× 1,000batch_size. For more, chain runs by passinglast_cursoras the next run'scursor. - Pacing: the actor waits 0.5 seconds between batches to keep the feed healthy.
- On a 503, the actor honors the API's
Retry-Afterheader and retries automatically; if it persists, check jobo.world/status. - Cursors are opaque — pass them back exactly as returned; don't construct or edit them. A stale cursor from an old run may be rejected — omit it to restart from the beginning.
- No keyword, salary, or skills filters — the feed is a firehose by design. For search and faceted filtering, use ATS Jobs API.
- Freshness: every listing is re-verified daily; expired jobs are removed within 24 hours of disappearing from the source board.
Integrations, API & MCP
Everything on the Apify platform works out of the box: schedules (hourly/daily/weekly runs), webhooks on run completion, and one-click integrations with Zapier, Make, n8n, Slack, Google Sheets, and Google Drive.
Prefer code? Call this actor as a bulk jobs feed API from Python or JavaScript with the Apify API clients — start a run, wait for it, and page through the dataset in a few lines (ready-made snippets are in the API section of this page). AI agents can run it through the Apify MCP server, which exposes this actor as a tool.
Use cases
| Who | What for |
|---|---|
| Data platforms | Sync millions of normalized jobs into a warehouse or lakehouse for analytics |
| Job boards | Backfill and refresh a full job index with cross-ATS coverage |
| Search infrastructure | Build a custom job search engine on top of the raw feed |
| HR tech | Market-intel pipelines fed by bulk daily syncs |
| AI training | Job-data corpora for embeddings, fine-tunes, and classifiers |
| Competitive intel | Track hiring velocity across companies and sectors at full-market scale |
❓ FAQ
Should I use this actor or ATS Jobs API?
Use ATS Jobs API for filtered, paginated queries — keyword search, salary and skills filters, up to 100 pages × 100 results. Use this actor for bulk download and sync: cursor pagination, 1,000 jobs per batch, built for ETL pipelines and warehouses.
How fast is it? What's the maximum throughput?
One run pulls up to 100,000 jobs (batch_size: 1000 × max_batches: 100), with a 0.5-second pause between batches. For the full index, chain runs — each run's FEED_METADATA hands the next one its starting cursor.
How do I resume a long export?
Open the previous run's Output → Feed Metadata, copy last_cursor, and pass it as cursor in the next run. API callers can GET /v2/actor-runs/<RUN_ID>/key-value-store/records/FEED_METADATA. When has_more is false, you've reached the end. The synchronous dataset-items response contains jobs only, not the cursor.
Can batches overlap or skip jobs?
Within a run, consecutive batches never overlap — the cursor encodes the exact feed position. Across resumed runs the cursor picks up where you left off, but the index is live: jobs added or expired in between follow the daily refresh.
Are duplicate listings removed?
Yes. Jobo de-duplicates by company + canonical title + listing URL before results are returned, so cross-posted duplicates of the same role are merged.
How fresh is the data?
New jobs are indexed within 24 hours of appearing on any of the 100+ platforms; every listing is re-verified daily and removed within 24 hours of expiring.
Where can I check if the API behind this actor is up?
At jobo.world/status — the live status page for the Jobo Connect API that powers every Jobo actor.
⚖️ Is it legal to scrape ATS job listings?
Yes — this actor only extracts publicly posted job listings, the content employers publish specifically to be found and shared. It does not collect private user data. Note that scraped results can incidentally contain personal data (e.g., a recruiter's name in a job description); personal data is protected by the GDPR and similar regulations, so only process it with a legitimate reason and consult a lawyer if unsure. Read more in Apify's guide to the legality of web scraping.
All ATS names are trademarks of their respective owners. This actor is an independent product and is not affiliated with, endorsed by, or sponsored by any of them.
🔗 Related actors
| Actor | Best for |
|---|---|
| ATS Jobs API | Search 100+ ATS platforms in one call |
| AI Deep Job Search | Describe your ideal job in plain English, get AI-scored matches |
| Greenhouse Jobs Scraper | 175,000+ jobs from tech companies on Greenhouse |
| Workday Jobs Scraper | 850,000+ jobs from Fortune 500 employers on Workday |
| Lever Jobs Scraper | 75,000+ jobs from VC-backed startups on Lever |
| Crunchbase Company Lookup | Funding, leadership, and tech-stack data for any company |
About Jobo & support
Jobo builds job-data infrastructure: a normalized, daily-verified index of jobs scraped directly from company ATS boards, powering job boards, AI agents, and HR-tech products.
- Questions or bugs? Open a ticket on this actor's Issues tab — issues are answered within hours.
- Website: jobo.world · Enterprise API: jobo.world/enterprise · API status: jobo.world/status
- Email: enrico@jobo.world