# StepStone Group Jobs Feed (`automation-lab/stepstone-group-jobs-feed`) Actor

Search Totaljobs, CWJobs, and Jobsite and export normalized UK vacancy records for recurring hiring intelligence.

- **URL**: https://apify.com/automation-lab/stepstone-group-jobs-feed.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** Jobs, Lead generation, Automation
- **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

## StepStone Group Jobs Feed

Search **Totaljobs, CWJobs, and Jobsite** and export normalized UK vacancy records for hiring intelligence, salary research, recruiting operations, and recurring job-market monitoring.

The Actor turns public search results or supplied job URLs into consistent records with vacancy identity, title, employer, location, displayed salary, recognized skills, work mode, publication date, description, job URL, and source portal. It is also useful when analysts need current **job position examples** from supported StepStone Group job boards without manually copying search pages.

### What does this Actor do?

StepStone Group Jobs Feed supports two input routes:

1. Search one supported portal by job keyword and optional location.
2. Supply one or more supported search, result, or individual job URLs.

Search pages produce normalized vacancy summaries. An individual job URL uses the page's public `JobPosting` structured data to return the full public description and exact publication timestamp when available.

Supported portals are:

- Totaljobs (`www.totaljobs.com`)
- CWJobs (`www.cwjobs.co.uk`)
- Jobsite (`www.jobsite.co.uk`)

Other StepStone Group properties are not currently supported. The Actor fails clearly on an unsupported hostname instead of returning misleading empty data.

### Who is this StepStone jobs feed for?

- **Recruiting teams** comparing active demand for roles across UK job boards.
- **Labor-market analysts** building repeatable vacancy and salary datasets.
- **Sales and staffing teams** identifying employers currently hiring.
- **Job-board operators** collecting normalized source links for downstream review.
- **Data engineers** feeding current vacancy records into spreadsheets, warehouses, or BI tools.
- **AI application builders** supplying compact, typed job records to research agents and RAG workflows.

### Why use it?

- One schema across three related UK portals.
- Stable job IDs support deduplication and scheduled comparisons.
- Keyword/location search and explicit-URL inputs cover discovery and targeted extraction.
- Residential HTTP extraction avoids shipping a heavyweight browser.
- Pagination and result limits are bounded and predictable.
- Missing source values remain `null` or empty arrays rather than being invented.
- Every row retains its source portal and source URL for traceability.

### What job data can you extract?

| Field | Meaning |
| --- | --- |
| `jobId` | Stable numeric identifier from the source listing |
| `title` | Public vacancy title |
| `employer` | Displayed employer name, when available |
| `location` | Displayed location or postcode |
| `salary` | Salary text shown by the portal |
| `skills` | Recognized technical/business skills named in listing text |
| `workMode` | `remote`, `hybrid`, `on-site`, or `null` when not stated |
| `postedText` | Source publication-age text, such as `2 days ago` |
| `datePosted` | Exact structured date or an ISO approximation from relative age text |
| `description` | Search-result summary, or full public text for an individual job URL |
| `applyUrl` | Canonical public job/application page |
| `sourcePortal` | `TOTALJOBS`, `CWJOBS`, or `JOBSITE` |
| `sourceUrl` | Search or job URL used for extraction |
| `scrapedAt` | ISO timestamp of extraction |

### Search StepStone job board listings

For a standard portal search, provide `portal`, `query`, and optionally `location`:

```json
{
  "portal": "TOTALJOBS",
  "query": "software engineer",
  "location": "London",
  "maxItems": 10,
  "maxPages": 2
}
```

The Actor builds the matching public search URL, follows pagination, deduplicates by `jobId`, and stops at `maxItems`.

### Extract supplied search or job URLs

Use `startUrls` when you already have a StepStone job board URL:

```json
{
  "startUrls": [
    { "url": "https://www.totaljobs.com/jobs/cyber-security/in-london" },
    { "url": "https://www.jobsite.co.uk/jobs/cyber-security/in-london" }
  ],
  "maxItems": 30,
  "maxPages": 1
}
```

When `startUrls` is present, `portal`, `query`, and `location` are ignored. The same global result limit and stable-ID deduplication apply across every URL.

An individual URL matching `/job/...-job123456789` returns one structured detail record rather than treating the page as a search result.

### Input parameters

| Input | Type | Default | Description |
| --- | --- | --- | --- |
| `portal` | string | `TOTALJOBS` | Portal for generated keyword searches: `TOTALJOBS`, `CWJOBS`, or `JOBSITE` |
| `query` | string | prefilled | Job title, skill, or phrase; required unless `startUrls` is supplied |
| `location` | string | — | Optional UK city, region, or postcode |
| `startUrls` | array | `[]` | Supported search/result URLs or individual job URLs |
| `maxItems` | integer | `10` | Unique jobs to save, from 1 to 500 |
| `maxPages` | integer | `5` | Search pages per URL, from 1 to 50 |

The source requires a UK residential proxy route. The Actor configures that route automatically. A run fails with a clear message if compatible proxy access is unavailable.

### Example output

This representative record was produced by the current parser from a public Totaljobs search; the description is shortened here for readability:

```json
{
  "jobId": "107835239",
  "title": "Country Software Engineer",
  "employer": "IKEA",
  "location": "North West London (NW10), NW10 0JQ",
  "salary": "starting salary £50,600 per annum",
  "skills": [],
  "workMode": null,
  "postedText": "2 days ago",
  "datePosted": "2026-08-13T14:17:26.105Z",
  "description": "Join us as our Country Software Engineer...",
  "applyUrl": "https://www.totaljobs.com/job/country-software-engineer/ikea-job107835239",
  "sourcePortal": "TOTALJOBS",
  "sourceUrl": "https://www.totaljobs.com/jobs/software-engineer/in-london",
  "scrapedAt": "2026-08-15T14:17:26.105Z"
}
```

Dates derived from text such as `2 days ago` are approximations based on extraction time. Individual job pages can provide an exact structured publication date.

### How much does it cost to extract StepStone Group job listings?

The Actor uses pay-per-event pricing:

- one `start` event per run;
- one `item` event for each normalized job record saved.

At the BRONZE tier, the run start costs **$0.005** and each job costs **$0.0012**. For example:

| Saved jobs | Example total |
| ---: | ---: |
| 10 | $0.017 |
| 25 | $0.035 |
| 100 | $0.125 |

Higher-volume platform tiers use lower per-job prices. Actual active pricing is always shown in Apify Console before a run. Failed, duplicate, rejected, or empty records do not incur an item event.

Residential proxy and compute usage are paid by the Actor under PPE pricing; users are charged through the declared events rather than a separate proxy line item.

### Getting started

1. Open the Actor in Apify Console.
2. Keep `TOTALJOBS` or select `CWJOBS`/`JOBSITE`.
3. Enter a real job keyword such as `data engineer`.
4. Optionally enter a UK location such as `London`.
5. Set a small `maxItems` value for the first run.
6. Click **Start**.
7. Open the **Jobs** dataset view.
8. Download JSON, CSV, Excel, XML, or RSS, or consume the dataset through the API.

The prefilled software-engineer search is designed to return useful current results.

### Recurring hiring-intelligence workflow

A practical scheduled workflow is:

1. Run one stable query per role/location/portal.
2. Retain `jobId`, `datePosted`, `salary`, and `sourcePortal` in your data warehouse.
3. Compare the current run with the previous snapshot by `sourcePortal + jobId`.
4. Mark newly observed IDs as openings and missing IDs as candidates for expiry review.
5. Aggregate employer, salary, location, skill, and work-mode changes in BI dashboards.

The Actor itself does not claim to identify expired jobs or persist cross-run state. Snapshot comparison belongs in your storage or automation workflow.

### Export to spreadsheets and data pipelines

After a run, use Apify integrations or dataset URLs to:

- append new records to Google Sheets;
- send results to Make or Zapier;
- load JSON/CSV into BigQuery, Snowflake, PostgreSQL, or object storage;
- trigger n8n workflows for employer monitoring;
- feed normalized vacancies to salary and workforce dashboards.

Use `sourcePortal` and `jobId` together as the downstream identity key.

### Run through the API

Set `APIFY_TOKEN` in your environment. Do not put tokens in source control.

#### cURL

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~stepstone-group-jobs-feed/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"portal":"CWJOBS","query":"data engineer","location":"London","maxItems":10}'
```

#### JavaScript

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/stepstone-group-jobs-feed').call({
  portal: 'CWJOBS',
  query: 'data engineer',
  location: 'London',
  maxItems: 10,
});
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/stepstone-group-jobs-feed').call(run_input={
    'portal': 'JOBSITE',
    'query': 'cyber security',
    'location': 'London',
    'maxItems': 10,
})
for item in client.dataset(run['defaultDatasetId']).iterate_items():
    print(item)
```

### Use with MCP and AI agents

Add the Actor to Claude Code:

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

#### Claude Desktop setup

Add this server object to Claude Desktop's MCP configuration:

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

#### Cursor setup

Add the same `apify` server URL under **Cursor Settings → Tools & MCP → New MCP Server**.

#### VS Code setup

Add the same `apify` server URL to your workspace MCP server configuration, then enable it from VS Code's MCP tools view.

Example prompts:

- “Search CWJobs for data engineer vacancies in London and summarize displayed salary ranges.”
- “Collect 30 cyber security jobs from the supplied Totaljobs and Jobsite URLs, then group them by employer.”
- “Return job position examples for software engineering and cite each public application URL.”

Agents should treat `datePosted` as approximate when `postedText` is relative.

### Tips for reliable runs

- Start with 10–25 results while confirming a query.
- Use the portal's public search URL in `startUrls` when you need filters not exposed as dedicated inputs.
- Keep `maxPages` proportional to `maxItems`; each search page normally contains about 25 cards.
- Schedule at a responsible interval rather than repeatedly polling unchanged pages.
- Deduplicate historical exports by `sourcePortal + jobId`.
- Preserve `sourceUrl` for audits and parser troubleshooting.

### Limits and failure behavior

- Only the three documented hostnames are accepted.
- Search summaries may be truncated by the source.
- Skills and work mode are conservative text-derived fields; `[]`/`null` means not confidently stated.
- Salary is source text, not a normalized currency/period calculation.
- Relative posting dates are approximated at extraction time.
- Listings can be changed or removed after extraction.
- Residential proxy access is required because direct/datacenter requests are blocked by the source.
- A challenge page, unsupported content type, exhausted retry sequence, or malformed input fails the run rather than silently returning zero records.
- The Actor does not log in, submit applications, contact employers, or access private candidate data.

### Responsible and legal use

The Actor accesses public vacancy pages without login. Web-scraping rules vary by jurisdiction and use case. You are responsible for checking applicable laws, portal terms, robots directives, contractual restrictions, and data-retention requirements.

Use reasonable schedules and limits. Do not use output for discrimination, spam, deceptive outreach, automated application submission, or attempts to identify private individuals. Preserve source attribution and honor removal requests in downstream systems.

### FAQ

#### Does this support every StepStone Group portal?

No. Current verified support is Totaljobs, CWJobs, and Jobsite. Unsupported domains fail validation.

#### Is this a StepStone job app or an official API?

No. It is an independent Actor that converts publicly visible job-board pages into structured dataset records. It is not affiliated with StepStone Group and does not interact with a mobile job app.

#### Can I scrape a single job posting?

Yes. Supply its supported public `/job/...-job<ID>` URL in `startUrls`. The Actor reads public `JobPosting` structured data when present.

#### Why is the description shorter in search output?

Search pages expose a listing summary. Use an individual supported job URL when you need the full public description for one vacancy.

#### Why did my run fail with a proxy message?

These portals block ordinary direct/datacenter routes. The Actor requires Apify's GB residential proxy path. Confirm the run is on Apify and retry only after compatible proxy access is available.

#### Why did a query return no rows?

Open the generated search on the selected portal and confirm that the role/location currently has results. Also check spelling and reduce location specificity. A genuine empty search exits successfully; a challenge or invalid response fails.

#### Can I monitor new and removed jobs?

Schedule consistent inputs and compare exported snapshots by `sourcePortal + jobId`. Cross-run change tracking is not stored automatically by this Actor.

### Related automation-lab Actors

- [Company Career Page Jobs Scraper](https://apify.com/automation-lab/company-career-page-jobs-scraper) for supported employer-owned career pages.
- [Pracuj.pl Jobs Scraper](https://apify.com/automation-lab/pracuj-pl-jobs-scraper) for Polish vacancy and salary intelligence.
- [NHS Jobs Scraper](https://apify.com/automation-lab/nhs-jobs-scraper) for UK healthcare vacancies.

These products cover different sources; they are not automatic fallbacks for this Actor.

# Actor input Schema

## `portal` (type: `string`):

StepStone Group portal used for keyword search. Ignored when Start URLs are supplied.

## `query` (type: `string`):

Job title, skill, or search phrase. Required unless Start URLs are supplied.

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

Optional UK city, region, or postcode used to narrow keyword search.

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

Optional Totaljobs, CWJobs, or Jobsite search/result URLs or individual job URLs. When supplied, portal, query, and location are ignored.

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

Maximum number of unique normalized job records to save.

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

Maximum pages to inspect for each supplied or generated search URL.

## Actor input object example

```json
{
  "portal": "TOTALJOBS",
  "query": "data analyst",
  "location": "London",
  "startUrls": [],
  "maxItems": 10,
  "maxPages": 5
}
```

# Actor output Schema

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

Dataset containing extracted Totaljobs, CWJobs, and Jobsite vacancy 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 = {
    "portal": "TOTALJOBS",
    "query": "software engineer",
    "startUrls": [],
    "maxItems": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/stepstone-group-jobs-feed").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 = {
    "portal": "TOTALJOBS",
    "query": "software engineer",
    "startUrls": [],
    "maxItems": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/stepstone-group-jobs-feed").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 '{
  "portal": "TOTALJOBS",
  "query": "software engineer",
  "startUrls": [],
  "maxItems": 10
}' |
apify call automation-lab/stepstone-group-jobs-feed --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/stepstone-group-jobs-feed"
        }
    }
}

```

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/9oh76yAymcyMP4dxt/builds/wKYAegagF2cxI4Kei/openapi.json
