Company Jobs Tracker avatar

Company Jobs Tracker

Pricing

from $50.00 / 1,000 company trackeds

Go to Apify Store
Company Jobs Tracker

Company Jobs Tracker

Track job listings for specific companies across StepStone portals (DE, AT, BE, NL, Totaljobs, NIjobs, Pnet). Detects new, changed, and removed postings with stateful diff tracking. Pay per company tracked.

Pricing

from $50.00 / 1,000 company trackeds

Rating

0.0

(0)

Developer

Black Falcon Data

Black Falcon Data

Maintained by Community

Actor stats

1

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Categories

Share

Company Jobs Tracker

Company Jobs Tracker — Hiring Monitor for 18 StepStone Group Portals

What is Company Jobs Tracker?

Company Jobs Tracker is an Apify Actor that monitors company hiring activity across 18 European job portals in the StepStone Group network. Input a list of companies, and receive structured change detection output on each run: which new jobs appeared, which removed jobs disappeared, and how many remain unchanged.

Built for recruitment pipelines, sales intelligence workflows, and investor due diligence. One record per company per run — predictable, pipeline-ready output. Schedule daily for continuous hiring signal without manual effort.


Key features

🏢 Company-level change detection

  • Track any combination of companies across StepStone's 18-portal network
  • New jobs, removed jobs, and unchanged counts per company per run
  • One structured record per company — stable output for downstream pipelines

🎯 Exact company targeting

  • Use companyId for server-side filtering — the portal returns only that company's listings, no client-side guesswork
  • Discover companyId automatically from any calibration run
  • Eliminates false positives from subsidiary names and ambiguous employer listings

🔄 Incremental change detection

  • First run establishes a baseline; subsequent runs return only what changed
  • Two-run removal confirmation prevents transient SERP fluctuations from triggering false removals
  • State persists across scheduled runs automatically

⚙️ Calibration mode

  • Run with calibrateOnly: true before committing to a tracking schedule
  • Identifies company name mismatches and shows the actual employer names returned by the portal
  • Writes no state — safe to run as many times as needed

📦 Predictable output

  • Always one record per input company, even on error or portal block
  • Unchanged jobs appear as a count only — no dataset bloat
  • Suitable for Google Sheets, webhooks, and ETL pipelines

💰 Predictable pricing

  • Flat $0.05 per company per run
  • Built-in cost guards prevent unexpected overruns

How it works

On the first run, the actor scrapes each company's job listings and stores them as a baseline. All jobs are classified as new, and no removals are reported — this is expected.

On each subsequent run, the actor re-scrapes and compares against the stored baseline:

  • Jobs found now but not before → new
  • Jobs found before but not now → candidates for removal (see Removal confirmation)
  • Jobs found in both runs → unchanged (counted, not listed)

The actor writes one dataset record per company per run regardless of outcome. Failed scrapes preserve the existing baseline — no false removals.


Run calibrateOnly: true before enabling live tracking. This validates your company name setup without writing any state.

Step 1 — Calibration run

{
"companies": [
{ "name": "Siemens", "geo": "DE" },
{ "name": "Bosch", "geo": "DE" }
],
"calibrateOnly": true
}

Step 2 — Check warnings

Look at the warnings field in each output record. A warning like:

no_company_match: 0/50 jobs matched "Bosch" in strict_normalized mode.
Top company names in results: "Robert Bosch GmbH", "Bosch Rexroth AG", "Bosch Sicherheitssysteme GmbH".

means the search returns results, but none match "Bosch" under strict_normalized. The portal lists the company as "Robert Bosch GmbH".

Step 3 — Adjust

Either:

  • Change name to "Robert Bosch GmbH" so normalisation strips "GmbH" and matches correctly, or
  • Switch to "matchMode": "prefix" so "Bosch" matches anything starting with "Bosch", or
  • Use companyId for exact server-side filtering (most reliable — see How to find companyId)

Step 4 — Enable live tracking

Once warnings are clear, remove calibrateOnly and schedule the run.


Quick start

Minimal input — three companies across DE, UK, and South Africa:

{
"companies": [
{ "name": "SAP", "geo": "DE" },
{ "name": "Unilever", "geo": "TOTALJOBS" },
{ "name": "Sasol", "geo": "PNET" }
],
"maxResultsPerCompany": 50
}

For exact matching, add companyId — see How to find companyId below.

Schedule this run daily to receive a structured diff of hiring activity for each company.


Input parameters

Top-level fields

ParameterTypeDefaultDescription
companiesarrayList of companies to track — required
includeDetailsbooleanfalseFetch full job descriptions — slower and more expensive
maxResultsPerCompanynumber50Max jobs fetched per company per run (max: 100)
calibrateOnlybooleanfalseDry-run mode — no state written, no removals emitted
removedConfirmationRunsnumber1Consecutive missed runs before a job is confirmed removed
maxCompaniesnumber200Hard cap on companies processed per run
maxTotalRequestsnumber500Hard cap on total HTTP requests — excess companies are skipped
proxyConfigurationobjectApify proxyProxy settings — residential proxy required for some portals

Per-company fields (companies[])

FieldTypeDefaultDescription
namestringCompany display name — used in output and matching (required)
geostringPortal to search — DE, AT, NL, BE, TOTALJOBS, CWJOBS, … (required)
querystring= nameSearch query override — useful when the company name is not a good search term
companyIdnumbernullServer-side filter — bypasses client-side matching entirely when set
matchModeselectstrict_normalizedstrict / strict_normalized / prefix / contains

Examples

Track two companies

{
"companies": [
{ "name": "Siemens", "geo": "DE" },
{ "name": "SAP", "geo": "DE" }
],
"maxResultsPerCompany": 20
}

Calibrate before tracking

{
"companies": [
{ "name": "BMW", "geo": "DE" }
],
"calibrateOnly": true
}

Exact match with companyId

{
"companies": [
{ "name": "SAP", "geo": "DE", "companyId": 215050 }
],
"maxResultsPerCompany": 50
}

Example output

{
"company": "Siemens",
"geo": "DE",
"scrapeOutcome": "success",
"counts": { "new": 3, "removed": 1, "unchanged": 42, "total": 45 },
"isFirstRun": false
}

Output

The actor emits one record per company per run. Unchanged jobs are counted but not listed individually.

Sample output

{
"company": "SAP",
"geo": "DE",
"matchMode": "strict_normalized",
"scrapeOutcome": "success",
"runAt": "2026-03-11T06:00:00.000Z",
"previousRunAt": "2026-03-10T06:00:00.000Z",
"isFirstRun": false,
"counts": { "new": 3, "removed": 1, "unchanged": 42, "total": 45 },
"serpCount": 120,
"processedCount": 50,
"matchedCount": 45,
"anonymousSkippedCount": 0,
"costGuardTriggered": false,
"warnings": [],
"error": null,
"newJobs": [
{
"trackId": "job-abc123",
"title": "Senior Java Developer",
"company": "SAP SE",
"url": "https://www.stepstone.de/stellenangebote--Senior-Java-Developer-..."
}
],
"removedJobs": [
{
"trackId": "job-xyz789",
"title": "Data Analyst",
"company": "SAP SE",
"url": "https://www.stepstone.de/...",
"firstSeen": "2026-03-05T06:00:00.000Z",
"lastSeen": "2026-03-09T06:00:00.000Z",
"removedAt": "2026-03-11T06:00:00.000Z"
}
]
}

Example output record

{
"company": "SAP",
"geo": "DE",
"matchMode": "strict_normalized",
"scrapeOutcome": "success",
"runAt": "2026-03-11T06:00:00.000Z",
"previousRunAt": "2026-03-10T06:00:00.000Z",
"isFirstRun": false,
"counts": {
"new": 3,
"removed": 1,
"unchanged": 42,
"total": 45
},
"serpCount": 120,
"processedCount": 50,
"matchedCount": 45,
"anonymousSkippedCount": 0,
"costGuardTriggered": false,
"warnings": [],
"error": null,
"newJobs": [
{
"trackId": "job-abc123",
"title": "Senior Java Developer",
"company": "SAP SE",
"url": "https://www.stepstone.de/stellenangebote--Senior-Java-Developer-..."
}
],
"removedJobs": [
{
"trackId": "job-xyz789",
"title": "Data Analyst",
"company": "SAP SE",
"url": "https://www.stepstone.de/...",
"firstSeen": "2026-03-05T06:00:00.000Z",
"lastSeen": "2026-03-09T06:00:00.000Z",
"removedAt": "2026-03-11T06:00:00.000Z"
}
]
}

Output fields

FieldTypeDescription
companystringCompany name from input
geostringPortal code
matchModestringMatching mode used
scrapeOutcomestringResult of the scrape: success, empty_serp, empty_after_filter, blocked, blocked_suspected, error, skipped
runAtstring (ISO)Current run timestamp
previousRunAtstring (ISO) | nullPrevious successful run timestamp
isFirstRunbooleanTrue when no prior state exists for this company
counts.newnumberJobs new since last run
counts.removednumberJobs confirmed removed
counts.unchangednumberJobs present in both runs
counts.totalnumberTotal matched jobs in current run
serpCountnumberTotal results returned by portal
processedCountnumberJobs actually fetched (up to maxResultsPerCompany cap)
matchedCountnumberJobs that passed company matching
anonymousSkippedCountnumberListings with no employer name — skipped from matching
costGuardTriggeredbooleanTrue if this company was skipped due to request cap
warningsstring[]Calibration hints — includes top employer names when 0 jobs match
errorstring | nullError detail when scrapeOutcome is error
newJobsarrayFull details of new jobs — trackId, title, company, url
removedJobsarrayDetails of confirmed removed jobs — includes firstSeen, lastSeen, removedAt

Unchanged jobs are not listed individually — only counted. This keeps dataset size predictable across runs.


Company matching

When companyId is not set, the actor filters SERP results by employer name. The matchMode controls how strictly names are compared.

ModeBehavior
strict_normalizedLowercases, strips punctuation, removes legal suffixes (AG, GmbH, Ltd, …), then requires exact equality. Default.
strictCase-insensitive trimmed equality — no suffix stripping
prefixNormalized listing name starts with normalized input name
containsNormalized listing name contains normalized input name

Example: "Bosch" in strict_normalized mode will not match "Bosch Gruppe GmbH" because normalisation produces "bosch gruppe""bosch". Use prefix mode, or provide companyId for a guaranteed match.

Legal suffixes stripped by strict_normalized include: AG, GmbH, GmbH & Co. KG, KG, SE, Ltd, Limited, Inc, LLC, PLC, A/S, ApS, AB, BV, NV, SA, SARL, and more.

When 0 results match in strict or strict_normalized mode, the actor emits a warning listing the top employer names from that search — use this to calibrate your input name.


How to find companyId

Using companyId is the most reliable way to track a company. The portal applies the filter server-side, so all returned results belong to that company and no client-side matching is needed.

To find a company's ID, open any job listing from that company on the relevant StepStone Group portal (e.g. stepstone.de, totaljobs.com). The companyId appears as a numeric parameter in the listing URL or in the page source. Copy it into companies[].companyId in your input.

Once companyId is set, matchMode is ignored for that company entry.


Removal confirmation

A job is only marked removed after it is absent from two consecutive successful scrapes (default). This prevents transient SERP ranking changes or one-off portal variations from triggering false removal alerts.

The removedConfirmationRuns input controls this threshold:

ValueBehavior
1 (default)Job must be missing in 2 consecutive successful runs before confirmed removed
0Aggressive mode — job confirmed removed after a single missed run (more noise)
2Job must be missing in 3 consecutive runs — more conservative, fewer false positives

Failed scrapes (blocked, error) do not advance the removal countdown — only successful scrapes count.


Supported portals

This actor tracks companies across 18 portals in the StepStone Group network — the same portals covered by the StepStone Jobs Feed actor. Use the geo field per company entry to select the portal.

RegionPortalgeo valueProxy
🇩🇪 Germanystepstone.deDENone
🇦🇹 Austriastepstone.atATNone
🇧🇪 Belgiumstepstone.beBENone
🇳🇱 Netherlandsstepstone.nlNLNone
🇬🇧 United Kingdomtotaljobs.comTOTALJOBSRequired
🇬🇧 United Kingdomcwjobs.co.ukCWJOBSNone
🇬🇧 United Kingdomjobsite.co.ukJOBSITENone
🇬🇧 United Kingdommilkround.comMILKROUNDNone
🇬🇧 United Kingdomcaterer.comCATERERNone
🇬🇧 United Kingdomretailchoice.comRETAILCHOICERequired
🇬🇧 United Kingdomcareerstructure.comCAREERSTRUCTURENone
🇬🇧 United Kingdomcityjobs.comCITYJOBSNone
🇬🇧 United Kingdomjustengineers.netJUSTENGINEERSNone
🇬🇧 United Kingdomemedcareers.comEMEDCAREERSRequired
🌐 Internationalcatererglobal.comCATERERGLOBALNone
🇮🇪 Irelandnijobs.comNIJOBSNone
🇮🇪 Irelandjobs.ieJOBSIENone
🇿🇦 South Africapnet.co.zaPNETNone

Portals marked Required need a residential proxy — pass proxyConfiguration with the RESIDENTIAL group.

Note: Some portals require browser automation (Playwright), which increases compute cost per run (e.g., BE, NL, EMEDCAREERS).


Pricing

$0.05 per company per run. Charged as a PAY_PER_EVENT fee — one event per company entry processed.

Platform compute costs (CU) are charged separately by Apify based on your subscription plan. A typical run tracking 10 companies on Cheerio portals (DE, AT, UK) costs less than $0.01 in compute. Playwright portals (BE, NL, EMEDCAREERS) cost more per request.

Example costs (event fees only)

CompaniesFrequencyMonthly event cost
10Daily$15
50Daily$75
200Daily$300

Compute costs are typically negligible compared to event fees. Built-in caps (maxCompanies, maxTotalRequests) prevent unexpected overruns — companies that cannot be processed within the caps are skipped and flagged in output with costGuardTriggered: true.


Use cases

Recruitment Monitor target accounts and client companies for new job openings. Know the moment a company starts hiring for a specific role — before your competitors notice.

Sales intelligence Use hiring activity as a buying signal. Companies posting large volumes of new roles in engineering or operations are often investing in new tooling or scaling rapidly.

Investor due diligence Track portfolio company hiring velocity over time. Cross-reference hiring acceleration or deceleration against financial reports and market signals.

Competitor intelligence Monitor what roles your competitors are hiring for, in which locations, and at what volume. Detect strategic pivots early from changes in job mix.

Market research Track hiring trends across an industry sector by monitoring multiple companies simultaneously. Quantify labour demand shifts by role, region, and company size.


Known limitations

  • First run is always a baseline — all jobs appear as new, no removals are reported. Tracking becomes meaningful from the second run onwards.
  • SERP ranking changes between runs can cause the same job to appear or disappear from the fetched page window without actually being posted or removed. The default removedConfirmationRuns: 1 reduces noise from this.
  • strict_normalized matching may not capture subsidiaries or brands with distinct legal names (e.g. "Bosch Rexroth AG" vs "Bosch"). Use companyId or prefix mode for these cases.
  • Portals marked Required (totaljobs.com, retailchoice.com, emedcareers.com) incur additional residential proxy costs.
  • Playwright portals (BE, NL, EMEDCAREERS) cost more per request than Cheerio portals.
  • irishjobs.ie is not supported — the portal uses anti-scraping protections that block automated access.
  • Some portals may temporarily return errors due to transient network conditions. Rerunning usually resolves this.

Support

This actor is self-serve. Follow the onboarding flow above to validate your setup before enabling live tracking.

If you run into an issue, use the Issues tab on this actor's Apify page and include your run ID and input configuration.