BaytAnswer

Does Bayt have an API? Search its jobs as JSON

We found no public Bayt API; ours returns 30 jobs per call at 1 credit, and a script saved 150 accountant jobs to CSV in 5 calls.

5 min read

Short answer

  • We found no public Bayt API: the developer, API and docs paths we tried return 404, and its UAE home page and About page link to none.
  • Of 465 distinct jobs on 18 saved search pages, 39 carried a pay band, all with a 7-digit job ID; none of the 318 with 8-digit IDs had one.
  • ToolzerHub's /v1/bayt/search and /v1/bayt/job return Bayt jobs as JSON with one API key, at 1 credit a call.
On this page

We found no public Bayt API or developer documentation. Our Bayt API returns its jobs as JSON: one search call gives you 30 jobs, and the script below saved 150 accountant jobs to CSV in 5 calls.

Bayt's own pages

When we checked, /developers, /api, /docs, /en/developers/ and /en/api/ on bayt.com returned a 404. The UAE home page (170 links) and the About page (72 links) pointed to no API or developer page. A web search for a Bayt job search API found Apify actors, GetApp listings and Bayt job ads for API developers. A private arrangement wouldn't show up in those checks, so if you need an official feed, ask Bayt.

Bayt jobs with ToolzerHub

We make ToolzerHub. Our Bayt API has two routes, each a GET with the x-api-key header at 1 credit a call:

  • /v1/bayt/search?query=... returns one page of 30 jobs with total, max_page and has_more. Optional filters: location (a country, a city Bayt lists, or City, Country), sort (relevance or date), posted_within_days (1, 7 or 30) and page, up to 334. When Bayt rounds a large count, total_is_estimate is true.
  • /v1/bayt/job?job_id_or_url=... takes a job_id or a bayt.com link and returns the description and skills HTML, the pay band with its period, the closing date, company size and the employer's candidate preferences.

For GulfTalent and Naukrigulf we have /v1/gulftalent/search and /v1/naukrigulf/search.

bash
export TOOLZERHUB_API_KEY=your_key
curl -G -H "x-api-key: $TOOLZERHUB_API_KEY" \
  --data-urlencode "query=accountant" \
  --data-urlencode "location=UAE" \
  --data-urlencode "sort=date" \
  "https://api.toolzerhub.com/v1/bayt/search"

A job from that page, trimmed:

json
{
  "job_id": "5504825",
  "title": "Sr. Accountant -General Accountant",
  "company": { "name": "Brentta General Trading LLC" },
  "location": "Dubai, UAE",
  "salary": { "label": "AED 5,509 - AED 7,345", "min": 5509, "max": 7345, "currency": "AED" },
  "career_level": "Mid career",
  "posted_at": "2026-11-05T09:11:56Z",
  "is_easy_apply": true
}

The same job from /v1/bayt/job, trimmed, with the band in US dollars a month:

json
{
  "salary": { "min": 1500, "max": 2000, "currency": "USD", "period": "month" },
  "employment_type": "FULL_TIME",
  "posted_date": "2026-11-05",
  "valid_through": "2026-12-05T00:00:00Z"
}

Save Bayt jobs to CSV

The script pages through one search, keeps each job once and writes one row per job with company, city, country, pay band, career level and posting date. Save it as bayt_jobs.py and install requests (pip install requests). Pass - as the location to search every country.

python
import csv
import os
import sys

import requests

API = "https://api.toolzerhub.com/v1/bayt/search"
HEADERS = {"x-api-key": os.environ["TOOLZERHUB_API_KEY"]}


def search(query, location=None, pages=3, sort="date"):
    seen = set()
    for page in range(1, pages + 1):
        params = {"query": query, "sort": sort, "page": page}
        if location:
            params["location"] = location
        response = requests.get(API, headers=HEADERS, params=params, timeout=60)
        response.raise_for_status()
        body = response.json()["data"]
        for job in body["results"]:
            if job["job_id"] not in seen:
                seen.add(job["job_id"])
                yield job
        if not body["has_more"]:
            break


def main():
    query = sys.argv[1]
    location = sys.argv[2] if len(sys.argv) > 2 and sys.argv[2] != "-" else None
    pages = int(sys.argv[3]) if len(sys.argv) > 3 else 3
    fields = ["job_id", "title", "company", "city", "country", "pay_min", "pay_max",
              "currency", "career_level", "posted_at", "easy_apply", "url"]
    with open("bayt_jobs.csv", "w", newline="", encoding="utf-8") as out:
        writer = csv.DictWriter(out, fieldnames=fields)
        writer.writeheader()
        count = 0
        for job in search(query, location, pages):
            salary = job["salary"] or {}
            writer.writerow({
                "job_id": job["job_id"],
                "title": job["title"],
                "company": job["company"]["name"],
                "city": job["city"],
                "country": job["country"],
                "pay_min": salary.get("min"),
                "pay_max": salary.get("max"),
                "currency": salary.get("currency"),
                "career_level": job["career_level"],
                "posted_at": job["posted_at"],
                "easy_apply": job["is_easy_apply"],
                "url": job["url"],
            })
            count += 1
    print(f"saved {count} jobs to bayt_jobs.csv")


if __name__ == "__main__":
    main()

python bayt_jobs.py "accountant" UAE 5 saved 150 jobs in 5 calls, 17 of them with a pay band. python bayt_jobs.py "data analyst" - 5 saved 150, 96 of them in India and none with a pay band.

What the saved pages showed

We saved the first 3 pages of three searches in each order, so every row below is 90 listings, and a job can appear in both orders. A job has a pay band when salary is not null, and the ID length is the number of digits in job_id. "Last 7 days" counts a posted_at date within 7 days of the search.

Search Order 7-digit IDs Pay band Last 7 days
accountant, UAE relevance 53 24 14
accountant, UAE date 16 10 41
site engineer, Saudi Arabia relevance 32 9 12
site engineer, Saudi Arabia date 19 7 16
data analyst, all countries relevance 62 6 33
data analyst, all countries date 1 0 90

Those 18 pages held 465 distinct jobs, and 39 carried a pay band. All 39 had 7-digit IDs, which are 147 of the 465. The 318 jobs with 8-digit IDs had no pay band and no career level, and none was easy apply. Date order brought fewer 7-digit IDs and fewer bands in all three searches.

Check currency before comparing pay. 14 of the 39 bands came in dollars, and each of the other 25 in AED or SAR equals a whole-hundred dollar amount times 3.6725 or 3.75. The Job route returned US dollars a month for all 6 banded postings we read, whatever currency search showed.

Order also changes how old the jobs are and where they come from. For "site engineer" in Saudi Arabia, 32 of the 90 relevance-ordered jobs had a posted_at over 90 days old, the oldest in 2023; the other five rows had none. The all-country "data analyst" search put 59 India jobs among its first 90 in date order, against 22 in relevance order. One accountant job came back on pages 2 and 3, which is why the script keeps each job once.

What it costs

The 150-job export took 5 credits, and a full posting is 1 more credit each. The 100 free credits a month cover 20 exports like it; $19 buys 10,000 credits that never expire, and plans for higher volume cover more searches. Set your key and the first search is a CSV in under a minute.

For other job boards, see Naukri job data and StepStone job data.

We are not affiliated with Bayt.

Get this data from your own code

The Bayt API returns it as JSON with one x-api-key header. 100 free credits monthly.