Bayt Scraper - Gulf & MENA Jobs & Salary Data API
Pricing
from $2.23 / 1,000 job listings
Bayt Scraper - Gulf & MENA Jobs & Salary Data API
Scrape public Bayt.com job listings across all 18 Gulf and MENA markets. Parsed salary ranges, exact posting dates, seniority, and an aggregated-listing flag. No API key.
Pricing
from $2.23 / 1,000 job listings
Rating
0.0
(0)
Developer
ParseForge
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
3 days ago
Last modified
Categories
Share
Bayt Scraper - Gulf & MENA Jobs & Salary Data API
A Bayt job board scraper for salary and hiring analysis across all 18 Gulf and MENA markets. Scrape public job listings from Bayt.com, the Middle East's largest job board — from the UAE and Saudi Arabia to Egypt, Morocco, and Pakistan — filtered by date, employment type, seniority, industry, or employer, the same way Bayt's own search filters them. Every listing comes with its published salary range, seniority, exact posting date, and a flag telling you whether Bayt hosts the job or aggregated it from elsewhere. No login or API key. Export to CSV, JSON, Excel, or XML.
Bayt has no public API. Search pages sit behind Cloudflare and sort by relevance, which quietly mixes in jobs posted months ago. This Actor reads the public search feeds directly, sorts by date so you get current openings, parses salary strings into numbers, and returns every match in one fixed schema.
| Who uses it | What they scrape Bayt for |
|---|---|
| Recruiters | Which roles a city is hiring for right now, and who is posting them |
| Talent-intelligence teams | Salary benchmarks by role, seniority, and Gulf market |
| Compensation analysts | Published pay ranges in AED, SAR, QAR, and USD |
| Market researchers | Which companies are expanding into which MENA markets |
| Job boards and aggregators | Public listings for approved aggregation workflows |
What it does
This Actor collects Bayt job listings by keyword, country, and city, and returns each one as a flat row. Every listing carries:
- 🧾 Core fields: title, company, location, city, country, and canonical job URL.
- 💰 Salary: the published range plus parsed
salaryMin,salaryMax, andsalaryCurrency. - 📅 Exact dates:
postedAtas a real ISO 8601 timestamp, not "15 days ago". - 🚩 Flags: remote, featured, and aggregated-from-third-party.
- 📝 Summary: the role summary shown on the listing card.
- 🏢 Employer: company name and its Bayt company-profile URL.
Results export to CSV, JSON, Excel, or XML, or stream from the API.
What you can do with Bayt data
💰 Benchmark salaries across the Gulf.
Run the same job title across uae, saudi-arabia, and qatar, then compare salaryMin and salaryMax by careerLevel. Currencies are parsed, so the numbers are ready to chart.
📈 Track hiring demand by city.
Scrape software engineer in Dubai, Abu Dhabi, and Riyadh on a schedule and watch the volume and freshness of postings move week over week.
🎯 Find companies that are actively hiring.
Sort by date, filter to isAggregated: false, and you get employer-posted roles with a company profile link — the ones worth a sales or recruiting outreach.
🧠 Build MENA labor-market datasets.
Collect thousands of listings with summaries, seniority, and timestamps for a labeled corpus of real regional hiring activity.
Why choose this scraper
Most Bayt scrapers return the search card as-is: a title, a company, and "15 days ago" as a string. That is fine for browsing and useless for analysis — you cannot sort by a relative date, average a salary that is still text, or trust a dataset where most rows came from a third-party feed with no salary at all.
This one is built for the analysis step:
| What you get | |
|---|---|
| All 18 Bayt markets | UAE, Saudi Arabia, Qatar, Kuwait, Bahrain, Oman, Egypt, Jordan, Lebanon, Iraq, Yemen, Morocco, Algeria, Tunisia, Libya, Pakistan, India, and International. |
| Salary parsed, not just copied | $3,000 - $4,000 becomes salaryMin: 3000, salaryMax: 4000, salaryCurrency: "USD". Handles USD, EUR, GBP, AED, SAR, QAR, KWD, BHD, OMR, EGP, and JOD. |
| Real dates you can sort on | postedAt is an exact ISO timestamp taken from Bayt's own data. postedAtText keeps the original "3 hours ago". |
| Newest jobs first | Sorts by date by default. Bayt's own relevance sort reaches back over 200 days. |
| Aggregation transparency | isAggregated tells you which rows are employer postings and which came from a third-party feed. Third-party rows carry no salary or seniority anywhere on Bayt — now you can filter them out. |
| Filters carried across pages | Bayt's pagination links drop your sort and filters. This Actor carries them through every page. |
| Four export formats | CSV, JSON, Excel, and XML, from the dashboard or the API. |
How it compares
Bayt is a crowded niche — more than a dozen actors scrape it, and most return the same search card. Two things separate them in practice: whether the salary and date arrive as usable values, and whether you are told that roughly nine out of ten keyword-search rows are third-party aggregated listings that carry no salary at all.
The competitor columns below reflect what each Actor's own public listing states, not a test run of it.
| Feature | ParseForge | blackfalcondata | shahidirfan | easyapi | makework36 | crawlerbros |
|---|---|---|---|---|---|---|
| Salary parsed into min / max / currency | Yes, 11 currencies | Native and USD | "salaries" | Not stated | Not stated | "salaries" |
| Exact ISO posting date, not "15 days ago" | Yes, plus original text | Not stated | Not stated | Not stated | Not stated | Not stated |
| Aggregated-listing flag with published coverage figures | Yes, isAggregated | No | No | No | No | No |
| Sorted newest-first by default | Yes | Not stated | Not stated | Not stated | Not stated | Not stated |
| Markets covered | 18 | 12 | MENA, unspecified | Not stated | UAE, KSA, EG, QA, KW + more | Not stated |
| Field count | 47 | 60+ | Not stated | Not stated | 5 core | Not stated |
| Price per result | $0.001 | $0.00099 | $0.00099 | $0.00299 | $0.0025 | $0.002 |
If you want the widest field set, blackfalcondata/bayt-scraper advertises 60+ fields at essentially the same price and is the most used actor in the niche. Come here when you need the salary and date as values you can sort and average, and when you need to know which rows are aggregated before you draw a conclusion from them.
What a Bayt job looks like
Every listing returns as one flat JSON row. Here is a real record, unedited apart from a trimmed summary:
{"jobId": "5477266","title": "Sales Manager, UAE - L&D Training","company": "Michael Page","companyUrl": "https://www.bayt.com/en/company/michael-page-1528978/","isAggregated": false,"location": "Dubai, UAE","city": "Dubai","country": "UAE","salary": "$3,000 - $4,000","salaryMin": 3000,"salaryMax": 4000,"salaryCurrency": "USD","careerLevel": "Mid career","isRemote": false,"isFeatured": false,"summary": "A dynamic Business Development Manager is sought, specializing in Training Sales for UAE clients. This role demands expertise in identifying new busin...","postedAt": "2026-08-18T14:32:28.000Z","postedAtText": "3 hours ago","url": "https://www.bayt.com/en/uae/jobs/sales-manager-uae-l-d-training-5477266/","searchUrl": "https://www.bayt.com/en/uae/jobs/?options%5Bsort%5D%5B%5D=d","scrapedAt": "2026-08-18T18:35:29.399Z"}
city is absent when Bayt lists only a country. Fields the employer did not publish are omitted rather than guessed.
How to get the richest data
Bayt mixes employer-posted jobs with listings pulled from third-party feeds, and the third-party ones carry no salary or seniority anywhere on Bayt. How much of each you get depends on how you search — so here is the measured breakdown, and how to search for what you need:
| Your goal | How to search | Salary present | Career level present |
|---|---|---|---|
| Salary benchmarking | Country, no keyword | 53% | 87% |
| Broad role research | Country + keyword | 7% | 30% |
| Specific openings in one city | Country + keyword + city | 2% | 9% |
For compensation research, search by country and filter isAggregated: false — that combination gives you employer-posted jobs with published pay. For finding specific openings, add the keyword and city and expect leaner metadata, since that is what Bayt's feed holds for those searches.
No other Bayt scraper tells you this, because none of them expose the aggregation flag that makes it measurable.
Configure the run
Drive the Actor with a keyword, a country, and an optional city — or paste a Bayt search URL to reproduce a search exactly. The Input tab lists every parameter.
Benchmark salaries across a whole market:
{ "country": "saudi-arabia", "sortBy": "date", "maxItems": 500 }
Track a role in one city:
{ "keyword": "software engineer", "country": "uae", "city": "Dubai", "maxItems": 200 }
Reproduce an existing Bayt search, filters and all:
{ "searchUrl": "https://www.bayt.com/en/qatar/jobs/nurse-jobs/", "maxItems": 300 }
Filters
Every filter below is a parameter on Bayt's own search, so a filtered run costs exactly the same as an unfiltered one — there is no extra request and no extra page.
| Filter | Values |
|---|---|
datePosted | Past 24 hours, 7 days, 30 days |
employmentType | Full time, Part time, Contractor, Temporary, Internship, Freelance |
careerLevel | Student/Internship, Fresh graduate, Entry, Mid career, Management, Director/Head, Senior executive |
industry | 22 industries, from Oil & Gas to IT Services |
companyType | Private employer, Recruitment agency, Public employer, Non-profit |
companyName | One employer by name |
directEmployersOnly | See below |
directEmployersOnly is the one no other Bayt scraper has. Most of a keyword search is aggregated repostings pulled from third-party boards, and those rows carry almost no structured data. This flag pins the search to direct private-sector employers and drops any aggregated row that slips through — and because they are dropped before anything is written, you are never charged for them.
It trades volume for quality, and the trade is steep. Same search for "software engineer" in Dubai, measured:
| Listings | Aggregated | Career level present | |
|---|---|---|---|
| Off | 10 | 9 | 1 |
| On | 4 | 0 | 3 |
Turn it on when you are going to act on the rows one by one and the junk costs you time. Leave it off when you want the widest possible view of a market.
Only jobs posted in the last 24 hours, full time, by the employer itself:
{ "country": "uae", "datePosted": "24h", "employmentType": "full-time", "directEmployersOnly": true, "maxItems": 500 }
Every senior opening at one employer:
{ "country": "uae", "companyName": "Al Futtaim Group", "careerLevel": "senior-executive", "maxItems": 100 }
Full job details
A search card carries what Bayt prints on the listing. The job's own page carries the rest, and includeDetails goes and gets it:
| From the job page | |
|---|---|
description / descriptionHtml | The complete posting, as text and as Bayt's original markup |
skills | Skills and qualifications the employer lists |
yearsOfExperience / monthsOfExperience | As written, and as a number you can sort on |
education | Minimum degree required |
expiresAt | Application deadline, so a re-run can drop stale rows |
detailSalaryMin / Max / Currency / Period | A numeric salary range, on listings where the card shows none |
vacancies, directApply, ageRange, residenceLocation | The rest of the employer's requirements |
addressLocality / addressRegion / countryCode | Structured address with an ISO country code |
This reads Bayt's own structured job-posting data rather than scraping the rendered page, so it survives redesigns that break selector-based scrapers.
It is not free and it is not fast. Each job means one extra request and about 25 seconds, run five at a time. A 100-listing run goes from roughly one minute to about eight, and the extra requests are billed as a separate Job detail event. Turn it on with a maxItems you actually need, not with 10,000.
{ "country": "uae", "datePosted": "7d", "directEmployersOnly": true, "includeDetails": true, "maxItems": 50 }
Sorting and freshness
Bayt sorts by relevance by default, which surfaces listings posted months ago: in one measured search, 42% were over 30 days old and the oldest was 216 days. This Actor sorts by date instead.
Sorting orders results, it does not filter them, so the gain shows up whenever maxItems is smaller than the total result count. Same search, same 65 available listings:
maxItems | Relevance: median age / over 30 days | Date: median age / over 30 days |
|---|---|---|
| 10 | 15 days / 2 | 4 days / 0 |
| 20 | 14 days / 4 | 6 days / 0 |
| 30 | 14 days / 4 | 13 days / 0 |
Set sortBy: "relevance" if you would rather have Bayt's own ranking.
Pricing
Pay-per-event, and every charge lands after the row is written, never before. Apify plan discounts apply automatically.
| Event | No discount | Bronze | Silver | Gold |
|---|---|---|---|---|
Job listing · result-item | $1.00 / 1,000 | $0.96 / 1,000 | $0.93 / 1,000 | $0.89 / 1,000 |
Job detail · job-detail | $3.00 / 1,000 | $2.89 / 1,000 | $2.78 / 1,000 | $2.67 / 1,000 |
Search query · search-query | $2.00 / 1,000 | $1.93 / 1,000 | $1.85 / 1,000 | $1.78 / 1,000 |
Actor start · apify-actor-start | $0.002 | $0.0019 | $0.0019 | $0.0018 |
What each one means:
- Job listing — one row written to your dataset. This is the only charge a plain search incurs.
- Job detail — the job's own page, read only with
includeDetails, and only when the page actually came back. One extra unblocking request per job, which is why it costs three times a listing. - Search query — one keyword or search URL resolved. Charged once per search, and only after that search has produced a listing: paging through results is not a new search, and a search that returns nothing is not billed at all.
| Run | Approximate cost |
|---|---|
| 100 listings | $0.10 |
| 1,000 listings | $1.00 |
| 10,000 listings | $10.00 |
One search adds $0.002; ten keywords in one run add $0.02. With includeDetails on, add $0.003 per listing — 1,000 listings with job pages runs about $4.00.
You do not pay platform usage costs. Bayt needs a strong unblocking proxy and the compute to go with it; both are already covered by the prices above, so there is no separate Apify bill on top.
New Apify accounts start with $5 in free credit — about 5,000 job listings.
Free users
Free-plan runs return up to 10 listings, enough to check the data before committing. Bayt blocks ordinary requests, so every run goes through a paid unblocking proxy whose cost we absorb — the free cap keeps that sustainable.
Any paid Apify plan lifts it to 10,000 listings per run, and the $5 starting credit covers roughly 5,000 of them.
Run it
- Create a free Apify account with $5 in credit.
- Open the Bayt Scraper.
- Pick a
country, add akeywordandcityif you want to narrow it, setmaxItems, and click Start. - Export the results as CSV, Excel, JSON, or XML from the Dataset tab.
Run it programmatically through the Apify API or the ApifyClient for JavaScript and Python.
Proxies
Bayt blocks datacenter and residential IPs aggressively, so this Actor defaults to Apify Proxy with the UNBLOCKER group, which gets through on the first request. Measured on the same search:
| Proxy group | Result |
|---|---|
| UNBLOCKER (default) | Works on the first request, no retries needed |
| RESIDENTIAL | Blocked on every attempt |
| No proxy | Blocked |
Its cost is included in the per-listing price, so you do not pay for it separately. Blocked pages are retried up to eight times with a fresh session and a new browser fingerprint each time.
If you point the Actor at a different proxy group and Bayt blocks it, the run switches to UNBLOCKER automatically after three blocked attempts instead of failing. And if the first page still never loads, the run fails with a clear message rather than handing you an empty dataset.
Use with AI agents (MCP)
Give an AI agent live access to Gulf hiring data through the Model Context Protocol. Add the Actor to Claude, Cursor, or any MCP client:
claude mcp add --transport http apify "https://mcp.apify.com?tools=parseforge/bayt-scraper"
Then prompt it in plain language:
- "Find software engineering jobs posted in Dubai this week and list the ones with a salary range."
- "Compare published salaries for accountants in the UAE, Saudi Arabia, and Qatar."
- "Pull the 100 newest jobs in Egypt and group them by company."
Copy this into ChatGPT, Claude, or Cursor to start:
Use the Apify Actor "parseforge/bayt-scraper" to collect public Bayt.com job listings. Input: { "keyword": "<role>", "country": "<uae|saudi-arabia|qatar|kuwait|bahrain|oman|egypt|jordan|lebanon|iraq|yemen|morocco|algeria|tunisia|libya|pakistan|india|international>", "city": "<optional city>", "sortBy": "date", "maxItems": <n> }. It returns title, company, companyUrl, location, city, country, salary, salaryMin, salaryMax, salaryCurrency, careerLevel, isRemote, isAggregated, summary, postedAt, and url per listing. Call it with the ApifyClient and my APIFY_TOKEN.
Troubleshooting
Why am I getting no results?
The city may not belong to the country you picked, or the keyword may have no matches in that market. Drop the city first, then the keyword, and confirm the country index returns jobs.
How do I get more rows with salary?
Search by country without a keyword, and filter to isAggregated: false. That takes salary coverage from about 7% to about 53%, because third-party aggregated listings do not carry salary anywhere on Bayt.
Why fewer listings than I asked for?
The search ran out of results. Bayt returns 30 per page, and a narrow keyword-plus-city search often holds only two or three pages. Widen the search or drop the city.
Why am I getting HTTP 403?
Your proxy group is being blocked. Set proxyConfiguration to the UNBLOCKER group — Bayt rejects datacenter and residential IPs. Its cost is already included in the per-listing price.
Why is the run slow?
Each page holds 30 listings, so a large maxItems fetches many pages, and blocked pages add backoff delay. Lower maxItems or split one job into scheduled runs.
A field stopped filling.
Bayt changed its page markup. Email us with your run ID so we can update the parser.
FAQ
| Question | Answer |
|---|---|
| Do I need a Bayt account or API key? | No. Bayt has no public API. This reads public search pages, so there is nothing to register or authorize. |
| Which countries does it cover? | All 18 Bayt markets, including the six GCC states, Egypt, Jordan, Lebanon, Iraq, Yemen, Morocco, Algeria, Tunisia, Libya, Pakistan, and India. |
| Does it return salary data? | Yes, parsed into salaryMin, salaryMax, and salaryCurrency across eleven currencies. Search by country to reach about 53% coverage — see the table above. |
What is isAggregated? | Bayt mixes its own employer postings with listings pulled from third-party feeds. Aggregated rows carry no salary or seniority, so this flag lets you filter to employer-posted jobs. |
| Can I filter by city? | Yes. Set city alongside country, for example Dubai, Riyadh, or Cairo. |
| Does it return the job description? | Every row carries the role summary shown on the listing, plus the canonical job URL so you can pull the full description for the roles you care about. |
| How many listings per run? | Up to 10,000 on any paid Apify plan, bounded by how many results the search holds. Free-plan runs return 10. |
| Do I need a proxy? | Yes, and it is already set up. The default UNBLOCKER group works out of the box, and its cost is included in the per-listing price. |
| Is this an official Bayt product? | No. It is unofficial and reads only public Bayt data. |
Related actors
- SEEK Australia Jobs Scraper: job listings from Australia's largest job board.
- Upwork Freelancers Scraper: freelance talent profiles, rates, and skills.
- LinkedIn Posts Scraper: public post content for employer-brand research.
- Crunchbase Scraper: company funding and headcount for the employers you find.
- UK Companies House Scraper: official company registry records.
Browse the full ParseForge collection for more scrapers.
🆘 Need help? Email parseforge@protonmail.com with your run ID, your input, and what you expected.
⚠️ Disclaimer. This Actor is unofficial and is not affiliated with, endorsed by, or sponsored by Bayt.com Inc. It collects only publicly available job listings. You are responsible for using the data in compliance with Bayt's terms and applicable laws, including GDPR, CCPA, and PIPL. Do not use it to identify, profile, or target individuals.
