# Gaming Jobs & Hiring Tracker — Entain, Evolution, Playtech (`zinin/gaming-industry-jobs-hiring-tracker`) Actor

Collect public Entain, Evolution and Playtech vacancies. Filter by country and title, export source-linked jobs, and compare complete observations for newly observed, changed and missing postings.

- **URL**: https://apify.com/zinin/gaming-industry-jobs-hiring-tracker.md
- **Developed by:** [Tim Zinin](https://apify.com/zinin) (community)
- **Categories:** Jobs, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.55 / 1,000 public vacancy delivereds

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/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

## Gaming Industry Jobs & Hiring Tracker

Collect public vacancies from the SmartRecruiters boards of **Entain, Evolution and Playtech**. Export jobs with employer, title, location, department, employment type and source links. Supply a previous snapshot to identify newly observed jobs, field changes and jobs no longer observed within the same filters.

Use the results for recruiting research, gaming industry vacancy feeds and changes in the mix of advertised roles. Coverage is limited to these three public boards; it does not include every vacancy at each employer. This is an independent tool, unaffiliated with the employers or SmartRecruiters.

### First run

Select an employer and leave the filters empty. Optionally set **Max total charge** in run options to bound paid delivery; API clients use `maxTotalChargeUsd`. A verified unset limit permits delivery within the source and size bounds. An explicit zero prevents paid rows. Check the price shown in the Actor's pricing panel before starting.

Example input for one employer:

```json
{
  "companies": ["Evolution"],
  "maxJobsPerCompany": 500,
  "countries": [],
  "titleKeywords": []
}
```

Omitting the input record or supplying `{}` selects all three employers, scans up to 500 source jobs per employer and applies no filters. The form starts with Evolution only for a smaller first run. There is no invented demo output: a normal run requests current public source data.

### Input

| Field | Meaning |
| --- | --- |
| `companies` | One to three of `Entain`, `Evolution`, `Playtech`. Defaults to all three. |
| `maxJobsPerCompany` | Source jobs scanned per employer, from 1 to 1000; default 500. This is not the number of filtered matches. |
| `countries` | Optional country codes such as `GE`, `MT`, `GB`. Up to 30 distinct codes. Empty selects all countries. |
| `titleKeywords` | Up to 10 words or phrases, each at most 100 characters. A title must contain at least one phrase, ignoring case. Empty selects all titles. |
| `previousSnapshot` | Optional JSON **string** containing the complete `SNAPSHOT` record from a previous run, up to 4 MiB of UTF-8 JSON. Leave empty for collection only. |

Countries and title filters both apply when supplied. Filtering happens after source traversal, so a small scan limit can miss matching jobs later in the board. Employers are processed alphabetically under a shared 90-second source collection limit, with at most 20 seconds per request. A slow earlier board can leave later employers incomplete. Use a run timeout of at least 180 seconds to allow collection and delivery.

### Results

The default Dataset contains rows with `recordType: "job"`. Each row includes:

- `company`, `employerName`, `jobId`, `jobKey`, `title`.
- `country`, `region`, `city`, `location`, `remote`, `hybrid`.
- `department`, `function`, `industry`, `employmentType`, `experienceLevel`.
- `releasedDate`, `jobUrl`, `sourceUrl`, and billing status at the time of writing.

Optional values absent from the source are `null`. `releasedDate` is the source publication timestamp, not a last-edit timestamp. Remote/hybrid flags are preserved when provided. The tool does not infer salary, employees, hires or headcount, and does not collect applicants or advertisement body text.

Diagnostics share the Dataset with jobs and have `recordType: "diagnostic"`. Filter by `recordType` when importing vacancies into a CRM or spreadsheet.

The default key-value store can contain:

| Record | Contents |
| --- | --- |
| `OUTPUT` | Outcome, per-employer coverage, observed dates, delivered counts and vacancy mix. Check this first. |
| `SNAPSHOT` | Versioned source snapshot for your next comparison. Available only after all collected job rows have been delivered and their result events confirmed. |
| `COMPARISON` | Detailed changes, present only when a previous snapshot was supplied and full delivery completed. Inspect `withheldCompanies` before using changes. |

`completed`, `partial` and `budget_stopped` normally finish with a SUCCEEDED run status; `source_unavailable` finishes with FAILED. A successful platform status alone does not mean complete source coverage. A cap, source error, changing total, duplicate, rejected row or unverified empty board makes that employer incomplete. Valid rows from incomplete boards remain usable and billable. Complete traversal of a changing board is not a transactional snapshot.

Common coverage reasons: `SOURCE_LIMIT` means the scan cap was reached; `SOURCE_DEADLINE` means the shared collection time expired; `EMPTY_BOARD_UNVERIFIED` means an empty board could not be confirmed; `SOURCE_TOTAL_CHANGED` means source counts changed during traversal; `DUPLICATE_POSTING_ID` means repeated source IDs were found. `INCOMPLETE_TRAVERSAL` means the returned pages did not account for the reported board total. These are coverage limitations, not proof that missing vacancies closed.

### Compare two observations

Download `SNAPSHOT` after the first run. On a later run, use the same employers, countries and title keywords, and pass the downloaded object as a JSON-encoded string in `previousSnapshot`:

```js
const input = {
  companies: previous.companies,
  countries: previous.filters.countries,
  titleKeywords: previous.filters.titleKeywords,
  maxJobsPerCompany: 500,
  previousSnapshot: JSON.stringify(previous)
};
```

Here `previous` is the parsed JSON downloaded from the first run. Observation windows must not overlap. Comparisons are withheld for employers whose earlier or current collection is incomplete. A changed filter scope is rejected.

Changes are `newly_observed`, `changed` and `no_longer_observed`. A job no longer observed may have left the filters or disappeared from the board; that does not establish a hire or closure. Field changes compare literal values, including differently formatted timestamps. Snapshot digests detect inconsistent data; they are not an authenticity signature.

### Pricing and recovery

One result event is requested for each delivered vacancy row. Repeat observations deliver and charge current vacancies again, including unchanged ones. Comparison artifacts do not request a separate result event. Diagnostics and zero matching jobs request no vacancy result events; any platform Actor-start charge displayed in the pricing panel can still apply.

Reserve enough of your Max total charge for any start event plus the expected vacancy rows. If the remaining limit cannot cover another job, delivery stops and full snapshot/comparison artifacts are withheld. Already delivered rows remain in the Dataset. A row's `unconfirmed_at_write` billing annotation is not a final payment receipt. Check `OUTPUT` when present and the run's settled event counters. On a failed run, OUTPUT can be absent even after rows have been delivered or charged; inspect the Dataset, run status message and settled counters directly.

Automatic retry, resurrection and migration recovery of the same run are unsupported. A durable run claim is saved before collection; a restarted container finding that claim stops before collecting or delivering again. This prevents automatic replay but does not complete interrupted work. After an uncertain storage or charging response, inspect its Dataset, artifacts and charges before starting a new run; a new run can deliver and charge overlapping jobs again. Full snapshots are limited to 4 MiB; comparison exports to 9 MiB. These are product limits.

### Sources and support

Data comes from the [SmartRecruiters public Posting API](https://developers.smartrecruiters.com/docs/posting-api) for the three named employers. Source totals and observation dates are included so you can assess coverage.

If output is incomplete or a field appears incorrect, open an Actor issue with the run link, employer and expected behavior. Do not include credentials or applicant data.

# Actor input Schema

## `companies` (type: `array`):

Choose public boards. Omitted input selects all three; the form begins with Evolution for a smaller first run.

## `maxJobsPerCompany` (type: `integer`):

Scanned source rows before filtering, not the number of matched vacancies. Reaching this cap before the full board makes coverage incomplete.

## `countries` (type: `array`):

Two-letter country codes, for example GE, MT or GB. Empty selects all. Case is ignored.

## `titleKeywords` (type: `array`):

Match any phrase in the title, ignoring case. Up to 100 characters each. Country filters also apply.

## `previousSnapshot` (type: `string`):

Paste the complete JSON from a previous SNAPSHOT record, up to 4 MiB. Use identical employers/country/title filters. In API input this field is a JSON string, not an object.

## Actor input object example

```json
{
  "companies": [
    "Evolution"
  ],
  "maxJobsPerCompany": 500,
  "countries": [],
  "titleKeywords": [],
  "previousSnapshot": ""
}
```

# Actor output Schema

## `results` (type: `string`):

Filter recordType=job for vacancies. Diagnostics describe partial coverage and budget stops.

## `summary` (type: `string`):

Check deliveryComplete and coverage when present. May be absent even after rows were delivered or charged on a failed run; inspect Dataset, status message and settled run counters.

## `snapshot` (type: `string`):

Only saved after complete delivery. May contain incomplete source coverage; comparisons for those employers are withheld.

## `comparison` (type: `string`):

Present only if requested and delivery completed. Inspect withheldCompanies.

# 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 = {
    "companies": [
        "Evolution"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("zinin/gaming-industry-jobs-hiring-tracker").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 = { "companies": ["Evolution"] }

# Run the Actor and wait for it to finish
run = client.actor("zinin/gaming-industry-jobs-hiring-tracker").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 '{
  "companies": [
    "Evolution"
  ]
}' |
apify call zinin/gaming-industry-jobs-hiring-tracker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,zinin/gaming-industry-jobs-hiring-tracker"
        }
    }
}
```

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/1TzmuGu70qfyTryQI/builds/5zPlybPBBFsJuKLo0/openapi.json
