AI Jobs Scraper (aijobs.net) — ML & Data Roles
Pricing
Pay per event
AI Jobs Scraper (aijobs.net) — ML & Data Roles
Scrape AI, machine learning and data science jobs from aijobs.net: ML engineer, data scientist, MLOps, research scientist, more. Each record has title, company, location, remote flag, seniority, salary band, posted date and apply URL. Filter by keyword and location; company + description included.
Fetch machine learning jobs and data science jobs from aijobs.net — AI engineer, ML engineer, data scientist, MLOps, research scientist and more — with company, remote flag, salary bands (where disclosed) and seniority levels. Filter by keyword and location, and page past the first ~50 cards.
What AI jobs data does this scraper extract?
Each result is one flat JSON record per job posting:
| Field | Meaning |
|---|---|
id | Stable source-side identifier |
slug | URL slug segment of the posting |
title | Job title as posted |
company | Hiring company / organisation. Populated by default (includeCompany defaults to true) — the listing page never shows it, so it is fetched from each job's own detail page (one extra request per job). null only if you turn includeCompany off. |
location | Location / duty station (may include remote hints), or null |
isRemote | Boolean remote/onsite flag, derived from the card text (true when it carries a remote hint such as "Remote" or "work from home", else false) |
url | Direct link to the posting |
postedAt | Posting date/time, computed server-side as ISO-8601 (YYYY-MM-DD, or a full timestamp when the source text is second/minute/hour-precision, e.g. "3h ago") from the source's relative-age text. null when that text doesn't match a known pattern. |
postedAtText | The original relative-age text as shown by the source (e.g. "5d ago"), kept verbatim for transparency, or null |
seniority | Experience-level badge from the card: Entry-level, Mid-level, Senior-level or Executive-level, or null |
snippet | Short description excerpt (from the listing card, ~400 chars) |
description | Fuller JD text (Tasks / Perks / Skills / Education / Roles) assembled from the job's detail page, up to 5000 chars. Populated by default (the same detail-page fetch that fills company); null only when includeCompany is turned off |
salary | Raw salary-band text, e.g. "USD 80K-160K". Only ~half of postings disclose one; null otherwise |
salaryMin / salaryMax | Parsed band bounds (whole currency units, e.g. 80000), or null |
salaryCurrency | 3-letter currency code parsed from the badge, or null |
salaryPeriod | Pay period (year/month/hour) — always null; the source never labels which period the band covers |
How to scrape AI jobs with this Actor
- Click Try for free / Run — no login to the target site, no cookies, no proxies to configure.
- Adjust the input — narrow with
searchQuery(keyword) andlocation, raisemaxItemsto page past the first ~50 cards, or keep the defaults. - Run it and export the dataset as JSON, CSV or Excel, or read it over the API.
Run it from your own code:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("nomad-agent/ai-jobs-net-scraper").call(run_input={"maxItems": 50, "includeCompany": True})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item["title"], "—", item["company"], item["url"])
Or a single HTTP call that runs the Actor and returns items in one response:
curl -X POST \"https://api.apify.com/v2/acts/nomad-agent~ai-jobs-net-scraper/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>" \-H "Content-Type: application/json" \-d '{"maxItems": 50}'
Input
| Field | Type | Default | Notes |
|---|---|---|---|
searchQuery | string | — | Keyword filter (alias: keyword). Keeps only jobs whose card text contains every word you enter (case-insensitive), e.g. machine learning. Empty returns all. |
location | string | — | Location filter. Keeps only jobs whose location text contains this value (case-insensitive substring), e.g. Berlin, Germany, Remote. Empty returns all locations. |
maxItems | integer | 50 | How many listing cards to fetch. aijobs.net serves a "Load more" feed, so values above one page (~50) follow the pagination and fetch more cards, up to 300 (8 pages). Keyword/location filters are applied to the fetched cards, so the returned count may be lower. Set 0 to fetch just the first page (~50). |
includeCompany | boolean | true | The listing page never shows the company name — only the per-job detail page does. On by default: fetches that page (one extra request per job, no extra per-job price) to populate company and description. Turn off for a faster listing-only pull, in which case both stay null. |
euBias | boolean | false | When enabled, listings whose location or title hints at a European country or remote-EU are sorted to the top. Non-EU jobs are still returned; they just appear later. |
cacheTtlSeconds | integer | 1800 | (Advanced) Cache the page-1 fetch in the key-value store for this many seconds; re-runs within the window skip that call. Load-more pages (2+) are always fetched live. Set 0 to disable. |
Output example
Default run (includeCompany: true):
{"id": "200475","slug": "competitive-coder-remote","title": "Competitive Coder","company": "micro1","location": "Remote","isRemote": true,"url": "https://aijobs.net/job/competitive-coder-remote-200475/","postedAt": "2026-06-29","postedAtText": "5d ago","seniority": "Entry-level","snippet": "Competitive Coder USD 80K-160K C plus plus | Codeforces | Competitive programming ...","description": "Tasks: ... | Perks/Benefits: ... | Skills/Tech-stack: ... | Education: ... | Roles: ...","salary": "USD 80K-160K","salaryMin": 80000,"salaryMax": 160000,"salaryCurrency": "USD","salaryPeriod": null}
company and description come from each job's detail page, so they are populated by default (one extra HTTP request per job — the same fetch fills both, at no extra per-job price). Turn includeCompany off for a faster listing-only pull, in which case both are null. Roughly half of postings don't disclose a salary band at all; on those, salary, salaryMin, salaryMax and salaryCurrency are all null.
Pricing
Pay per event: $0.005 per Actor start and $0.002 per job returned.
100 jobs ≈ $0.205. No subscription, no rental — you pay only for what you fetch. Enabling includeCompany adds an extra request per job but does not change the per-job price.
Use cases
- AI-specialist job boards and newsletters
- Tracking ML-engineer demand and salaries
- Sourcing AI talent pipelines
- Feeding the ml-ai-dev-bundle with anchor data
FAQ
Is it legal to scrape AI jobs? This Actor reads only publicly available job postings — data any visitor can see without logging in. No personal data behind authentication is touched. Review the target site's terms and your local regulations for your specific use case.
Do I need an account on the target site? No. Postings are fetched from public pages/APIs — no login, cookies or session tokens.
How fresh is the data?
Every run fetches live listings. Results are cached for cacheTtlSeconds (default 30 min, set 0 to always hit the source live).
How many jobs can I get?
maxItems caps the run. aijobs.net serves its listing as a "Load more" feed, so raising maxItems above one page (~50) follows the pagination and fetches more cards, up to 300 (8 pages). Keyword/location filters are then applied to the fetched cards, so the returned count may be lower. Set 0 to fetch just the first page.
Why is company empty?
It normally isn't — includeCompany defaults to true, so company (and the full description) is fetched from each job's detail page. company is only null if you turn includeCompany off, or if a particular detail page has no company anchor.
Can I filter by keyword or location?
Yes. Set searchQuery (keyword; every word must match) and/or location (substring of the location text). Both are case-insensitive and applied to the fetched cards.
Something broken or missing? Open an issue on the Actor's Issues tab — it is monitored and reliability fixes ship fast.
Integrations
Export the dataset as JSON, CSV, Excel/XLSX, or plug it straight into Make, Zapier or n8n via the Apify integrations. For one-shot pulls, call run-sync-get-dataset-items to run the Actor and get items back in a single HTTP response, or drive it through the Apify MCP server from any MCP-compatible agent.
Is this Actor useful to you? A quick ⭐ review on the Actor's Reviews tab helps other AI/ML job seekers find it — and tells us what to build next.
Related Actors
- AI & ML Engineer Jobs Scraper — 8 Boards in One
- Hacker News Who Is Hiring Scraper — HN Jobs
- LinkedIn Jobs Scraper — No Login, No Cookies
- Built In Jobs Scraper — US Tech & Startup Jobs
From the maker of Oink — an open-source, AI-powered job-search bot for Telegram that runs on these Actors. Try the free bot, get a managed instance at oinkjobsearch.com, or browse the full catalog of 50+ Actors.