# Bayt Jobs Scraper - Middle East (MENA) Job Listings (`haketa/bayt-scraper`) Actor

Scrape jobs from Bayt.com, the #1 job site in the Middle East: title, company, location, salary, experience, employment type, posting date and full description across UAE, Saudi Arabia, Egypt, Qatar, Kuwait and 30+ MENA countries. Export to JSON, CSV, Excel.

- **URL**: https://apify.com/haketa/bayt-scraper.md
- **Developed by:** [Haketa](https://apify.com/haketa) (community)
- **Categories:** Jobs, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.75 / 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 🌍

**Extract job listings from Bayt.com — the #1 job site in the Middle East — into clean, structured data.** Search by keyword and country and export thousands of jobs with company, location, **salary, years of experience, employment type, posting date, the full description** and the apply link — across the **UAE, Saudi Arabia, Egypt, Qatar, Kuwait, Jordan** and 30+ MENA markets. Built for recruiters, job boards, salary benchmarking and labour-market research.

[![Actor](https://img.shields.io/badge/Apify-Actor-00b04f?style=flat-square\&logo=apify)](https://apify.com)
[![Region](https://img.shields.io/badge/Region-Middle%20East%20%2F%20MENA-006c35?style=flat-square)](https://apify.com)
[![Salary](https://img.shields.io/badge/Salary-Structured-brightgreen?style=flat-square)](https://apify.com)
[![Full description](https://img.shields.io/badge/Description-Full%20text-success?style=flat-square)](https://apify.com)
[![Output](https://img.shields.io/badge/Output-JSON%20%7C%20CSV%20%7C%20Excel-2b7489?style=flat-square)](https://apify.com)
[![Pagination](https://img.shields.io/badge/Pagination-Automatic-blue?style=flat-square)](https://apify.com)
[![Countries](https://img.shields.io/badge/Countries-30%2B-orange?style=flat-square)](https://apify.com)
[![No code](https://img.shields.io/badge/No--code-Friendly-9cf?style=flat-square)](https://apify.com)
[![Maintained](https://img.shields.io/badge/Maintained-Yes-brightgreen?style=flat-square)](https://apify.com)

***

### 🎯 What does Bayt Jobs Scraper do?

Bayt.com is the leading employment marketplace in the Middle East and North Africa, with tens of thousands of active vacancies across the Gulf and wider MENA region. This actor turns any Bayt search into a structured dataset you can download or feed into your own tools.

Give it a **search term** (and optionally a **country**) — or a **Bayt search URL** — and it will:

- 🔎 Open the Bayt results page and **read every job** on it
- 📄 Automatically **paginate** through all result pages until it reaches your limit
- 🏢 Capture **company, company profile link, city and country**
- 💰 Add **structured salary** (min / max / currency), **experience** and **employment type** *(detail mode)*
- 📝 Include the **full job description** *(detail mode)*
- 🧹 Return **clean, deduplicated, structured records** — no HTML, no clutter
- ⬇️ Export to **JSON, CSV, Excel, HTML or via API** in one click

No login, no browser extensions, no manual copy-paste.

***

### ✨ Key features

| Feature | Description |
| --- | --- |
| **Keyword + country search** | Type keywords and pick a country (UAE, Saudi Arabia, Egypt…) or search internationally. |
| **URL input** | Paste any Bayt search URL to scrape a pre-filtered result set. |
| **Structured salary** | Minimum, maximum and currency for jobs that publish pay *(detail mode)*. |
| **Experience & type** | Required years of experience, education level and employment type *(detail mode)*. |
| **Full description** | The complete job description text *(detail mode)* — ready for search and NLP. |
| **Company data** | Company name, profile link and stable company ID for enrichment. |
| **30+ MENA markets** | UAE, Saudi Arabia, Egypt, Qatar, Kuwait, Jordan, Lebanon, Bahrain, Oman and more. |
| **Automatic pagination** | Walks through all result pages up to your `maxItems` limit. |
| **Deduplicated output** | Each job appears once, identified by its unique Bayt job ID. |
| **Clean exports** | JSON, CSV, Excel, HTML table, RSS or JSON API. |

***

### 📥 Input

The actor accepts a simple, no-code input form.

#### Option A — by keyword & country (easiest)

```json
{
    "searchTerms": ["software engineer", "accountant"],
    "country": "uae",
    "maxItems": 200
}
```

#### Option B — with full details

```json
{
    "searchTerms": ["marketing manager"],
    "country": "saudi-arabia",
    "includeDescription": true,
    "maxItems": 300
}
```

#### Option C — by search URL

```json
{
    "startUrls": [
        { "url": "https://www.bayt.com/en/uae/jobs/data-analyst-jobs/" }
    ],
    "maxItems": 500
}
```

#### Input parameters

| Field | Type | Description |
| --- | --- | --- |
| `searchTerms` | array | Job keywords to search. |
| `country` | string | Country to search within (`international`, `uae`, `saudi-arabia`, `egypt`, `qatar`, `kuwait`, …). |
| `startUrls` | array | Bayt search-results URLs (scraped in addition to search terms). |
| `includeDescription` | boolean | Fetch each detail page for full description, salary, experience and employment type. Default `false`. |
| `maxItems` | integer | Maximum number of jobs to collect. Default `200`. |
| `proxyConfiguration` | object | Proxy settings. Apify Proxy is recommended and on by default. |

***

### 📤 Output

Each job is returned as a clean JSON object (fields marked *detail* appear when **Include full description & salary** is enabled):

```json
{
    "jobId": "5475027",
    "title": "Full Stack Developer",
    "url": "https://www.bayt.com/en/saudi-arabia/jobs/full-stack-developer-5475027/",
    "company": "Tabeq",
    "companyId": "2312631",
    "companyUrl": "https://www.bayt.com/en/company/tabeq-2312631/",
    "city": "Riyadh",
    "country": "Saudi Arabia",
    "postedAgo": "5 days ago",
    "snippet": "Summary: Elevate your career as a Full Stack Developer…",
    "description": "Overview of the role: …",
    "salaryMin": 500,
    "salaryMax": 1000,
    "salaryCurrency": "USD",
    "salaryPeriod": "MONTH",
    "employmentType": "FULL_TIME",
    "yearsExperience": 3,
    "educationLevel": "bachelor degree",
    "postedDate": "2026-08-08",
    "validThrough": "2026-10-07",
    "jobCountryCode": "SA",
    "totalOpenings": 1,
    "isDirectApply": true
}
```

#### Output fields

| Field | Type | Description |
| --- | --- | --- |
| `jobId` | string | Unique Bayt job ID. |
| `title` | string | Job title. |
| `url` | string | Direct link to the job. |
| `company` / `companyId` / `companyUrl` | | Company name, ID and profile link (ID/URL when the company is public). |
| `city` / `country` | string | Job location. |
| `postedAgo` | string | Relative posting date (e.g. "5 days ago"). |
| `snippet` | string | Short summary from the results page. |
| `description` | string | Full job description *(detail)*. |
| `salaryMin` / `salaryMax` / `salaryCurrency` / `salaryPeriod` | | Structured salary *(detail, when published)*. |
| `employmentType` | string | e.g. FULL\_TIME, PART\_TIME *(detail)*. |
| `yearsExperience` | number | Required experience in years *(detail)*. |
| `educationLevel` | string | Required education *(detail)*. |
| `postedDate` / `validThrough` | string | Absolute posting and expiry dates *(detail)*. |
| `jobCountryCode` | string | ISO country code *(detail)*. |
| `totalOpenings` | number | Number of vacancies *(detail)*. |
| `isDirectApply` | boolean | Whether direct apply is available *(detail)*. |

You can download the dataset as **JSON, CSV, Excel, HTML, RSS or XML**, or fetch it programmatically through the Apify API.

***

### 🚀 How to use Bayt Jobs Scraper (step by step)

1. Click **Try for free** / **Start**.
2. Type one or more **search terms** and pick a **country** — or paste a **Bayt search URL**.
3. (Optional) Enable **Include full description & salary** for richer data.
4. Set **maxItems** to how many jobs you want.
5. Click **Save & Start**.
6. When the run finishes, open the **Dataset** tab and **Export** to your preferred format — or grab it via API.

That's it. No code required.

***

### 💡 Use cases

- **Recruitment & sourcing** — Track who is hiring for which roles across the Gulf and MENA, and reach out directly.
- **Salary benchmarking** — Build compensation datasets by role, country and experience for the region.
- **Job boards & aggregators** — Feed fresh MENA vacancies into your own portal or newsletter.
- **Market & labour research** — Measure demand by country, sector, seniority and employment type.
- **Competitive intelligence** — Monitor a competitor's open roles across the region to infer growth and priorities.
- **HR & talent teams** — Benchmark your own postings against the live regional market.

***

### 🌍 Countries covered

The Gulf and wider MENA region, including **United Arab Emirates, Saudi Arabia, Egypt, Qatar, Kuwait, Jordan, Lebanon, Bahrain, Oman** and more — or search **internationally** across all of them at once. Use the `country` option or paste any country-specific Bayt URL.

***

### 🔌 Integrations & automation

Because this runs on Apify, you can:

- 📅 **Schedule** runs (hourly, daily, weekly) to keep a live feed of new vacancies.
- 🔗 Push results to **Google Sheets, Airtable, Slack, Zapier, Make, or any webhook**.
- 🧩 Call it from your backend with the **Apify API** and SDKs (JavaScript / Python).
- 🔔 Use **webhooks** to trigger downstream workflows the moment a run completes.

#### Call via API (example)

```bash
curl -X POST "https://api.apify.com/v2/acts/YOUR_ACTOR_ID/runs?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
        "searchTerms": ["accountant"],
        "country": "uae",
        "maxItems": 200
      }'
```

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

const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('YOUR_ACTOR_ID').call({
    searchTerms: ['software engineer'],
    country: 'saudi-arabia',
    includeDescription: true,
    maxItems: 500,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

***

### ❓ FAQ

**Do I need a Bayt account or API key?**
No. Just provide a search term or a Bayt URL.

**Which countries can I scrape?**
The whole MENA region — UAE, Saudi Arabia, Egypt, Qatar, Kuwait, Jordan, Lebanon, Bahrain, Oman and more — or `international` for all at once.

**Does it include salary?**
Yes, for jobs that publish it. Enable **Include full description & salary** to get structured `salaryMin` / `salaryMax` / `salaryCurrency`, plus experience, education and employment type.

**Does it include the full job description?**
Yes — enable detail mode and each job's complete description is fetched.

**Why are some company IDs missing?**
Some employers post as "Confidential Company" and don't expose a public profile. The company name is still captured; the ID/URL is only present for public companies.

**Are results deduplicated?**
Yes. Each job is uniquely identified by its Bayt job ID and appears once per run.

**What formats can I export?**
JSON, CSV, Excel, HTML, RSS and XML — via the dashboard or the API.

**How do I keep data fresh?**
Schedule the actor to run on the interval you need; each run returns the current live listings.

***

### 📌 Tips for best results

- **Start narrow, then widen.** Test one keyword and a small `maxItems`, confirm the fields, then scale up.
- **Use country for focus.** Pick a specific market for local hiring intelligence, or `international` for the whole region.
- **Enable detail mode for salary & descriptions.** The list is fast; detail mode adds pay, experience and full text.
- **Use URLs for precise filters.** Apply filters on Bayt itself, then paste the URL.
- **Schedule for freshness.** The market moves daily; a scheduled run keeps your dataset current.

***

### ⚖️ Legal & responsible use

This actor is intended for lawful data collection such as market research, analytics and recruitment. You are responsible for how you use the collected data. Only collect publicly available information, respect the target website's Terms of Service and `robots.txt`, and comply with all applicable laws and regulations, including data-protection rules when processing any personal data. Do not use the data for spam or any unlawful purpose. This actor is an independent tool and is **not affiliated with, endorsed by, or connected to Bayt.com** or its subsidiaries. All trademarks belong to their respective owners.

***

### 🛟 Support

Questions, feature requests or an issue with the data? Open an issue on the actor's page — feedback is welcome and helps improve the tool.

***

⭐ **If this actor saves you time, please leave a review — it really helps!**

# Actor input Schema

## `searchTerms` (type: `array`):

One or more job keywords to search on Bayt (e.g. software engineer, accountant, sales manager). The scraper paginates through all results automatically.

## `country` (type: `string`):

Country to search within when using search terms. Use 'international' for all countries, or a country slug like uae, saudi-arabia, egypt, qatar, kuwait, jordan, lebanon, bahrain, oman.

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

Paste Bayt.com search-results URLs (e.g. https://www.bayt.com/en/uae/jobs/accountant-jobs/). Use these for pre-filtered searches. When provided, these are scraped in addition to the search terms.

## `includeDescription` (type: `boolean`):

Fetch each job's detail page to add the full description, structured salary (min/max/currency), employment type, experience and education. More complete, but slower.

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

Maximum number of jobs to collect across all search terms and URLs.

## `proxyConfiguration` (type: `object`):

Proxy settings. Residential proxies are enabled by default and are recommended for reliable, uninterrupted results.

## Actor input object example

```json
{
  "searchTerms": [
    "software engineer"
  ],
  "country": "international",
  "includeDescription": false,
  "maxItems": 200,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `jobId` (type: `string`):

Bayt job ID

## `title` (type: `string`):

Job title

## `url` (type: `string`):

Job page URL

## `company` (type: `string`):

Hiring company

## `companyUrl` (type: `string`):

Company profile URL

## `city` (type: `string`):

Job city

## `country` (type: `string`):

Job country

## `postedAgo` (type: `string`):

Relative posting date

## `salaryMin` (type: `string`):

Minimum salary (with description)

## `salaryMax` (type: `string`):

Maximum salary (with description)

## `employmentType` (type: `string`):

Employment type (with description)

## `yearsExperience` (type: `string`):

Required experience (with description)

## `description` (type: `string`):

Full description (with 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 = {
    "searchTerms": [
        "software engineer"
    ],
    "maxItems": 200
};

// Run the Actor and wait for it to finish
const run = await client.actor("haketa/bayt-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 = {
    "searchTerms": ["software engineer"],
    "maxItems": 200,
}

# Run the Actor and wait for it to finish
run = client.actor("haketa/bayt-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 '{
  "searchTerms": [
    "software engineer"
  ],
  "maxItems": 200
}' |
apify call haketa/bayt-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,haketa/bayt-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/YyiDrIsjZUmW9JDZn/builds/4Q2Nh4nOL4eg5CK5u/openapi.json
