# Bayt Jobs Scraper (Cheap) (`data_api/bayt-jobs-scraper-cheap`) Actor

Bayt job listings scraper that pulls job titles, companies, salaries, and locations from any Bayt.com search URL, pages through results automatically, so you get MENA job market data as clean JSON without manual browsing.

- **URL**: https://apify.com/data\_api/bayt-jobs-scraper-cheap.md
- **Developed by:** [Data API](https://apify.com/data_api) (community)
- **Categories:** Jobs, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.99 / 1,000 results

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

## Bayt Jobs Scraper

A lot of the Middle East and North Africa hiring market runs through Bayt.com, but the site gives you no clean way to get listings into a spreadsheet. So you copy role titles, employers, and salaries by hand, page after page. This scraper reads the pages for you. Hand it a Bayt search URL and it walks every results page, pulls the job title, hiring company, location, pay range, seniority, and posting date off each card, and gives them back as one row per listing. Point it at a single keyword search or a stack of country pages and let it work through the lot.

![Bayt Jobs Scraper](cover.jpg)

### What you get

Each job card on the page becomes one row with a steady shape, so your columns line up when the data lands in a sheet or database. Fields that an employer left blank come back as `null` rather than disappearing. Three groups per listing:

- **Role** — `roleTitle`, `roleSummary`, `seniorityLevel`, `experienceRange`, `payRange`, `workArrangement`, `nationalityRequirement`
- **Employer and location** — `employerName`, `employerUrl`, `employerLogo`, `cityName`, `countryName`
- **Listing metadata** — `postingId`, `postingUrl`, `postedEpoch`, `postedAt`, `postedLabel`, `quickApply`, `externalListing`, `collectedAt`

### Quick start

1. Hit **Try for free** and open the input form.
2. Paste one or more Bayt.com search URLs into **Bayt search URLs** (a country page, a keyword search, or a city-filtered result all work).
3. Set a **Results limit** per URL and raise the **Timeout (seconds)** if your runs hit slow responses.
4. Press **Start**, then export the results as JSON, CSV, Excel, or XML when the run finishes.

![How it works](how-it-works.jpg)

### Use cases

- **Salary benchmarking** — gather pay ranges for the same role across the UAE, Saudi Arabia, and Qatar to compare what each market pays
- **Hiring trend tracking** — re-run a search weekly to watch which employers are growing and where the openings cluster
- **Competitor recruitment monitoring** — follow a specific company's postings to read its expansion and skill priorities
- **Recruitment sourcing** — feed fresh listings into a downstream workflow that matches candidates to open roles
- **Labor market research** — build a MENA jobs dataset for HR analytics, reporting, or model training

### Input

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `searchUrls` | array of strings | Yes | One or more Bayt.com job search URLs. Country pages, keyword searches, and city-filtered results all work, as long as each points to bayt.com. |
| `resultsLimit` | integer | No | How many listings to pull from each URL before moving on. Default `20`. |
| `timeoutSeconds` | integer | No | Seconds to wait on each request before giving up. Default `45`; raise it if you see frequent timeouts. |

#### Example input

```json
{
    "searchUrls": [
        "https://www.bayt.com/en/saudi-arabia/jobs/marketing-manager-jobs/",
        "https://www.bayt.com/en/qatar/jobs/"
    ],
    "resultsLimit": 20,
    "timeoutSeconds": 45
}
```

### Output

Every job card becomes one row in the dataset, and each field is always present — values an employer left out come back as `null` so the data stays rectangular. Pull results as JSON, CSV, Excel, or XML from the Storage tab once the run ends.

#### Example output

```json
{
    "postingId": "5461128",
    "roleTitle": "Unreal Engine Gameplay Programmer",
    "postingUrl": "https://www.bayt.com/en/qatar/jobs/unreal-engine-gameplay-programmer-5461128/",
    "employerName": "Dunetech Studios",
    "employerUrl": "https://www.bayt.com/en/company/dunetech-studios-2304796/",
    "employerLogo": "https://secure.b8cdn.com/58x58/images/logo/96/2304796_logo_n.png",
    "cityName": "Doha",
    "countryName": "Qatar",
    "roleSummary": "A small independent studio is hiring a gameplay programmer to help build interactive experiences in Unreal Engine.",
    "seniorityLevel": "Mid career",
    "experienceRange": "3-5 Years of Experience",
    "payRange": null,
    "workArrangement": "Hybrid",
    "nationalityRequirement": null,
    "postedEpoch": 1781095408,
    "postedAt": "2026-06-12T10:43:28+00:00",
    "postedLabel": "21 hours ago",
    "quickApply": true,
    "externalListing": false,
    "collectedAt": "2026-06-29T08:12:34.123456+00:00"
}
```

#### Output fields

| Field | Type | Description |
|-------|------|-------------|
| `postingId` | string | Numeric identifier Bayt.com assigns to the listing |
| `roleTitle` | string | Position title printed on the listing card |
| `postingUrl` | string | Direct link to the full job page on Bayt.com |
| `employerName` | string | Company that posted the role |
| `employerUrl` | string | Link to the company's profile page on Bayt.com |
| `employerLogo` | string | Image link for the company logo |
| `cityName` | string | City the role is based in |
| `countryName` | string | Country the role is based in |
| `roleSummary` | string | Short blurb about the role shown on the results card |
| `seniorityLevel` | string | Experience tier such as Entry level, Mid career, or Senior executive |
| `experienceRange` | string | Years-of-experience span pulled from the seniority label |
| `payRange` | string | Compensation band when the employer chose to publish it |
| `workArrangement` | string | Remote or hybrid setup when the listing states one |
| `nationalityRequirement` | string | Citizenship or nationality condition noted on the card |
| `postedEpoch` | integer | Posting time as a Unix timestamp in seconds |
| `postedAt` | string | Posting time as an ISO 8601 UTC datetime |
| `postedLabel` | string | Relative posting time as written on the page, like 4 days ago |
| `quickApply` | boolean | True when the card offers a one-click apply button |
| `externalListing` | boolean | True when the role links out to a site other than Bayt.com |
| `collectedAt` | string | ISO 8601 UTC timestamp of when the record was captured |

### Tips for best results

- **Start small.** Run one URL with `resultsLimit` at 20 before committing to a big batch — URL-format mistakes show up in the first page.
- **Copy the URL straight from Bayt.** Browse to the search you want on bayt.com, apply your filters, then paste the address from the bar; every filter carries over.
- **Some fields stay empty by design.** `payRange`, `workArrangement`, `nationalityRequirement`, and `experienceRange` only fill in when the employer published them, so expect `null` on plenty of cards.
- **Raise `timeoutSeconds` to ~60** for large runs or when responses come back slowly.
- **Mind the page size.** Bayt shows roughly 20 to 30 cards per page, so at the default limit a run usually finishes inside one or two pages per URL.

### How can I use Bayt jobs data?

**How can I use the Bayt Jobs Scraper to compare salaries across MENA?**
Paste the same role search for several countries — say marketing manager in the UAE, Saudi Arabia, and Qatar — and the scraper returns each listing's `payRange`, `cityName`, `countryName`, and `seniorityLevel`. Group the rows by country to see how compensation shifts between markets and where the better-paying openings sit.

**How can I track who is hiring on Bayt.com over time?**
Save a search URL for an industry or company and run it on a schedule. Each pass returns `employerName`, `roleTitle`, `postedAt`, and `postedLabel`, so you can see which employers post most often and how quickly new roles appear. That gives you a rough read on hiring momentum without checking the site by hand.

**How can I build a Bayt job dataset for analytics or model training?**
Feed in a list of country or keyword search URLs and set `resultsLimit` to the depth you need. Every card comes back as one row with the role, employer, location, and posting metadata. Export the result to CSV or Excel and load it straight into your pipeline.

### Is it legal to scrape data?

Our actors are ethical and do not extract any private user data, such as email addresses or private contact information. They only extract what the user has chosen to share publicly. We therefore believe that our actors, when used for ethical purposes by Apify users, are safe.

However, you should be aware that your results could contain personal data. Personal data is protected by the GDPR in the European Union and by other regulations around the world. You should not scrape personal data unless you have a legitimate reason to do so. If you're unsure whether your reason is legitimate, consult your lawyers.

You can also read Apify's blog post on the [legality of web scraping](https://blog.apify.com/is-web-scraping-legal/).

### Support

Questions, feature requests, or a field you'd like added? Reach out at <data.apify@proton.me> and we'll get back to you.

# Actor input Schema

## `searchUrls` (type: `array`):

Paste one or more Bayt.com job search links. Anything from a country landing page to a keyword or city-filtered result works, as long as the address points to bayt.com.

## `resultsLimit` (type: `integer`):

How many listings to pull from each URL before moving on. Handy for trial runs or keeping spend in check.

## `timeoutSeconds` (type: `integer`):

How long to wait on each request before giving up. Bump it up if you hit frequent timeouts.

## Actor input object example

```json
{
  "searchUrls": [
    "https://www.bayt.com/en/saudi-arabia/jobs/marketing-manager-jobs/",
    "https://www.bayt.com/en/qatar/jobs/"
  ],
  "resultsLimit": 20,
  "timeoutSeconds": 45
}
```

# 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 = {
    "searchUrls": [
        "https://www.bayt.com/en/uae/jobs/accountant-jobs/"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("data_api/bayt-jobs-scraper-cheap").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 = { "searchUrls": ["https://www.bayt.com/en/uae/jobs/accountant-jobs/"] }

# Run the Actor and wait for it to finish
run = client.actor("data_api/bayt-jobs-scraper-cheap").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 '{
  "searchUrls": [
    "https://www.bayt.com/en/uae/jobs/accountant-jobs/"
  ]
}' |
apify call data_api/bayt-jobs-scraper-cheap --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/bASF3wWYodCAft2Ls/builds/XVSbxUoEtKdR8InD5/openapi.json
