# Eluta Jobs Scraper (`automation-lab/eluta-jobs-scraper`) Actor

Extract public Eluta jobs for Canadian recruiting, job monitoring, and labor-market analysis.

- **URL**: https://apify.com/automation-lab/eluta-jobs-scraper.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** Jobs
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#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

## Eluta Jobs Scraper

Extract public **Eluta jobs** into a structured dataset for Canadian recruiting, labor-market research, lead generation, and scheduled monitoring.

Search by job title, skill, employer, and Canadian location, or provide a real Eluta search or job URL. Each result includes the title, employer, location, summary, salary when published, posting age or exact date, and useful source links.

### What does Eluta Jobs Scraper do?

Eluta Jobs Scraper turns public listings from [Eluta.ca](https://www.eluta.ca/) into integration-ready JSON records.

It supports:

- one or many keyword searches in the same run;
- an optional Canadian city, province, or region;
- direct Eluta search-result URLs;
- direct Eluta `/spl/` job-detail URLs;
- bounded pagination with `maxItems` and `maxPages`;
- duplicate removal by canonical Eluta job URL;
- clean output in the run's default Apify dataset.

The Actor uses Eluta's server-rendered public pages through a reusable Apify datacenter proxy session. It does not require an Eluta account, browser, or user-supplied proxy configuration.

### Who is it for?

#### Recruiters and sourcers

Build focused lists of open roles by occupation and region. Use employer and source URLs to continue qualification outside the dataset.

#### Labor-market analysts

Compare titles, employers, locations, salary disclosures, and listing activity across repeat runs.

#### Sales and lead-generation teams

Find organizations that are hiring for relevant functions, then enrich the employer outside this Actor using your approved workflow.

#### Data and automation teams

Schedule searches and send normalized records to a spreadsheet, warehouse, webhook, or downstream Apify Actor.

### Why use this Actor?

- **Eluta-specific output:** field names describe jobs rather than generic scraped pages.
- **Two input routes:** use easy keyword searches or preserve an exact Eluta URL.
- **Useful provenance:** every row includes the processed page and canonical job URL.
- **Detail-page support:** a direct job URL adds exact posting dates, expiry, employment type, full description, and the original-source redirect when Eluta exposes them.
- **Cost-conscious extraction:** HTTP plus a datacenter proxy avoids browser and residential-proxy overhead.
- **Safe bounds:** item and page limits prevent an accidental unlimited run.

### What data can you extract?

| Field | Meaning |
| --- | --- |
| `recordId` | Stable identifier from Eluta |
| `title` | Job title |
| `employer` | Hiring employer, when available |
| `location` | Search-card or structured job location |
| `summary` | Search summary or full detail-page description |
| `salary` | Published compensation text, or `null` |
| `postedAge` | Relative age from a search result, such as `2 days ago` |
| `postedAt` | Exact timestamp from a direct job page, or `null` |
| `validThrough` | Listing expiry from a direct job page, or `null` |
| `employmentType` | Structured employment type, or `null` |
| `jobUrl` | Canonical public Eluta job URL |
| `sourceJobUrl` | Eluta redirect to the employer's original listing, when available |
| `employerJobsUrl` | Eluta page for jobs from the same employer |
| `searchUrl` | Page from which this record was extracted |
| `searchTerm` | Associated keyword for search-result records |
| `searchLocation` | Associated location for search-result records |
| `scrapedAt` | UTC extraction timestamp |

Fields that are not present on a specific page are returned as `null`. Search cards prioritize efficient discovery; direct job URLs expose richer structured metadata.

### How to run Eluta job searches

1. Open the Actor input page.
2. Add one or more values to **Search terms**, such as `software engineer`.
3. Optionally set **Location**, such as `Toronto, ON`.
4. Choose a small **Maximum jobs** value for the first run.
5. Click **Start**.
6. Open the **Eluta jobs** dataset view when the run succeeds.
7. Export the records as JSON, CSV, Excel, XML, or RSS through Apify.

You can also omit search terms and provide Eluta start URLs. At least one search term or start URL is required.

### Input parameters

#### `searchTerms`

An array of up to 20 job keywords, job titles, skills, or employer names. Each term creates one Eluta search.

Example:

```json
["data analyst", "cybersecurity"]
```

#### `location`

An optional location applied to every generated search.

Examples:

- `Toronto, ON`
- `Edmonton, AB`
- `Ontario`
- `Canada`

#### `startUrls`

Up to 20 HTTPS URLs on `eluta.ca`. Supported forms are:

- search pages such as `https://www.eluta.ca/search?q=project+manager&l=Edmonton+AB`;
- canonical `...-jobs-in-...` search pages;
- individual job pages under `/spl/`.

Other domains and unrelated Eluta pages fail validation instead of being silently scraped.

#### `maxItems`

Maximum unique records saved across all inputs. Default: `50`. Allowed range: `1` to `1000`.

#### `maxPages`

Maximum total pages requested. Default: `20`. Allowed range: `1` to `100`.

This is a safety bound, not a promise that every search has that many pages.

### Input examples

#### Search for software engineer jobs in Toronto

```json
{
  "searchTerms": ["software engineer"],
  "location": "Toronto, ON",
  "maxItems": 10,
  "maxPages": 3
}
```

#### Process an exact Edmonton search page

```json
{
  "startUrls": [
    { "url": "https://www.eluta.ca/search?q=project+manager&l=Edmonton+AB" }
  ],
  "maxItems": 8,
  "maxPages": 3
}
```

#### Extract richer metadata from one job

```json
{
  "startUrls": [
    { "url": "https://www.eluta.ca/spl/full-stack-software-engineer-autosync-0b54b15a966759e9612f7ec2536cb18b" }
  ],
  "maxItems": 1,
  "maxPages": 1
}
```

### Output example

The following shape comes from the current search workflow; listing content changes over time:

```json
{
  "recordId": "0b54b15a966759e9612f7ec2536cb18b",
  "title": "Full Stack Software Engineer, AutoSync",
  "employer": "TRADER Corporation",
  "location": "Toronto, ON",
  "summary": "...software tools to simplify operations...",
  "salary": "$100,000 - $120,000",
  "postedAge": "17 hours ago",
  "postedAt": null,
  "validThrough": null,
  "employmentType": null,
  "jobUrl": "https://www.eluta.ca/spl/full-stack-software-engineer-autosync-0b54b15a966759e9612f7ec2536cb18b",
  "sourceJobUrl": null,
  "employerJobsUrl": "https://www.eluta.ca/jobs-at-trader-corporation",
  "searchUrl": "https://www.eluta.ca/search?q=software+engineer&l=Toronto%2C+ON",
  "searchTerm": "software engineer",
  "searchLocation": "Toronto, ON",
  "scrapedAt": "2026-08-03T03:37:15.120Z"
}
```

### How much does it cost to extract Eluta jobs?

The Actor uses pay-per-event pricing:

- one `start` event for each run;
- one `item` event for each unique job saved.

The start event is **$0.005 per run**. Item prices decrease across the six Apify platform tiers: **$0.0013754 FREE, $0.001196 BRONZE, $0.00093288 SILVER, $0.0007176 GOLD, $0.0004784 PLATINUM, and $0.00033488 DIAMOND per saved job**. Failed, duplicate, or rejected records do not produce an item charge.

Examples at the BRONZE tier:

| Saved jobs | Estimated total |
| ---: | ---: |
| 10 | $0.01696 |
| 25 | $0.03490 |
| 100 | $0.12460 |

```text
estimated total = $0.005 + (saved jobs × your tier's item price)
```

Keep `maxItems` small while testing a new query. Check the Actor's live pricing tab before a large run because platform pricing can change.

### Scheduling and monitoring new Eluta jobs

Use an Apify Schedule to run the same input daily or weekly. Each run creates a run-specific dataset, making it suitable for snapshot comparison.

A typical monitoring workflow is:

1. schedule the Actor with stable search terms and location;
2. fetch the latest dataset through the API;
3. compare `jobUrl` or `recordId` with your previously stored snapshot;
4. treat unseen identifiers as new jobs;
5. notify a recruiter or write changes to your own database.

The Actor does not keep a global cross-run history or send alerts by itself. Your scheduler or downstream workflow owns state and notifications.

### Export Eluta jobs to a spreadsheet or pipeline

From the dataset page, download CSV or Excel for manual analysis. For automation, use the dataset API or an Apify integration.

Common patterns include:

- Google Sheets for recruiter review;
- Make or Zapier for notification workflows;
- webhooks after successful runs;
- a warehouse ingestion job keyed by `jobUrl`;
- scheduled snapshot comparisons for labor-market analysis.

### Run with the Apify API

Replace `YOUR_APIFY_TOKEN` with a token you control.

#### cURL

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~eluta-jobs-scraper/runs?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "searchTerms": ["data analyst"],
    "location": "Toronto, ON",
    "maxItems": 25,
    "maxPages": 5
  }'
```

#### JavaScript

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/eluta-jobs-scraper').call({
  searchTerms: ['data analyst'],
  location: 'Toronto, ON',
  maxItems: 25,
  maxPages: 5,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

#### Python

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/eluta-jobs-scraper').call(run_input={
    'searchTerms': ['data analyst'],
    'location': 'Toronto, ON',
    'maxItems': 25,
    'maxPages': 5,
})

items = client.dataset(run['defaultDatasetId']).list_items().items
print(items)
```

### Use Eluta Jobs Scraper through MCP

Add the Actor to Claude Code through Apify's hosted MCP server:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/eluta-jobs-scraper"
```

#### Claude Desktop, Cursor, and VS Code setup

Use this equivalent MCP configuration in Claude Desktop, Cursor, or VS Code:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=automation-lab/eluta-jobs-scraper"
    }
  }
}
```

Example prompts:

- “Run Eluta Jobs Scraper for data analyst jobs in Toronto and return 20 records.”
- “Extract this Eluta job URL and summarize the employer, salary, dates, and source link.”
- “Create a dataset for cybersecurity and cloud engineer jobs in Canada.”

MCP authentication and tool availability follow your Apify account configuration.

### Limits and extraction behavior

- Eluta controls listing availability, ranking, summaries, and freshness.
- Search results can change between pages or runs.
- A listing may omit salary, exact dates, employment type, or source links.
- Search cards expose relative age; exact dates require a direct `/spl/` input.
- The Actor does not enrich employers, infer seniority, or guess missing fields.
- `maxPages` applies across all inputs, so early searches can consume the page budget.
- The Actor reuses one Apify datacenter proxy session and rotates it at most once after a detected verification page.
- Residential and browser fallbacks are not enabled; the run fails explicitly if the bounded datacenter route is exhausted.
- Markup changes can temporarily affect extraction until the parser is updated.

### Responsible use and legality

Use this Actor only for data you are legally allowed to collect and process.

You are responsible for:

- reviewing Eluta's terms and applicable website rules;
- complying with privacy, employment, anti-discrimination, and database laws;
- choosing a reasonable schedule and volume;
- avoiding unsolicited or harmful outreach;
- honoring deletion, retention, and access obligations in your downstream systems.

This Actor accesses public pages and does not bypass login controls. Public availability does not remove your compliance obligations.

### Troubleshooting

#### The run says an Eluta URL is unsupported

Use an HTTPS Eluta search page, a canonical `-jobs-in-...` page, or an individual `/spl/` job URL. Employer pages and unrelated navigation URLs are intentionally rejected.

#### The dataset is empty

Open the same search on Eluta and confirm that it currently has organic jobs. Try a broader keyword, remove the location, or increase `maxPages` without exceeding your intended budget.

#### I received fewer jobs than `maxItems`

The source may have fewer unique matching listings, or `maxPages` may have been reached. Duplicate canonical job URLs are saved only once.

#### Exact posting dates are `null`

Search cards provide relative posting age. Supply individual `/spl/` job URLs when exact schema.org dates are required.

#### A source link is `null`

Not every search card exposes the employer's original listing redirect. Direct detail pages expose it when Eluta includes the link.

#### The source changed or returned an error

Inspect the run log for the failing URL and HTTP status. Transient timeouts, 429 responses, and temporary 5xx errors receive bounded retries. Deterministic invalid inputs fail immediately.

### Related Automation Lab Actors

- [Canada Job Bank Scraper](https://apify.com/automation-lab/canada-job-bank-scraper) — collect public listings from Canada's official Job Bank source.
- [Workopolis Job Scraper](https://apify.com/automation-lab/workopolis-job-scraper) — add another Canada-focused commercial job source.
- [LinkedIn Jobs Scraper](https://apify.com/automation-lab/linkedin-jobs-scraper) — use a broader professional-network job source when that coverage fits your workflow.

These Actors use different sources and contracts. Combine datasets only after normalizing fields and checking each source's rules.

### FAQ

#### Does this Actor need an Eluta account?

No. It extracts supported public pages.

#### Does it use a browser or proxy?

It uses server-rendered HTML over HTTP with an Apify datacenter proxy. It does not launch a browser or use residential proxy traffic.

#### Can it monitor jobs automatically?

Yes, when run on an Apify Schedule and connected to your own snapshot-comparison or notification workflow. The Actor itself does not persist cross-run monitoring state.

#### Can I search several occupations at once?

Yes. Add up to 20 `searchTerms`. Results are deduplicated in one dataset.

#### Can I scrape one specific job?

Yes. Add its public Eluta `/spl/` URL to `startUrls` for the richest available record.

#### Does it return contact details?

No. It returns public job and employer fields shown by Eluta. It does not infer or enrich personal contact information.

#### Is complete historical coverage guaranteed?

No. Output reflects listings currently available through the supported public pages at run time.

# Actor input Schema

## `searchTerms` (type: `array`):

One or more job keywords, titles, skills, or employer names to search on Eluta.

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

Optional Canadian city, province, or region applied to every search term, for example Toronto, ON or Edmonton, AB.

## `startUrls` (type: `array`):

Optional public Eluta search-result or individual /spl/ job URLs. These are processed in addition to search terms.

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

Maximum number of unique job records saved across all searches and start URLs.

## `maxPages` (type: `integer`):

Safety limit for the total number of Eluta search and job pages requested during one run.

## Actor input object example

```json
{
  "searchTerms": [
    "software engineer"
  ],
  "location": "Toronto, ON",
  "maxItems": 10,
  "maxPages": 5
}
```

# Actor output Schema

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

Default dataset containing all extracted job records.

# 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 = {
    "searchTerms": [
        "software engineer"
    ],
    "location": "Toronto, ON",
    "maxItems": 10,
    "maxPages": 5
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/eluta-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 = {
    "searchTerms": ["software engineer"],
    "location": "Toronto, ON",
    "maxItems": 10,
    "maxPages": 5,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/eluta-jobs-scraper").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "searchTerms": [
    "software engineer"
  ],
  "location": "Toronto, ON",
  "maxItems": 10,
  "maxPages": 5
}' |
apify call automation-lab/eluta-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=automation-lab/eluta-jobs-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/SLfauuU7gmhJEmgU0/builds/BuTIt4WAonO6HENWQ/openapi.json
