Bayt Scraper - Middle East Jobs and Companies avatar

Bayt Scraper - Middle East Jobs and Companies

Pricing

from $2.20 / 1,000 results

Go to Apify Store
Bayt Scraper - Middle East Jobs and Companies

Bayt Scraper - Middle East Jobs and Companies

Extract Bayt.com jobs and company profiles across the Middle East and other Bayt markets. Get titles, salaries, locations, full descriptions and optional company details. Pay per delivered row plus a start fee.

Pricing

from $2.20 / 1,000 results

Rating

0.0

(0)

Developer

kane liu

kane liu

Maintained by Community

Actor stats

1

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Security

Limited permissions

Share

Bayt Scraper

Extract Bayt.com jobs and company profiles across the Middle East and other Bayt markets as structured rows you can export.

  • Job titles, employers, locations, salary ranges, career levels and posting dates.
  • Full job descriptions, skills and employment details when requested.
  • Company profiles, with optional websites, listed employees and open jobs.
  • Countries and cities with job counts.
  • Pay only for the rows you receive: $3.00 per 1,000 rows on the Free plan plus a small start fee.

What does Bayt Scraper do?

Bayt Scraper collects job and employer information from Bayt.com. Use it to compare hiring activity, track vacancies or build a shortlist of roles. Markets include the UAE, Saudi Arabia, Egypt, Qatar, Kuwait and other countries listed on Bayt; availability depends on the source.

  • Job search: search with keyword, country, city and optional filters.
  • Job pages: supply jobIds to read specific jobs in full.
  • Company: supply companyUrl for one employer profile.
  • Locations: select locations to list countries, or a country's cities, with job counts.
  • All jobs: select allJobs for broader searches and continuation with cursor, subject to coverage and row limits.
  • Company open-job rows: includeCompanyJobs is off by default. Each added job is a separate row, billed at the same price as the company row.

What data can you extract from Bayt?

Fields depend on the row type and what Bayt publishes. Missing values remain empty or null.

Job rows (dataType: job)

FieldDescriptionExample
jobIdBayt job identifier5488783
titleJob titleSoftware Engineer
listingUrlJob page linkhttps://www.bayt.com/en/uae/jobs/software-engineer-5488783/
companyEmployer name, unless confidentialExample Company
companyUrlEmployer's Bayt pagehttps://www.bayt.com/en/company/al-futtaim-1661592/
locationDisplayed job locationDubai, UAE
countryCodeCountry codeAE
salaryDisplayPublished salary rangeAED 5,000 - 7,000
careerLevelCareer levelMid Career
experienceYearsMinimum and maximum experience{"min": 2, "max": 5}
workplaceWork arrangementon-site
postedAtPosting timestamp2026-10-20T09:00:00+00:00

Full job rows (dataType: job_detail)

Full pages add these fields to job information where available. Reading a full page enriches the same row; it does not create a second billed row.

FieldDescriptionExample
descriptionFull job description as textDevelop and maintain applications.
skillsPublished skills and requirementsPython and SQL
aiSummarySummary supplied by Bayt, if presentnull
employmentTypeEmployment arrangementFull Time Employee
monthlySalaryRangeSalary text from the job pagenull
vacanciesPublished vacancy count as text1

Company rows (dataType: company)

FieldDescriptionExample
nameCompany nameExample Company
groupIdBayt employer identifier1661592
websiteWebsite with includeCompanyPagehttps://example.com
aboutCompany introduction with includeCompanyPageExample company description.
employeesUp to 50 listed employees; part of the company row[{"name": "Jane Doe", "title": "Recruiter", "profileUrl": null}]
openJobsJob count when includeCompanyJobs is enabled12
leadAbsencesReasons contact fields are empty{"geo": "Not on this site: Bayt gives no coordinates."}

Location rows (dataType: location)

FieldDescriptionExample
typeCountry or citycity
namePlace nameDubai
locationIdBayt location identifierae,4,0
jobsCountListed job count, not rows delivered120
jobsCountedAtWhen the count was recorded2026-10-20T09:00:00+00:00

How to scrape Bayt

  1. Open Bayt Scraper in Apify Console. A free Apify account is enough to try it.
  2. Fill a target such as keyword, jobIds or companyUrl.
  3. Set maxResults to 5 for a small first run.
  4. Click Start and wait for completion.
  5. Download the dataset or read it through the Apify API.

Empty input {} starts an example search for software engineer in uae, limited to 3 rows. This is a normal priced run, not a free preview. The form prefills use the same example. Explicit jobs, locations and allJobs modes do not trigger the example just because their target fields are empty.

With mode set to auto, filling one target selects the matching mode. Job IDs take priority over a company; a company takes priority over a keyword or place. Check INPUT_REPORT for ignored fields and inferred choices.

Enter a title or skill in keyword. Add country before using city. In explicit jobs mode, an empty keyword means all jobs and an empty country means all countries. Enable enrichDetails for full pages.

Job pages

Put Bayt job IDs or job links in jobIds. Each available job produces one full job row. Closed or missing IDs can return no row. includeSimilarJobs adds related IDs inside each row, not separate job rows.

Company

Enter a Bayt company link or numeric ID in companyUrl. Enable includeCompanyPage for its website, about text, followers and listed employees. Enable includeCompanyJobs separately for job rows; with maxResults: 5, the company and its jobs share five rows.

Locations

Set mode to locations. Leave country empty for countries, or fill it for cities in that country. Check jobsCountedAt: some country counts were recorded earlier, rather than during this run.

All jobs

Set mode to allJobs, optionally narrowing by country or filters. When RUN_SUMMARY.nextCursor is present, send it as cursor in another run with the same search input. This mode can reach beyond one search's window, but does not guarantee every matching job.

What to fill in

FieldWhat to enterDefault
modeauto, jobs, jobDetails, company, locations, allJobsauto
keywordOne job title, skill or company searchEmpty; form sample software engineer
countryCountry name, code or slug such as uaeEmpty; form sample uae
cityCity within the selected countryEmpty
jobIdsArray of Bayt job IDs or URLsEmpty
companyUrlBayt company URL or numeric IDEmpty
maxResultsMaximum rows per input70; form sample 3
dateIntervalEmpty, 24h, 7d or 30dEmpty
remoteApply Bayt's remote-work filterfalse
careerLevelEmpty, student, graduate, entry, mid, management, director, executiveEmpty
employmentTypeEmpty, full time, part time, contractor, temporary, internship, freelanceEmpty
sortByrelevance or daterelevance
enrichDetailsRead full pages for matching jobsfalse
enrichLimitMaximum job pages to enrich, from 0 to 30030
includeSimilarJobsAdd similar IDs in jobDetails modefalse
includeCompanyJobsAdd separately billed company job rowsfalse
includeCompanyPageAdd public company-page attributesfalse
cursorEarlier RUN_SUMMARY.nextCursor, for allJobs onlyEmpty

Job search:

{"keyword": "accountant", "country": "uae", "city": "Dubai", "dateInterval": "7d", "maxResults": 5}

Job pages; replace the ID with a current job:

{"mode": "jobDetails", "jobIds": ["5488783"], "maxResults": 1}

Company and optional job rows:

{"companyUrl": "https://www.bayt.com/en/company/al-futtaim-1661592/", "includeCompanyJobs": true, "includeCompanyPage": true, "maxResults": 5}

Cities:

{"mode": "locations", "country": "uae", "maxResults": 5}

All-jobs mode with a small limit:

{"mode": "allJobs", "country": "india", "maxResults": 5}
  • maxItems and limit are accepted aliases for maxResults.
  • Unknown fields do not fail input resolution. Close misspellings can be corrected; others are ignored with a note. Invalid filter choices are ignored with a warning.
  • Input-resolution errors use INVALID_INPUT: <field> — <how to fix>. Further validation can return a plain field-specific message, such as requiring a Bayt company link. These checks happen before rows are collected or charged; the start fee is separate.
  • INPUT_REPORT in the run's key-value store records fields filled, normalized, inferred or ignored, including whether the example ran.
  • dateInterval is relative to each run; it is not an automatically advancing date range.

Output example

Illustrative job row, shortened to the main fields; values are examples, not a freshly collected vacancy:

{
"dataType": "job",
"type": "job",
"jobId": "5488783",
"name": "Software Engineer",
"title": "Software Engineer",
"company": "Example Company",
"location": "Dubai, UAE",
"country": "UAE",
"countryCode": "AE",
"salaryDisplay": null,
"workplace": "on-site",
"status": "open",
"authority": "www.bayt.com",
"listingUrl": "https://www.bayt.com/en/uae/jobs/software-engineer-5488783/",
"phones": [],
"emails": [],
"contentDepth": "search"
}

You can export the dataset as JSON, CSV, Excel, XML, RSS or an HTML table.

Why use this Bayt scraper?

  • Pay per delivered row. Job, company and location rows have the same price.
  • Optional detail without duplicate rows. Full job pages enrich existing rows; listed employees remain company attributes and are not billed separately.
  • Useful partial results. If some job pages cannot be read, successfully read rows can still be returned with warnings. A hard stop before delivery is not guaranteed to preserve undelivered rows.
  • Explainable empty fields. Missing salary and employer details are not invented; leadAbsences explains unavailable contact information.
  • Several IDs per run. jobIds accepts multiple jobs. keyword accepts one search string, not separate keyword searches.
  • No proxy setup. You do not need to set up proxies, supply cookies or provide a Bayt account.

How much does it cost to scrape Bayt?

The Actor uses pay-per-event pricing. The start event costs $0.005, charged once per GB of run memory with a minimum of one event. At the default 512 MB, one start costs $0.005. Platform usage is included in these prices.

Apify planPrice per rowPrice per 1,000 rows
Free$0.0030$3.00
Starter$0.0030$3.00
Scale$0.0026$2.60
Business$0.0022$2.20

maxResults applies to each input: a search, company, location request or job ID/URL. Its default is 70, not a promise of 70 matches. Larger requests are collected in parts. All row types share the applicable allowance; adding company jobs does not add a separate allowance.

Free Apify plan runs are capped at 200 rows, with 10 runs of this Actor in total. Paid plans remove that run-count restriction, but row limits, source availability and your spending limit still apply. The whole run is capped by Maximum cost per run (maxTotalChargeUsd in the API).

Example: one search delivering 5 rows on the Free plan at 512 MB costs 5 × $0.003 + $0.005 = $0.020. A run with no rows has no row charge; it can still incur the start fee.

What happens when the run timeout is too short

Some Bayt collections, such as an allJobs run with a large maxResults, a search with enrichDetails: true or a company with includeCompanyJobs: true, can take longer than the run timeout you chose. In that case the run does not fail. It ends early with the status message "Queued on the collection backend; this run will resume automatically when results are ready (about N s)." and shows as ABORTED for a while.

When the results are ready, the same run starts again by itself, reports "Resumed: delivering N rows.", writes the rows to the same dataset and finishes as SUCCEEDED. Rows that were already delivered are skipped, so no row is delivered or charged twice. You do not need to start another run.

  • This can happen at most 3 times per run. To avoid it, keep the default timeout of 3600 seconds.
  • The synchronous API endpoints (run-sync, run-sync-get-dataset-items) wait at most 300 seconds and can return an empty dataset while the run is paused. For larger jobs, start the run asynchronously and read the dataset after the run reaches SUCCEEDED, or use a webhook on the "succeeded" event.

Use with AI agents and the API

Apify MCP server (Claude, ChatGPT, Cursor, VS Code)

Add this Actor to a client that supports remote MCP servers:

https://mcp.apify.com?tools=lentic_clockss/bayt-scraper

Sign in with Apify through OAuth, or send Authorization: Bearer <YOUR_APIFY_TOKEN>. The tool returns run and dataset IDs; read rows with get-dataset-items. Clients without remote support can use npx @apify/actors-mcp-server --tools lentic_clockss/bayt-scraper with APIFY_TOKEN set.

Example prompt: "Find five accountant jobs in the UAE and return their titles, employers and links."

Apify API

Python:

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("lentic_clockss/bayt-scraper").call(
run_input={"keyword": "accountant", "country": "uae", "maxResults": 5}
)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item)

JavaScript:

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('lentic_clockss/bayt-scraper').call({
keyword: 'accountant', country: 'uae', maxResults: 5
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

For HTTP, send the JSON input to POST https://api.apify.com/v2/acts/lentic_clockss~bayt-scraper/runs, with Authorization: Bearer <YOUR_APIFY_TOKEN>. After completion, read GET https://api.apify.com/v2/datasets/<datasetId>/items?format=json, using the run's defaultDatasetId.

Integrations

Use Apify integrations with Google Sheets, Make, Zapier, n8n, Slack or Airtable, or connect a webhook. Use Apify Schedules for recurring runs.

FAQ

This Actor collects publicly available information. You are responsible for checking Bayt's terms and applicable data-protection law. Personal data needs a lawful basis for collection and use; public visibility alone does not settle that question.

Why did my run end as ABORTED?

Check the run log and status message to identify why it stopped, including whether it was manually aborted. Do not assume an aborted run delivered rows or will resume automatically. Inspect the dataset before starting another run.

How many results can I get?

The default is 70 rows per input. allJobs accepts up to 100,000; other modes cap maxResults at 5,000. Available matches, Free-plan limits and the maximum cost can reduce delivery. One job ID normally yields at most one job row.

Why are some fields empty?

Bayt may omit salary, hide an employer or provide no value. Description fields require full pages. Company websites and employees require includeCompanyPage; reading that page can fail without losing the basic company row.

Are phone numbers, email addresses and employees included?

Job and company rows return empty phones and emails. Public company pages can add up to 50 listed employees, with names, titles and profile links where shown. They are attributes, not separately billed rows or guaranteed contact details.

Why did I get no rows?

Check RUN_SUMMARY.emptyReason: LOCATION_UNRESOLVED means the place was not recognized; NO_MATCH can mean no matching jobs, an unknown company or closed job IDs. A successful empty run is different from a collection failure.

For allJobs, reuse RUN_SUMMARY.nextCursor with the same search input. A cursor may be omitted when the maximum charge prevented delivery of all returned rows. Changing the search makes the cursor unsuitable; start over without it.

Do I need a Bayt account?

No. The Actor accepts job-search inputs and public Bayt links without your Bayt login. It does not apply for jobs or access private candidate profiles.

Limitations

  • One Bayt search can expose only its first 10,000 matches. allJobs widens coverage, but some groups remain capped. Use RUN_SUMMARY.coverage rather than assuming a complete export.
  • Job counts and pages change. Continuation across runs can repeat rows; deduplicate saved exports by jobId.
  • City filtering needs a country. UK covers the two country codes Bayt uses, but country availability is not a fixed market count.
  • Full descriptions, company-page attributes and similar-job IDs are optional and may be missing. enrichLimit allows at most 300 full-page enrichments.
  • This documentation does not guarantee delivery of undelivered rows after a manual stop or timeout.

More job board and freelance marketplace scrapers from the same publisher:

Browse all of our scrapers at apify.com/lentic_clockss.

Support

Found a problem or need another field? Open an issue in the Issues tab of this Actor's page and include the run ID and the input you used.