# Foorilla AI Jobs Scraper — ML & Data Roles (`nomad-agent/foorilla-ai-jobs-scraper`) Actor

Scrape Foorilla Hiring's Data, AI, and Machine Learning jobs. Get job title, company, location, remote flag, seniority, salary band, posted date, description, and job URL. Filter by keyword and location; no Foorilla login or proxies required.

- **URL**: https://apify.com/nomad-agent/foorilla-ai-jobs-scraper.md
- **Developed by:** [Nomad Dev](https://apify.com/nomad-agent) (community)
- **Categories:** Jobs
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 foorilla job results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Foorilla AI Jobs Scraper — ML & Data Roles

Scrape the **Data, AI, and Machine Learning** jobs on [Foorilla Hiring](https://foorilla.com/hiring/data-ai-and-machine-learning/). Export job titles, companies, locations, remote-work signals, seniority, salary bands, posting dates, descriptions, and Foorilla job URLs.

Use the Actor for machine-learning job alerts, recruiting research, salary analysis, and AI talent pipelines. It reads public Foorilla pages and requires no Foorilla account, cookies, or proxy configuration.

### What does the Foorilla Jobs Scraper extract?

Each dataset item represents one Foorilla job:

| Field | Meaning |
|---|---|
| `id` | Stable numeric ID from the Foorilla job URL |
| `slug` | Human-readable URL slug |
| `title` | Job title |
| `company` | Hiring company from the job detail page |
| `location` | Location text shown by Foorilla |
| `isRemote` | `true` when the listing contains an explicit remote-work signal; otherwise `null` |
| `url` | Direct Foorilla job URL |
| `postedAt` | Exact `YYYY-MM-DD` publication date when available, otherwise a date or timestamp derived from the relative-age label |
| `postedAtText` | Original relative-age label, such as `5d ago` |
| `seniority` | Seniority badge, when supplied |
| `snippet` | Compact listing-card text |
| `description` | Full job-description sections from the detail page |
| `salary` | Raw disclosed salary band |
| `salaryMin` / `salaryMax` | Parsed numeric salary bounds |
| `salaryCurrency` | Three-letter currency code |
| `salaryPeriod` | `null` when Foorilla does not identify a pay period |

### Quick start

1. Click **Try for free** or **Run**.
2. Optionally set a keyword, location, or maximum result count.
3. Run the Actor and export the dataset as JSON, CSV, Excel, XML, or another supported format.

Python example:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("nomad-agent/foorilla-ai-jobs-scraper").call(
    run_input={"searchQuery": "machine learning", "maxItems": 50}
)

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["title"], item["company"], item["url"])
```

Synchronous HTTP example:

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/nomad-agent~foorilla-ai-jobs-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 | empty | Keeps jobs whose card text contains every entered word, case-insensitively. `keyword` is accepted as an alias. |
| `location` | string | empty | Case-insensitive location substring, such as `Berlin`, `Germany`, or `Remote`. |
| `maxItems` | integer | `50` | Fetch up to 300 jobs across at most eight Foorilla pages. `0` fetches the first page. |
| `includeCompany` | boolean | `true` | Deprecated compatibility input. Detail pages are always requested; company stays `null` when Foorilla omits it, while listings without retrievable descriptions are omitted. |
| `euBias` | boolean | `false` | Sorts European and remote-EU listings first without excluding other jobs. |
| `cacheTtlSeconds` | integer | `1800` | Caches the first upstream listing page for this many seconds. Use `0` to disable the cache. |

Keyword and location filters are applied to the fetched cards, so a filtered dataset can contain fewer than `maxItems` results.

### Output example

```json
{
  "id": "3578233",
  "slug": "engineering-ai-systems-lead-remote-gst-hours",
  "title": "Engineering AI Systems Lead",
  "company": "Example company",
  "location": "Remote",
  "isRemote": true,
  "url": "https://foorilla.com/hiring/jobs/engineering-ai-systems-lead-remote-gst-hours-3578233/",
  "postedAt": "2026-09-08",
  "postedAtText": "1d ago",
  "seniority": "Senior-level",
  "snippet": "Engineering AI Systems Lead Remote ...",
  "description": "Tasks: ... Skills/Tech-stack: ...",
  "salary": null,
  "salaryMin": null,
  "salaryMax": null,
  "salaryCurrency": null,
  "salaryPeriod": null
}
```

Fields stay `null` when Foorilla does not publish the corresponding value. The Actor does not infer a salary period or an onsite policy from missing information.

### Pricing

Pay per event: **$0.005 per Actor start** and **$0.002 per job returned**. A run returning 100 jobs costs approximately **$0.205**. There is no monthly rental.

### Foorilla scraper use cases

- Build Foorilla AI and machine-learning job alerts
- Track AI hiring demand, locations, seniority, and disclosed salaries
- Source ML engineers, data scientists, MLOps specialists, and research scientists
- Feed job boards, spreadsheets, dashboards, and recruiting workflows

### FAQ

#### Does this scrape every category on Foorilla?

No. This Actor is intentionally scoped to Foorilla Hiring's **Data, AI, and Machine Learning** topic. It does not claim to cover unrelated Foorilla categories.

#### Does it require a Foorilla login?

No. It reads publicly accessible Foorilla Hiring pages without authentication.

#### Why can a run return fewer results than `maxItems`?

The Actor applies your keyword and location filters after fetching listing cards. The source can also have fewer available listings than requested.

#### How fresh are results?

Each run reads the current Foorilla listing. The first page is cached for 30 minutes by default; set `cacheTtlSeconds` to `0` to disable that cache.

#### Something broken or missing?

Open an issue on the Actor's **Issues** tab with the run ID and input. Source failures are recorded in the run's `RUN-SUMMARY` key-value-store record.

### Related Actors

- [AI & ML Engineer Jobs Scraper — 8 Boards in One](https://apify.com/nomad-agent/ml-ai-dev-bundle)
- [Hacker News Who Is Hiring Scraper](https://apify.com/nomad-agent/hackernews-scraper)
- [LinkedIn Jobs Scraper](https://apify.com/nomad-agent/linkedin-scraper)
- [Built In Jobs Scraper](https://apify.com/nomad-agent/builtin-scraper)

***

Built by [Nomad Agent](https://apify.com/nomad-agent), creator of the open-source [Oink AI Job Search](https://github.com/Exdenta/OinkAIJobSearch).

# Actor input Schema

## `searchQuery` (type: `string`):

Only keep jobs whose card text (title, snippet, skills, seniority, salary badge) contains every whitespace-separated word you enter — e.g. "machine learning" keeps cards mentioning both words. Case-insensitive. Leave empty to return all cards. (Alias: `keyword`.)

## `location` (type: `string`):

Only keep jobs whose location text contains this value (case-insensitive substring), e.g. "Berlin", "Germany", "Remote" or "United States". Matches against the card's location plus the title/slug so remote-in-title postings are still caught. Leave empty to return all locations.

## `maxItems` (type: `integer`):

How many Foorilla listing cards to fetch. Values above one page (~50) follow the site's Load more pagination, up to 300 items / 8 pages. Keyword and location filters are applied after fetching, so the returned count may be lower. Set 0 to fetch the first page.

## `includeCompany` (type: `boolean`):

Deprecated compatibility input. The Actor always requests each job's detail page; company remains null when Foorilla omits it, listings without retrievable descriptions are omitted, and false is ignored.

## `euBias` (type: `boolean`):

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` (type: `integer`):

Cache the upstream page-1 fetch in the key-value store for this many seconds; re-runs within the window skip that network call. Load-more pages (page 2+) are always fetched live. Set 0 to disable.

## Actor input object example

```json
{
  "maxItems": 50,
  "includeCompany": true,
  "euBias": false,
  "cacheTtlSeconds": 1800
}
```

# Actor output Schema

## `dataset` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("nomad-agent/foorilla-ai-jobs-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("nomad-agent/foorilla-ai-jobs-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call nomad-agent/foorilla-ai-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nomad-agent/foorilla-ai-jobs-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/3pmwELozh8x1P0dSu/builds/BG8qoiVadxteqjkjN/openapi.json
