# Manatal Jobs Monitor & Scraper (`cliqtomedia/manatal-jobs-monitor-scraper`) Actor

Get public Manatal jobs with full descriptions and apply links. Compare complete careers-page.com snapshots to track new, changed and removed postings.

- **URL**: https://apify.com/cliqtomedia/manatal-jobs-monitor-scraper.md
- **Developed by:** [Cliqto Media](https://apify.com/cliqtomedia) (community)
- **Categories:** Jobs, Business, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.50 / 1,000 job record saveds

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?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

Get public Manatal jobs from known careers-page.com boards. Read full job descriptions and apply links, or track job changes between complete snapshots. Start with `{"tenants":["manatal"]}`. Pricing is $0.04 per run plus $0.0045 per saved job row; empty and unchanged runs pay only the start fee.

![Manatal Jobs Monitor and Scraper](https://api.apify.com/v2/key-value-stores/vtgxhwdUGlfo5NPSZ/records/hero.png)

### Contents

- [What it does](#what-it-does)
- [Data you get](#data-you-get)
- [Quick start](#quick-start)
- [Input fields](#input-fields)
- [Input examples](#input-examples)
- [Output example](#output-example)
- [Output fields](#output-fields)
- [Pricing](#pricing)
- [Use cases](#use-cases)
- [Monitoring](#monitoring)
- [API and integrations](#api-and-integrations)
- [Limits and partial results](#limits-and-partial-results)
- [Troubleshooting](#troubleshooting)
- [FAQ](#faq)
- [Related Actors](#related-actors)
- [Support](#support)

### What it does

Add up to 3 known Manatal board slugs or board URLs. The Actor reads their public job lists with descriptions. It returns current jobs in `scrape` mode. In `monitor` mode, it compares complete snapshots and returns new, changed and removed jobs.

The first monitor run makes a baseline and returns the current jobs. Later runs return only changes. The Actor reads a documented public Manatal API without a login or API key.

### Data you get

- Job title, department, location and contract type.
- Public job ID and numeric ID.
- Full description as HTML and plain text, when the source provides it.
- Job page and apply links.
- Change type, content hash and scan time.

The Dataset is for job rows. The Key-value store contains:

| Record | Use |
|---|---|
| `OUTPUT` | Overall result and status for each board. |
| `RUN_SUMMARY` | Scan counts, saved rows, charged rows, requests, retries and limits. |
| `SNAPSHOT` | Full unfiltered jobs for the next run. Check `complete: true`. |
| `CHANGES` | Full change counts and the change rows delivered to the Dataset. |

### Quick start

1. Open **Input** and add `manatal` to **Career board slugs or URLs**.
2. Keep `mode` as `scrape` and `maxResults` as `315`.
3. Set a maximum cost of at least $0.20 for this example.
4. Click **Start**.
5. Open **Output** and the Dataset. Check `title`, `source_job_id` and `description_text`.
6. Check `OUTPUT.status` and each board status before using the results.

The board had 32 jobs in our check. Public job counts can change. The form prefills `manatal`; API calls must supply `tenants`.

### Input fields

| Key | Type | Default / prefill | Range | Effect | Recommendation |
|---|---|---|---|---|---|
| `tenants` | string array | Required; form prefill `["manatal"]` | 1–3 entries | Selects known public boards. Slugs or HTTPS careers-page.com board URLs. Repeated boards count once. | Start with one board. |
| `mode` | string | `scrape` | `scrape`, `monitor` | Returns current jobs or snapshot changes. | Use scrape for exports; monitor for changes. |
| `previousRunId` | string | Not set | 17 letters/numbers; monitor only | Reads a complete snapshot from a successful run of this Actor. The boards must match. | Omit for the first monitor run. |
| `maxResults` | integer | `315` | 1–315 | Limits output rows after the full scan. A capped result is partial. | Keep 315 for full output. |
| `titleContains` | string | Empty | 0–100 characters | Literal title filter; case is ignored. Applied after the full scan and change check. | Leave empty to get all matching jobs or changes. |

A full board URL such as `https://www.careers-page.com/manatal/` is accepted. Job URLs, candidate portals, custom domains, HTTP URLs and unknown input fields are rejected. Filters and output limits do not reduce the full source scan.

### Input examples

#### Current jobs

```json
{"tenants":["manatal"],"mode":"scrape"}
```

#### Known boards with a title filter

```json
{"tenants":["manatal","1st-jobscom"],"titleContains":"Engineer","maxResults":315}
```

#### First monitor run

```json
{"tenants":["manatal"],"mode":"monitor"}
```

For the next run, add `previousRunId` with the first run's ID. Use the same boards. The previous run may use scrape or monitor mode, but its `SNAPSHOT.complete` must be true.

### Output example

These selected fields come from a real scrape run. Each full row has all fields in the next table.

```json
{
  "tenant": "manatal",
  "company_name": "Manatal Co LTD",
  "source_job_id": "L8597V4V",
  "title": "Business Development Internship (12PM - 9PM)",
  "department": "Customer Success",
  "location": "Bangkok, Bangkok, Thailand",
  "employment_type": "full_time",
  "url": "https://www.careers-page.com/manatal/job/L8597V4V",
  "apply_url": "https://www.careers-page.com/manatal/job/L8597V4V/apply",
  "change_type": "current"
}
```

### Output fields

All fields are present. Missing source values use `null`, not an empty string. HTML and text examples below are excerpts.

| Field | Type | Null? | Example | Meaning |
|---|---|---|---|---|
| `tenant` | string | No | manatal | Board slug. |
| `company_name` | string | No | Manatal Co LTD | Actual public board owner name. An agency board can list jobs for other employers. |
| `source_platform` | string | No | manatal | Always manatal. |
| `source_job_id` | string | No | L8597V4V | Public job hash, unique within a board. |
| `source_numeric_id` | integer | No | 1333846 | Numeric Manatal job ID. |
| `title` | string | No | Business Development Internship (12PM - 9PM) | Public position name. |
| `department` | string/null | Yes | Customer Success | Public organization name, when shown. |
| `location` | string/null | Yes | Bangkok, Bangkok, Thailand | Display location from the source. |
| `city` | string/null | Yes | Bangkok | City, if provided. |
| `state` | string/null | Yes | Bangkok | State or region, if provided. |
| `country` | string/null | Yes | Thailand | Country, if provided. |
| `is_remote` | boolean/null | Yes | `null` | Source remote flag. Null means unknown. |
| `employment_type` | string/null | Yes | full_time | Source contract label, such as full_time. |
| `url` | string | No | https://www.careers-page.com/manatal/job/L8597V4V | Public job page. |
| `apply_url` | string | No | https://www.careers-page.com/manatal/job/L8597V4V/apply | Public application link. The Actor does not open or submit it. |
| `posted_at` | string/null | Yes | `null` | Null: this list API does not publish a posting date. |
| `source_url` | string | No | https://www.careers-page.com/manatal | Public company board URL. |
| `record_type` | string | No | job_record | Always job_record. |
| `source` | string | No | manatal-jobs-monitor-scraper | Always manatal-jobs-monitor-scraper. |
| `observed_at` | string | No | 2026-10-04T16:32:09.795Z | UTC time of this scan; not a posting date. |
| `description_html` | string/null | Yes | <p>Manatal...</p> (excerpt) | Full public source description as HTML. Treat it as untrusted content. |
| `description_text` | string/null | Yes | Manatal... (excerpt) | Description as readable text with HTML removed. |
| `content_hash` | string | No | c9faf6e98a7f4b510810e407d8a2e66079cdc6fd4481886cf8196384a45c047d | SHA-256 of job content; excludes fetch time and change_type. |
| `change_type` | string | No | current | current, baseline, new, changed or removed. |

For a `removed` row, job details come from the previous complete snapshot. `observed_at` is the new scan time. A removed row means the posting is no longer on that board; it does not prove a hire. `is_remote: null` does not mean on-site.

### Pricing

| Event | Price |
|---|---:|
| Start a run | $0.04 |
| Save a current job or a detected change to the Dataset | $0.0045 |

The price is the same across plan tiers. The row event is charged once after the row is saved. Duplicate inputs do not add rows. No row fee is charged for an empty board, no matching titles or no changes. The $0.04 start fee still applies, including failed or partial runs. Platform usage is included in PPE pricing for paid customer runs. Your own developer runs show platform usage costs.

| Saved rows in one run | Event total |
|---:|---:|
| 0 | $0.04 |
| 1 | $0.0445 |
| 10 | $0.085 |
| 100 | $0.49 |
| 315 | $1.4575 |

1,000 rows need at least four runs because each run is limited to 315 source jobs. At four starts, the event total is $4.66. This is arithmetic for several runs, not a tested single-run capacity. Set the maximum run cost to cover the start fee and the rows you need. The minimum accepted cost limit is $0.05. A cost stop can leave a partial result.

### Use cases

| Task | Mode | Useful fields |
|---|---|---|
| Build an export for known company boards | scrape | title, description_text, url |
| Check hiring signals | monitor | tenant, change_type, observed_at |
| Follow job edits | monitor | source_job_id, content_hash, description_text |
| Track agency job lists | scrape | company_name, department, location |

### Monitoring

1. Run monitor mode without `previousRunId`.
2. Check the run succeeded and `SNAPSHOT.complete` is true.
3. Add that run ID as `previousRunId` for the next run.
4. Read new, changed and removed rows. Zero rows can mean no changes.
5. Use the latest successful complete run as your next baseline.

Only the same set of boards can be compared. An incomplete, missing or foreign Actor snapshot is rejected. If any current board is incomplete, all monitor changes are disabled. A 404 is not treated as mass removal. A complete empty board can report removed jobs when a complete earlier snapshot had jobs.

You can create a schedule in Apify Console yourself. After each complete run, update the baseline ID in your next input or automation. This Actor does not create schedules or webhooks, and it does not advance the baseline automatically. Each run has the start fee. Use a reasonable interval for the source.

### API and integrations

Run `cliqtomedia/manatal-jobs-monitor-scraper` with the same JSON input through the [Apify API](https://docs.apify.com/api/v2/actors-runs-post). After the run ends, use its `defaultDatasetId` to download JSON or CSV through the Dataset API. Read `OUTPUT` from its Key-value store to check completeness.

The [Apify MCP server](https://docs.apify.com/platform/integrations/mcp) can run Actors from an AI client. Pass this Actor name and the same input. Availability follows your account access and Actor visibility. You can connect Dataset results to your own integrations. No integration is created by this Actor.

### Limits and partial results

- Up to 3 known boards and 315 source jobs in total per run. Live checks covered 315 jobs from 3 boards.
- 256 MB memory and a 90-second internal source deadline. A separate 120-second process limit also bounds initialization, storage and shutdown. A forced stop can leave missing terminal records; check run status.
- At most 20 HTTP attempts, 2 retries per temporary failure, 2 MiB per response and 8 MiB total response data.
- All boards are read before output filtering. More source jobs can hit the scan limit even if the filter matches none.
- `complete`: all boards and matching output are complete. An empty successful board uses this status.
- `partial`: a board, source page, output limit or charge limit stopped a full result. Check the board reasons.
- `not_found`: the requested board returned 404. The run fails if all boards are missing.
- `error`: invalid input, source, snapshot or storage failure. It does not mean there are no jobs.

A source list can change while pages are read. Count changes, missing pages and conflicting duplicates prevent a complete snapshot. Equal-count source changes during a scan may remain undetected: the source does not offer an atomic snapshot. A page size or deadline failure also prevents a valid monitor baseline. Job descriptions are public source text and can include HTML; sanitize it before displaying it in your own website.

Company discovery, applications, candidate accounts, private ATS data, salary inference and posting-date inference are outside this Actor. `posted_at` stays null. Only known boards hosted on careers-page.com are accepted. Memory above 256 MB and non-positive or unbounded platform timeouts are rejected before source work. Finite platform timeouts of 300 seconds or longer are accepted; they do not increase the internal work limits. Restarting or resurrecting a used run is not supported; start a new run with a complete baseline instead.

### Troubleshooting

| What you see | What to check | Next action |
|---|---|---|
| `not_found` | Board slug and public board URL | Check the careers-page.com URL and correct the slug. |
| Empty Dataset, `complete` | Filter or no changes | Read `RUN_SUMMARY` and `CHANGES.counts`. |
| `partial`, `RESULT_LIMIT` | maxResults | Use 315 or a narrower filter; start a new run. |
| `partial`, `CHARGE_LIMIT` | Maximum cost | Allow start fee plus enough row events; run again. |
| `SCAN_LIMIT` | Total source jobs | Use fewer or smaller boards. A title filter will not reduce source work. |
| `INCOMPATIBLE_SNAPSHOT` | Same Actor, boards, complete flag | Pick a complete successful baseline. |
| `PREVIOUS_RUN_NOT_COMPATIBLE` | Previous run status and owner access | Use a successful run of this Actor. |
| `error` or missing records | Source availability or storage | Check logs; retry in a new bounded run. Do not use it as a baseline. |

### FAQ

**Do I need a Manatal API key?** No. The Actor reads the public career-page API.

**Does it find company boards for me?** No. Supply known slugs or board URLs.

**Does it download applications or candidate data?** No. It reads job postings. Apply links are returned as links only.

**Are full descriptions included?** Yes, when the public list provides them. Both HTML and readable text are saved.

**Are unchanged jobs charged in monitor mode?** No. Monitor emits changes only after the first baseline. An unchanged run pays the start fee.

**Is a partial snapshot safe for removal checks?** No. The Actor rejects it as a baseline and disables changes when the current scan is incomplete.

**Does maxResults reduce the scan cost?** No. It limits output after reading source jobs.

### Related Actors

For other public boards, use our [Greenhouse Jobs Monitor](https://apify.com/cliqtomedia/greenhouse-jobs-monitor-scraper) or [Lever Jobs Scraper](https://apify.com/cliqtomedia/lever-jobs-scraper).

### Support

Use this Actor's Issues tab. Include the run ID, public board slug and expected result. Share no tokens, candidate data or private ATS records. This Actor is maintained by CliqtoMedia and is not affiliated with Manatal. Source endpoint details are in the [Manatal documentation](https://developers.manatal.com/reference/career-page_jobs_list).

# Actor input Schema

## `tenants` (type: `array`):

Add 1–3 known public Manatal boards. Use a slug such as manatal or a full HTTPS careers-page.com board URL. Job URLs are not supported. Repeated boards count once.

## `mode` (type: `string`):

Scrape returns current jobs. Monitor returns baseline jobs on the first run, then only new, changed and removed jobs.

## `previousRunId` (type: `string`):

Optional for monitor. Copy the 17-character run ID from this Actor. The previous run must succeed, have a complete snapshot, and use the same boards. Omit to start a baseline.

## `maxResults` (type: `integer`):

Return 1–315 rows. All source jobs are read before this limit. A capped result is partial and cannot be used as a new monitor baseline.

## `titleContains` (type: `string`):

Optional literal text, up to 100 characters. Case is ignored. The filter runs after the full scan and change check. Empty means all titles.

## Actor input object example

```json
{
  "tenants": [
    "manatal"
  ],
  "mode": "scrape",
  "maxResults": 315,
  "titleContains": ""
}
```

# Actor output Schema

## `jobs` (type: `string`):

No description

## `output` (type: `string`):

No description

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

No description

## `changes` (type: `string`):

No description

## `snapshot` (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 = {
    "tenants": [
        "manatal"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("cliqtomedia/manatal-jobs-monitor-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 = { "tenants": ["manatal"] }

# Run the Actor and wait for it to finish
run = client.actor("cliqtomedia/manatal-jobs-monitor-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 '{
  "tenants": [
    "manatal"
  ]
}' |
apify call cliqtomedia/manatal-jobs-monitor-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,cliqtomedia/manatal-jobs-monitor-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/UU3xmRkiKZrkGRssc/builds/hbb9n26lkvjPu4lO9/openapi.json
