Bayt Jobs Scraper: Gulf and MENA Jobs, Salary, Company avatar

Bayt Jobs Scraper: Gulf and MENA Jobs, Salary, Company

Pricing

from $0.72 / 1,000 jobs

Go to Apify Store
Bayt Jobs Scraper: Gulf and MENA Jobs, Salary, Company

Bayt Jobs Scraper: Gulf and MENA Jobs, Salary, Company

Scrape Bayt.com jobs by keyword, country and city: title, company, location, posted date, job type, career level, experience, salary where shown, full description, apply link and company profile link. Pagination to your cap. No login.

Pricing

from $0.72 / 1,000 jobs

Rating

0.0

(0)

Developer

The Mine Works

The Mine Works

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

5 days ago

Last modified

Share

30 Bayt jobs with full descriptions, salary and company links in 77 seconds

Part of The Mine Works Jobs and hiring family: Foundit Monster India Jobs, Hirist Jobs Scraper, India Jobs MCP, Naukri Jobs Scraper, Shine.com Jobs Scraper, Internshala Scraper.

Updated 24 Oct 2026: first release. Bayt.com jobs by keyword, country and city, or from a pasted Bayt search or job link: title, company, location, posted date, job type, career level, experience, salary where shown, full description, apply link and company profile link, one flat row per job. Bookmark this Actor on its Store page so it is one click away next time.

Why choose this actor?

  • The columns a recruiter or analyst filters on. Every row has the posting time as an ISO date, the closing date, job type, career level, years of experience, and the salary split into salary_min, salary_max, salary_currency and salary_period whenever the employer shows one. Sort a whole search in a spreadsheet without cleaning text.
  • The full job, not a snippet. With job pages on (the default), each row carries the whole description as plain text and as HTML, the skills section, the number of openings, company size and industry, and Bayt's Preferred candidate table (nationality, career level, gender, age and years of experience when the employer sets them).
  • Gulf, Levant, North Africa and South Asia in one input. United Arab Emirates, Saudi Arabia, Egypt, Qatar, Kuwait, Bahrain, Oman, Jordan, Lebanon, Iraq, Morocco, Tunisia, Algeria, Libya, Syria, Pakistan, India, Turkiye, United Kingdom, United States, or all Bayt markets at once. Narrow it to one or more cities.
  • Pay per job, nothing for errors. Links that are not Bayt pages, the summary row and duplicates found by two searches are never charged. No Bayt account, cookies or API key.

Run it on Apify

Try it in one minute

Paste this into the input (JSON view) and press Start. It returns the first 30 accountant jobs in the UAE with their job pages opened. It took 77 seconds in our test run:

{
"searchQueries": ["accountant"],
"country": "uae",
"maxItems": 30
}

Put several keywords on separate lines to run several searches at once, add cities such as Dubai and Abu Dhabi, or paste a Bayt link into startUrls. A job that two of your searches find is delivered once.

Apify's free plan includes $5 of credit every month, which covers about 5,600 jobs at this actor's price.

Copy to your AI assistant

themineworks/bayt-jobs-scraper on Apify. Searches Bayt.com (the largest Middle East and North Africa job board) by keyword, country and city, or from pasted Bayt search or job links, and returns one flat row per job with company, location, salary where shown, career level, full description and apply link, with no login. Call ApifyClient("TOKEN").actor("themineworks/bayt-jobs-scraper").call(run_input={"searchQueries": ["accountant"], "country": "uae", "cities": ["Dubai"], "maxItems": 100}), then client.dataset(run["defaultDatasetId"]).list_items().items. Give searchQueries (list of keywords), country (one of uae, saudi-arabia, egypt, qatar, kuwait, bahrain, oman, jordan, lebanon, iraq, morocco, tunisia, algeria, libya, syria, pakistan, india, turkiye, uk, usa, international; default uae), cities (optional list, for example Dubai, Riyadh, Cairo, Doha) or startUrls (list of bayt.com search or job links) or a mix; up to 100 searches. With no keyword and no link the newest jobs of the country are listed. Optional: maxItems (default 50, 1 to 5000, per search), includeDetails (default true; opens each job page for description, description_html, skills, expires_at, openings, company_size, industry, preferred_candidate, region), maxAgeDays (skip older jobs), proxyConfiguration (default Apify residential in the UAE; Bayt turns away most datacenter proxies). Job rows have no _type field and carry job_id, title, company, company_url, company_logo, company_size, industry, location, city, region, country, country_code, posted_at, posted_relative, expires_at, job_type, career_level, experience, salary_raw, salary_min, salary_max, salary_currency, salary_period, summary, description, description_html, skills, preferred_candidate, openings, direct_apply, easy_apply, is_external, is_aggregated, job_url, apply_url, keyword, search_url, page, position, scraped_at, details_scraped. Each run also writes one row with _type "summary", one with _type "info" when jobs were delivered, and a row with _type "error" for each input that could not be read; none of these is charged. Full spec: GET https://api.apify.com/v2/acts/themineworks~bayt-jobs-scraper/builds/default (Bearer TOKEN), which returns inputSchema and readme. Token: https://console.apify.com/account/integrations?fpr=ymnoit&utm_source=apify-readme&utm_medium=referral

Key features

  • Keyword, country and city. Type keywords the way you would in the Bayt search box, pick a country and optionally list cities. Each keyword is searched in each city, the way Bayt builds its own pages (/en/uae/jobs/accountant-jobs-in-dubai/). Pages after the first are followed from the site's pager, 30 jobs a page.
  • Bayt links. Paste a Bayt search link from your browser, or single job links to refresh a known set of jobs. Sort and filter parameters in a pasted link (options[...], filters[...]) are removed, because Bayt's robots.txt asks crawlers not to use them.
  • Salary as Bayt shows it. Many jobs show a salary (20 of 30 in one test run, 20 of 50 in another). salary_raw is the text on the page, and the range is split into numbers with the currency code Bayt displays (AED, USD and so on) and the pay period. A job with no salary has no salary fields.
  • Employer and apply links. company_url is the Bayt company profile, job_url the job page and apply_url the Bayt apply link. Jobs whose employer is hidden are returned with the company Confidential.
  • Preferred candidate. The employer's stated nationality, career level, gender, age and years of experience, as a small object, plus the number of openings and the closing date.
  • Stops cleanly. Two pages in a row with no new jobs end a search; six failed or blocked pages in a row end the run; the run stops before its time limit and keeps every row it read. The summary row says why.

How to use it

Basic: one role in one country

{
"searchQueries": ["software engineer"],
"country": "saudi-arabia",
"maxItems": 300
}

Ten pages of results, one row per job. Sort by posted_at to see the newest first, or by salary_max to see the best paid.

One role across several cities

{
"searchQueries": ["sales manager", "marketing manager"],
"country": "uae",
"cities": ["Dubai", "Abu Dhabi", "Sharjah"],
"maxItems": 100
}

Six searches (two keywords in three cities), 100 jobs each. A job that appears in two of them is delivered once.

Fresh jobs only, for a daily hiring feed

{
"searchQueries": ["nurse"],
"country": "qatar",
"maxItems": 200,
"maxAgeDays": 3
}

Jobs posted more than 3 days ago are skipped before their pages are opened. Schedule it daily and compare on job_id.

Everything in a country, no keyword

{
"country": "egypt",
"maxItems": 500,
"includeDetails": false
}

With no keyword the newest jobs of the country are listed. Job pages off keeps it quick and light.

{
"startUrls": [
"https://www.bayt.com/en/uae/jobs/accountant-jobs-in-dubai/",
"https://www.bayt.com/en/uae/jobs/sales-and-technical-manager-5499061/"
],
"maxItems": 60
}

The first link is a search, followed page by page; the second is one job.

Fast card-only export

{
"searchQueries": ["driver"],
"country": "saudi-arabia",
"maxItems": 500,
"includeDetails": false
}

Rows come from the search cards only: title, company, location, salary, career level, posted time and Bayt's two sentence summary. Same price per job.

Input parameters

ParameterTypeDefaultWhat it does
searchQueriesarray of stringsemptyKeywords, one search each, for example accountant.
countrystringuaeBayt country path: uae, saudi-arabia, egypt, qatar, kuwait, bahrain, oman, jordan, lebanon, iraq, morocco, tunisia, algeria, libya, syria, pakistan, india, turkiye, uk, usa or international.
citiesarray of stringsemptyCities inside the country, for example Dubai. Each keyword is searched in each city.
startUrlsarray of stringsemptyBayt search links or job links copied from your browser.
maxItemsinteger50Most jobs per search (per keyword and city, or per link), 1 to 5,000.
includeDetailsbooleantrueOpens each job page for the full description, skills, closing date, openings, company size and the preferred candidate table.
maxAgeDaysintegeremptySkips jobs posted more than this many days ago.
proxyConfigurationobjectresidential, UAEProxy used for the requests. Bayt turns away most datacenter addresses, so keep the default.

Give searchQueries, cities, startUrls or any mix. Up to 100 searches per run.

What data do you get?

Summary row (_type: "summary", never charged): searches_requested, searches_read, searches_failed, searches_not_started, pages_read, jobs_found, jobs_delivered, charged_for, duplicates_skipped, skipped_too_old, details_requested, details_ok, details_failed, http_requests, http_retries, http_blocked, proxy_megabytes, ended_on_deadline, stopped_by_max_cost, stopped_by_block_guard, shortfall_reason when fewer jobs came back than asked, and per_search, one entry per search with pages, jobs_on_site (Bayt's own "N jobs found"), jobs_delivered and why it stopped. The same summary is saved as the OUTPUT record of the run.

Error rows (_type: "error", never charged): one per input that could not be read, with error_type (invalid_input, not_found, blocked, fetch_error), identifier, reason and http_status.

Stable fields for automations

These were present in every job row of our test runs (30 rows, job pages on), and their names will not change:

FieldWhat it is
job_idThe key to store and join on
titleJob title
job_urlLink to the job on Bayt
apply_urlBayt apply link
companyEmployer, or Confidential
locationLocation as shown
cityCity
countryCountry
posted_atPosting time, ISO
expires_atClosing date (with job pages on)
job_typeFull time, Part time and so on (with job pages on)
descriptionFull text (with job pages on)
summaryBayt's short summary from the card
keywordSearch that found it
positionPlace in the search

Optional, present only when the job shows a value: salary_* (20 of 30 test rows), career_level (25 of 30), experience (6 of 30), preferred_candidate (25 of 30), industry (8 of 30), company_url and company_logo (hidden for confidential employers), and skills.

Output examples

One job from the "accountant" search with job pages on (test run, 23 Oct 2026, trimmed):

{
"job_id": "5490491",
"title": "Group Accountant (Chartered Accountant / ACCA)",
"company": "Ultrafitler GmbH",
"company_url": "https://www.bayt.com/en/company/ultrafitler-gmbh-2321122/",
"company_size": "1-9 Employees",
"location": "Dubai, UAE",
"city": "Dubai",
"region": "Dubai",
"country": "UAE",
"country_code": "AE",
"posted_at": "2026-10-11T08:31:42.000Z",
"posted_relative": "12 days ago",
"expires_at": "2026-11-10T00:00:00.000Z",
"job_type": "Full time",
"career_level": "Mid career",
"experience": "3 - 6 Years of Experience",
"salary_raw": "AED 11,018 - AED 14,690",
"salary_min": 11018,
"salary_max": 14690,
"salary_currency": "AED",
"salary_period": "MONTH",
"description": "Ultrafilter is a European manufacturer of industrial and sterile filters with companies in Europe, the UAE and India. We are building our group finance function...",
"skills": "Chartered Accountant / ACCA, month-end close, multi-entity group accounting, ...",
"preferred_candidate": { "Years of experience": "3 - 6 years", "Career level": "Mid career" },
"openings": 1,
"direct_apply": true,
"easy_apply": true,
"job_url": "https://www.bayt.com/en/uae/jobs/group-accountant-chartered-accountant-acca-5490491/",
"apply_url": "https://www.bayt.com/en/job/apply/index/5490491/",
"keyword": "accountant",
"search_url": "https://www.bayt.com/en/uae/jobs/accountant-jobs/",
"page": 1,
"position": 13,
"scraped_at": "2026-10-23T18:28:00.570Z",
"details_scraped": true
}

Pricing

Pay per event: you pay for the jobs you receive, plus a flat $0.003 per run, whatever memory you choose. Opening job pages costs nothing extra.

EventWhen it is chargedFree planBronze (Starter)Silver (Scale)Gold (Business)
job-scrapedOnce per job row stored in your dataset$0.89 per 1,000$0.84 per 1,000$0.77 per 1,000$0.72 per 1,000
run-startOnce per run, after the first results page returned jobs$0.003$0.003$0.003$0.003

The price of one job is the price per 1,000 divided by 1,000.

Never charged:

  • links that are not Bayt pages (each gets an error row);
  • a job that a second search of the same run finds again;
  • jobs past your maxItems;
  • the summary, info and error rows;
  • a run with no valid input, or one whose searches return no jobs: the start fee is charged only once a results page has returned jobs;
  • anything past your "Max cost per run". The actor checks the budget before each batch of rows and stops while the total is still below your limit, so the run ends SUCCEEDED with a partial result and a status message saying so.

Run it on a schedule

  1. Open the actor in Apify Console, set your input and click Save as a new task.
  2. In the task, open Schedules, click Add schedule and pick how often (every day, every Monday at 08:00 and so on).
  3. Compare runs on job_id to see new vacancies, or on expires_at to see what closed. maxAgeDays keeps a daily run to the newest postings.
  4. Optional: add an integration (Google Sheets, Slack, a webhook) so each run lands where your team works.

FAQ

What does this actor read?

Bayt.com's public job search pages and, with includeDetails on, each listed job's public page, as anyone sees them without logging in. It does not log in, apply to jobs or read candidate data. It uses the /en/<country>/jobs/ search paths and job pages that Bayt's robots.txt leaves open, and does not use the sort and filter parameters it asks crawlers to avoid.

How many jobs can I get?

Up to 5,000 per search and 100 searches per run. A results page holds 30 jobs. Each search page says how many jobs Bayt holds for it (484 for "accountant" in the UAE on 23 Oct 2026), shown as jobs_on_site in the summary. A search ends when the pager has no next page, two pages in a row bring nothing new, or maxItems is reached.

Why do some rows have no salary, experience or industry?

Bayt shows what the employer entered. In our test 20 of 30 jobs showed a salary, 6 stated years of experience and 8 named an industry. Missing values are left out of the row, not filled with guesses.

Which currency is the salary in?

The one Bayt displays for that job, in salary_currency. Some jobs show AED, others USD. The actor does not convert anything.

What is the difference between includeDetails on and off?

Off, each row comes from the search card: title, company, city, country, salary, career level, posted time and Bayt's two sentence summary. On, the job page adds the full description, skills, closing date, openings, company size, industry, region and the preferred candidate table. On is slower (30 jobs took 77 seconds in our test) and costs the same.

Can I filter by career level, job type or date?

Filter the rows: career_level, job_type, experience, salary_max and posted_at are separate columns for that, and maxAgeDays drops old postings during the run. Bayt's own sort and filter parameters are not used, because its robots.txt asks crawlers to leave them alone.

Can I search a city?

Yes. Put the city in cities, spelled as Bayt writes it (Dubai, Abu Dhabi, Riyadh, Jeddah, Cairo, Doha). A city Bayt has no page for returns a not_found error row for that search and the run goes on.

How long does a run take?

In our tests: 77 seconds for the "Try it" input (30 jobs, job pages on) and 126 seconds for 50 jobs with job pages on. Job pages off is faster because only the result pages are read, 30 jobs each. The default time limit is 3,600 seconds; the actor stops before it and keeps every row.

Do I need an account, cookies or a proxy?

No. Bayt sits behind Cloudflare and turns away most datacenter addresses, so the actor reads the public pages through Apify residential proxy by default. You do not need a proxy account of your own. A request that is turned away is retried on a new address, up to five times.

Which actor should I use for other job boards?

See "More from The Mine Works" below for the other job boards we cover.

Which formats can I download?

JSON, CSV, Excel, XML, RSS and HTML from the run's Storage tab or through the API. The dataset has two ready views: Jobs, and Job details. In CSV and Excel, preferred_candidate is flattened into columns such as preferred_candidate/Nationality.

Can I use it from Claude, ChatGPT or Cursor (MCP)?

Yes, through Apify's MCP server. Connector URL: https://mcp.apify.com/?tools=themineworks/bayt-jobs-scraper

  • Claude: Settings > Connectors > Add custom connector, paste the URL, sign in with Apify.
  • ChatGPT: turn on developer mode, add an MCP connector with the URL, sign in with Apify.
  • Cursor or VS Code: add it as an HTTP MCP server with that URL.
  • Claude Code: claude mcp add -t http bayt-jobs-scraper "https://mcp.apify.com/?tools=themineworks/bayt-jobs-scraper"

The actor reads only public job listings that anyone can see without logging in. It opens Bayt pages only where the site's robots.txt allows it. You are responsible for how you use the data, including Bayt's terms and data protection law such as GDPR and CCPA, especially for any contact details an employer writes into a description. This is general information, not legal advice.

Integrations

  • Google Sheets: send each run's jobs to a sheet with Apify's Google Sheets integration; one row per job fits a sheet as is.
  • Make, Zapier and n8n: start a run and read its dataset with the Apify apps and nodes, for example "new nursing jobs in Qatar every Monday to Slack".
  • Webhooks: have Apify call your URL when a run succeeds, then fetch the dataset.
  • API and SDKs: run it from Python or JavaScript with the Apify client, or with a plain HTTP call (see "Copy to your AI assistant" above).
  • MCP clients: Claude, ChatGPT, Cursor and VS Code can run it as a tool through the connector URL in the FAQ.

More from The Mine Works

Jobs and hiring

Social media and video

Leads and business directories

Marketing, SEO and reviews

LinkedIn

Real estate

Science, health and government data

Company and business data

E-commerce and marketplaces

Food and local services

Developer and AI tools

More tools

Support

Found a search that returns fewer jobs than the site, or a field that comes back empty? Open an issue in the Issues tab with the input and the run ID, and we will look at it. For a field you need or a new source, email dmineworks@gmail.com.

Search Bayt.com by keyword, country and city and get every job back as one row, with company, location, salary where shown, career level, full description, apply link and company profile link, no login.