# Bayt Jobs Lookup: Gulf jobs scraper from $1.5/1k (`accountable_eel/bayt-jobs-lookup`) Actor

Bayt jobs scraper by keyword and location: run a search on Bayt.com, one of the largest job boards in the Gulf and MENA region, and get one row per posting: title, company, location, pay (if stated), link. No login required. Pay per posting returned; empty searches are free.

- **URL**: https://apify.com/accountable\_eel/bayt-jobs-lookup.md
- **Developed by:** [Adrian Voss](https://apify.com/accountable_eel) (community)
- **Categories:** Jobs, Lead generation
- **Stats:** 1 total users, 0 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.14 / 1,000 job posting returneds

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/actors/running/actors-in-store.md#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 Lookup — Gulf & MENA Job Postings by Keyword & Location

You write job searches the way you'd type them into Bayt — `accountant @ Dubai` — and this actor
runs each one against **Bayt.com's own search-results pages**, one of the largest job boards in
the Gulf and wider MENA region, and returns one clean row per posting: title, company, location,
career level, pay range (when Bayt shows one), Bayt's own AI-written summary, and a permanent
link.

Bayt sits behind Cloudflare — a bare request gets a 403 challenge page, not the listing. This
actor requests every page through Apify's UNBLOCKER proxy, which clears it cleanly (a real,
server-rendered page comes back, no headless browser needed), so you never have to think about
that yourself.

### Who it's for

A staffing agency or in-house recruiter hiring across the UAE, Saudi Arabia, Qatar or the wider
Gulf wants a live feed of what's actually open right now, by role and by city, without clicking
through Bayt's own results pages by hand. A market-research or BI team tracking Gulf hiring
demand for a sector or a set of employers wants the same feed at scale, across many searches at
once. Both get the same shape here: paste a list of "keyword @ location" searches, get back a
flat row per posting, and pay only for postings actually returned — a search that finds nothing
costs nothing.

This actor is the Gulf/MENA-focused counterpart to `seek-jobs-search-lookup` (Australia),
`stepstone-jobs-lookup` (DACH) and `dice-jobs-lookup` (US tech): wide-net keyword + location
search rather than a per-company listing. The ATS lookups in the same family
(`greenhouse-jobs-lookup`, `lever-jobs-lookup` and friends) answer "what is *this company*
hiring for" — you bring the company list. This one answers "who is hiring for *this role*, in
*this Gulf city*" when you don't have the list yet.

### Why this one

- **Gets past Bayt's Cloudflare wall for you.** A plain request to Bayt returns an HTTP 403
  challenge page — confirmed directly, not assumed. This actor routes every request through
  Apify's UNBLOCKER proxy group, which clears it cleanly: a normal 200 response with the full,
  real, server-rendered listing. No headless browser is needed once past that wall, since Bayt's
  own job cards are already in the HTML it sends back.
- **`postedAt` is a real timestamp, not a guess.** Bayt embeds an exact Unix-epoch instant on
  every posting's "posted X ago" badge — this actor reads that directly, so `postedAt` is an
  absolute date, not a same-day approximation reverse-engineered from relative text (the best
  several sibling job-board actors on other sites can do). `postedAgo` still carries Bayt's own
  human wording ("2 days ago") alongside it.
- **A real summary, not a blank field.** Bayt writes its own short AI summary of each posting and
  puts it right on the search card — this actor reads it into `description` (truncated to 500
  characters), rather than leaving the field empty because a detail-page fetch wasn't worth
  doubling the request cost, which is the honest trade-off some sibling actors on sparser cards
  had to make.
- **Honest about what Bayt's card genuinely doesn't have.** There is no employment-type
  (full-time/part-time/contract) field on any individual posting — Bayt only exposes that as a
  sidebar filter facet describing the whole result set, never a fact about one specific job — so
  `employmentType` is always `null` here rather than guessed from the facet list. There's no
  structured remote/work-arrangement signal either (Bayt's "remote" toggle is a search filter,
  not a field to read back), so `remote` is title-only detection, same as every sibling job-board
  actor falls back to when a site gives it nothing better.
- **Location narrows honestly, in two layers.** Bayt's own URL structure filters by whole
  country, not by city — a search for `@ Dubai` actually fetches the UAE-wide listing. This actor
  then keeps only the rows whose own displayed location actually mentions "Dubai", so you still
  get city-accurate results without this actor pretending Bayt's URL scheme does something it
  doesn't.
- **You are never billed for the same posting twice.** Every posting is deduplicated by Bayt's own
  job ID across the pages of one search and, by default, across every search in the run — an
  overlapping pair of searches returns, and bills, each posting once.

### What you get

One row per job posting by default. (Turn off "One row per job posting" in the Input tab to get
one row per *search* instead, with the whole posting list nested in `jobs`.) Every row carries
these fields:

| Field | Type / format | Description |
| --- | --- | --- |
| `query` | text | The search line you passed in, unchanged. |
| `found` | boolean | `true` if the search returned at least one posting. `false` rows are never charged. |
| `status` | text | `OK`, `NOT_FOUND` (no postings for that search), `BAD_FORMAT` (a blank line), or `BLOCKED`. |
| `searchKeywords` | text | The keywords actually sent to Bayt. |
| `searchLocation` | text | The location text from your search line (or the run-level default). |
| `jobCount` | number | How many postings this search returned after your filters — this is exactly what you're charged for. |
| `totalAvailable` | number | Bayt's own total-match count for the country-level page this search resolved to, when Bayt's page includes it — best-effort, sometimes `null` (see FAQ). |
| `truncated` | boolean | `true` if more postings were available than you asked for, or if paging stopped early (a mid-run Cloudflare re-challenge). |
| `jobs` | array | The full posting list. Present in every row; it's what gets expanded into separate rows in "one row per posting" mode. |
| `jobId` | text | Bayt's own numeric posting ID — stable, and what deduplication keys on. |
| `title` | text | Job title. |
| `company` | text | Hiring company, or literally "Confidential Company" for postings Bayt itself doesn't name. |
| `location` | text | Location as Bayt prints it on the card, e.g. "Sharjah, UAE". |
| `remote` | boolean | `true` if the title itself reads as remote — see "Why this one" for why there's no location-based half to this check on Bayt. |
| `salaryText` | text | The pay range exactly as Bayt's chip shows it (e.g. "AED 7,345 - AED 11,018"). Present on roughly 6 in 10 postings in this actor's testing — Bayt shows a range for some postings and not others. |
| `employmentType` | text | Always `null` — see "Why this one". Kept as a column for schema consistency with this portfolio's other search-shaped job-board actors. |
| `postedAt` | date (ISO) | The exact instant Bayt's own timestamp encodes — see "Why this one". |
| `postedAgo` | text | Bayt's own words for the same thing ("2 days ago"). |
| `url` | link | Permanent link to the posting on bayt.com. |
| `description` | text | Bayt's own short AI-written summary of the posting, truncated to 500 characters. |
| `careerLevel` | text | Bayt's own seniority + experience line, e.g. "Mid career · 2-5 Years of Experience", when shown. |
| `isFeatured` | boolean | `true` if Bayt marked this posting "Featured" in the results. |
| `scrapedAt` | date (ISO) | When this actor fetched the row. |

A search that returns no postings comes back as a single `found: false` row with a
`status`/`message` explaining why, and is never charged. So does a blank line.

### Pricing

- **Job posting returned**: $1.5 per 1,000 job postings

Plus a $0.00005 start fee per run. Each event above is billed independently, only when it actually returns data — misses (`found:false`) are never charged.

Pay-per-event, per job posting returned:

- **Job posting returned**: $1.5 per 1,000 job postings, less on paid Apify plans.

Plus a $0.00005 start fee per run. Misses (`found: false`) are never charged.

You're charged **per posting returned**, not per search — a search that returns 12 postings costs
twelve, a search that returns none costs nothing, and a blank line costs nothing.

Getting past Bayt's Cloudflare wall needs Apify's UNBLOCKER proxy group, already configured by
default — there's nothing for you to set up, but it is a real, metered cost on this actor's own
side, which is reflected in the price: this is a little higher per posting than a plain-HTTP
job-board actor like `dice-jobs-lookup` or `seek-jobs-search-lookup`, which need no proxy at all.

1,000 postings through this actor: **~$1.50** if every search finds results, less on a paid Apify
plan. Because you pay per posting, "Most postings to return per search" is your budget control:
leave it at 50 and a ten-search run costs at most 500 postings' worth.

### How to use

1. **In the Apify Console.** Open the actor page and click **Start** — the `searches` field is already pre-filled with a working example. Results land in the run's dataset as soon as each item is found.
2. **Via the API.** Call it directly with a POST request — no Console needed once you have an API token:
   ```bash
   curl "https://api.apify.com/v2/acts/accountable_eel~bayt-jobs-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
     -X POST \
     -H "Content-Type: application/json" \
     -d '{"searches":["accountant @ Dubai"]}'
   ```
3. **On a schedule.** Save this actor as an Apify **Task** with the input you want, then add a **Schedule** (hourly, daily, weekly) so it runs on its own — no server of your own required.

Paste one search per line:

```
accountant @ Dubai
sales manager
civil engineer @ Riyadh
```

A line with no `@ location` uses the location you set once in **🔍 Search settings** — leave that
blank too and the search covers Bayt's "international" (all-country) listing.

**🔍 Search settings**:

| Input | What it does |
| --- | --- |
| `defaultLocation` | Location for any line that doesn't name one. Write it the way Bayt does — "Dubai", "Riyadh", "Doha", or a country name. |
| `maxJobsPerQuery` | Most postings to return per search. Default 50. |

**🎯 Narrow the results** — applied here, to the postings after they arrive. They combine with AND
across fields and OR within a field:

| Input | What it does |
| --- | --- |
| `titleKeywords` | Keep only titles containing one of these. |
| `excludeTitleKeywords` | Drop titles containing one of these. Applied after the include list. |
| `companies` | Keep only these companies — partial names match. |
| `excludeCompanies` | Drop these companies — useful for filtering out recruitment agencies you already know. |
| `locations` | Narrow a wide search to particular cities — applied on top of whatever your search line already narrowed. |
| `remoteOnly` | Keep only roles whose title reads as remote. |
| `skipDuplicateJobs` | On by default. Each posting is returned, and billed, once per run even if two searches overlap. |

### Input

```json
{
  "searches": [
    "accountant @ Dubai"
  ]
}
```

One search per line. Write it as "keywords @ location", or just the keywords and set a location below. Bayt is a Gulf/MENA board — locations are city or country names, e.g. "Dubai", "Riyadh", "Doha". Accepted formats: accountant @ Dubai, sales manager, civil engineer @ Riyadh.

### Output

| query | found | status | searchKeywords | searchLocation | jobCount | totalAvailable | truncated | jobs | jobId | title | company | location | remote | salaryText | employmentType | postedAt | postedAgo | url | description | careerLevel | isFeatured | scrapedAt |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| accountant @ Dubai | true | OK | accountant | Dubai | 50 |  |  | \<all postings found (full list)> | 5481491 | Senior Accountant | eliteUSA | Dubai, UAE | false |  |  | 2026-09-08T09:52:33.000Z | 7 hours ago | https://www.bayt.com/en/uae/jobs/senior-accountant-5481491/ | An exceptional opportunity awaits a detail-oriented Senior Accountant in Dubai. This role demands expertise in maintaining financial records, managing invoicing, and ensuring compliance with UAE accounting standards. The ideal candidate will thrive in a fast-paced environment, ensuring timely and accurate financial reporting while collaborating across departments. | Mid career | false | 2026-09-08T17:44:18.881Z |

A miss comes back as a row with `"found": false` and is never charged.

### Use it from Clay, n8n, Make, or an AI agent

This actor runs synchronously over plain HTTP — call it directly from a script, a workflow tool, or an AI agent, no Apify Console needed once you have an API token.

```bash
curl "https://api.apify.com/v2/acts/accountable_eel~bayt-jobs-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{"searches":["accountant @ Dubai"]}'
```

**n8n.** Add an HTTP Request node: Method `POST`, URL `https://api.apify.com/v2/acts/accountable_eel~bayt-jobs-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>`, Body Content Type `JSON`, JSON Body `{"searches":["accountant @ Dubai"]}` (swap in an expression from an earlier node for a real value).

**Clay.** Add an "HTTP API" column: Method `POST`, URL `https://api.apify.com/v2/acts/accountable_eel~bayt-jobs-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>`, Body `{"searches":["{{search}}"]}`, mapping the row's search into the `searches` array.

**MCP.** In Claude, Cursor, or any MCP client with the Apify MCP server, ask for "Bayt Jobs Scraper | Gulf Jobs API | Apify" — the agent will find and run this actor.

### Tips

- Run "Try it first" on a handful of searches you already know return results for, to sanity-check
  the shape before spending on a full list.
- Keep `maxJobsPerQuery` modest (the default 50 is a sensible ceiling) — you pay per posting
  returned, so a broad keyword search with no location can otherwise return far more rows than a
  narrower one, at proportionally higher cost.
- A search line's location only narrows Bayt's request down to a whole country — use the
  `locations` filter (or just trust the automatic per-search narrowing this actor already applies)
  when you specifically want one city, not a whole country's worth of postings.
- `remoteOnly` only catches roles whose title literally says "remote" — Bayt gives this actor
  nothing else to check a posting's work arrangement against.
- If you need more than the summary in `description`, `url` links straight to the posting on
  bayt.com for anything you've shortlisted.

### vs. alternatives

| | What it costs | What you get | Trade-off |
|---|---|---|---|
| **This actor** (`bayt-jobs-lookup`) | $0.0015 per posting returned (less on paid Apify plans), $0.00005 actor start, nothing for a search that finds nothing | One row per Bayt posting — title, company, location, career level, pay range (when listed), Bayt's own AI summary, and link — filtered by title keyword, company, location, or remote-only | Gulf/MENA listings only. No employment-type field — Bayt never puts one on the card (see "Why this one"). Location narrows to country level via Bayt's own URL scheme, then to city level client-side. |
| **blackfalcondata/bayt-scraper** | Pay-per-result on Apify (163 u30, rated 5.00 on 1 review) | Also scrapes Bayt search results | A single review to judge reliability against. This actor prices per posting rather than a flat run fee, dedupes across overlapping searches, and reads an exact posted timestamp rather than only relative text. |
| **TheirStack** | $0.005–$0.03 per company | A job-postings dataset with history, normalised across many ATS platforms and job boards | Broader coverage across many sources and platforms, and it keeps history. This reads Bayt's own search pages live, at a fraction of that price per row, for the Gulf/MENA region specifically. |
| **Doing it yourself** | Your time + a Cloudflare-clearing proxy, tracking Bayt's own markup as it changes, and handling pagination and dedup by hand | The same data | The Cloudflare-clearing proxy wiring, card parsing, pagination, and dedup this actor already does are the maintenance burden it absorbs. |

Prices for third-party tools are their published figures as of September 2026 and are not tracked
here — check the vendor before relying on the comparison.

### FAQ

**Why is a row empty, or why does `found` say `false`?**
Either the input line is blank (`status: BAD_FORMAT`), Bayt/Cloudflare blocked the request
(`status: BLOCKED`, HTTP 403/429/503), the request failed after retries
(`status: REQUEST_FAILED`), or the search genuinely has no matching postings right now
(`status: NOT_FOUND`). Check the `message` column for the specific reason. None of these are
billed.

**Am I charged for a miss?**
No. You're only charged for postings actually returned. A blocked search, a search with zero
matches, or a blank input line all produce a row (unless you turn on "Hide rows with no result")
and none of them cost anything.

**Why is `employmentType` always empty?**
Bayt's search-results card never carries a full-time/part-time/contract field for an individual
posting — "Employment type" only exists as a sidebar filter facet describing counts across the
*whole* result set. Rather than guess a specific posting's employment type from a facet that
describes hundreds of postings at once, this field is always `null`. It's kept as a column for
schema consistency with this portfolio's other search-shaped job-board actors.

**Is `postedAt` an exact timestamp?**
Yes. Unlike some sibling job-board actors that only have relative text ("2 days ago") to work
from, Bayt embeds an exact Unix-epoch instant directly in the page for every posting, and this
actor reads that value rather than approximating a date from the relative wording. `postedAgo`
still carries Bayt's own human-readable phrase alongside it.

**Why is `totalAvailable` sometimes empty?**
It's read from a "N jobs found" counter Bayt prints on the page — present on some fetches and not
on others in this actor's own live testing, for reasons not yet fully pinned down. When it's
missing, `jobCount` (what you're actually charged for) and every posting field are unaffected —
only the "how many more are out there" context is unavailable for that search.

**Does a search for a specific city actually only search that city?**
Bayt's own URL scheme narrows by whole country, not by city — a search for "@ Dubai" fetches the
UAE-wide listing from Bayt. This actor then automatically keeps only the postings whose own
displayed location mentions "Dubai", so your results are still city-accurate; it just means the
`totalAvailable` count reflects the whole country's total, not a city-specific one.

**Does this handle Cloudflare's block on Bayt?**
Yes, automatically. Every request goes through Apify's UNBLOCKER proxy group by default — there's
nothing for you to configure. If Bayt still re-challenges a session mid-run, that shows up as a
`BLOCKED` status on the affected search rather than a silent failure.

**Do I need to configure proxies?**
No. UNBLOCKER is the default proxy group for this actor specifically, because a plain request to
Bayt is blocked by Cloudflare — this is different from some sibling job-board actors that need no
proxy at all. You don't need to change anything to use it.

**Can I schedule this to re-check the same searches on a cadence?**
Yes — set up an Apify Task with a schedule (daily, weekly, whatever cadence fits) and point it at
this actor with a saved input. Each run is a fresh fetch against Bayt's live listings.

**Can an AI agent call this directly?**
Yes. It's registered on the Apify MCP server — an agent in Claude, Cursor, or another MCP client
can find and run it by name ("Bayt Jobs Scraper | Gulf Jobs API | Apify"), or you can call the
REST endpoint shown above from any script or workflow tool.

### Related actors

- [Dice Jobs Lookup](https://apify.com/accountable_eel/dice-jobs-lookup) — the same keyword +
  location search shape, for US tech roles on Dice.
- [SEEK Jobs Search Lookup](https://apify.com/accountable_eel/seek-jobs-search-lookup) — the same
  shape again, for Australia's largest general job board.
- [StepStone Jobs Lookup](https://apify.com/accountable_eel/stepstone-jobs-lookup) — the same
  shape for the DACH region.
- [ATS Jobs Unified Lookup](https://apify.com/accountable_eel/ats-jobs-unified-lookup) — once you
  have a specific company in mind rather than a keyword search, pull its open postings directly
  from its own ATS.

# Actor input Schema

## `searches` (type: `array`):

One search per line. Write it as "keywords @ location", or just the keywords and set a location below. Bayt is a Gulf/MENA board — locations are city or country names, e.g. "Dubai", "Riyadh", "Doha". Accepted formats: accountant @ Dubai, sales manager, civil engineer @ Riyadh. You're only charged for the ones we actually find — a miss costs nothing.

## `testRun` (type: `boolean`):

Turn this on to test your input on a small sample before running the full list. Turn it off to process everything.

## `onlyFound` (type: `boolean`):

Only keep rows where something was actually found. Misses are always free, whether or not you show them here.

## `includeKeywords` (type: `array`):

Optional. Only keep results that mention at least one of these words (e.g. a job title, a city, a product name). Leave empty to keep everything.

## `excludeKeywords` (type: `array`):

Optional. Drop any result that mentions one of these words. Leave empty to skip nothing.

## `maxResults` (type: `integer`):

Optional. Stop the run once this many results have been found — useful for a quick, cheap sample. Leave blank for no limit.

## `defaultLocation` (type: `string`):

Used for any line that's just keywords. Write it the way Bayt does — "Dubai", "Riyadh", "Doha", or a country name. Leave empty to search all Bayt regions.

## `maxJobsPerQuery` (type: `integer`):

Bayt shows a fixed number of postings per page. This actor stops at a modest page depth per search by default to keep proxy cost predictable — raise it if you need more. You pay per posting returned, so this is also your budget control.

## `titleKeywords` (type: `array`):

Optional. Keep only roles whose title contains at least one of these words. Case doesn't matter and partial words work. Leave empty to keep every role.

## `excludeTitleKeywords` (type: `array`):

Optional. Drop any role whose title contains one of these words. Applied after the include list above.

## `companies` (type: `array`):

Optional. Keep only roles at companies whose name contains one of these. Partial matches work.

## `excludeCompanies` (type: `array`):

Optional. Drop roles at companies whose name contains one of these — handy for filtering out recruitment agencies you already know.

## `locations` (type: `array`):

Optional. Narrow a wide search down to particular cities — e.g. "Dubai", "Abu Dhabi", "Jeddah". Applied to the location Bayt prints on each posting.

## `remoteOnly` (type: `boolean`):

Keep only roles whose title reads as remote. Bayt postings rarely carry a structured remote/work-arrangement field, so this is a title-only signal — treat it as a weak filter, not a guarantee.

## `skipDuplicateJobs` (type: `boolean`):

On by default. Overlapping searches routinely surface the same role — with this on, each posting is returned, and billed, exactly once per run.

## `columns` (type: `array`):

Choose which pieces of information to include in each result row. All are included by default.

## `expandRows` (type: `boolean`):

When on, each job posting found gets its own row instead of being grouped under its search. You're still only charged once per search, no matter how many rows it produces.

## `maxConcurrency` (type: `integer`):

Parallel requests. Keep conservative — this target has no browser fallback, so getting blocked costs more than slow-and-steady.

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

Apify Proxy config. Residential recommended for anti-bot-sensitive targets.

## Actor input object example

```json
{
  "searches": [
    "accountant @ Dubai"
  ],
  "testRun": false,
  "onlyFound": false,
  "includeKeywords": [],
  "excludeKeywords": [],
  "defaultLocation": "",
  "maxJobsPerQuery": 50,
  "titleKeywords": [],
  "excludeTitleKeywords": [],
  "companies": [],
  "excludeCompanies": [],
  "locations": [],
  "remoteOnly": false,
  "skipDuplicateJobs": true,
  "columns": [
    "searchKeywords",
    "searchLocation",
    "jobCount",
    "totalAvailable",
    "truncated",
    "jobs",
    "jobId",
    "title",
    "company",
    "location",
    "remote",
    "salaryText",
    "employmentType",
    "postedAt",
    "postedAgo",
    "url",
    "description",
    "careerLevel",
    "isFeatured"
  ],
  "expandRows": true,
  "maxConcurrency": 5,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "UNBLOCKER"
    ]
  }
}
```

# Actor output Schema

## `results` (type: `string`):

No 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 = {
    "searches": [
        "accountant @ Dubai"
    ],
    "includeKeywords": [],
    "excludeKeywords": [],
    "titleKeywords": [],
    "excludeTitleKeywords": [],
    "companies": [],
    "excludeCompanies": [],
    "locations": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("accountable_eel/bayt-jobs-lookup").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 = {
    "searches": ["accountant @ Dubai"],
    "includeKeywords": [],
    "excludeKeywords": [],
    "titleKeywords": [],
    "excludeTitleKeywords": [],
    "companies": [],
    "excludeCompanies": [],
    "locations": [],
}

# Run the Actor and wait for it to finish
run = client.actor("accountable_eel/bayt-jobs-lookup").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 '{
  "searches": [
    "accountant @ Dubai"
  ],
  "includeKeywords": [],
  "excludeKeywords": [],
  "titleKeywords": [],
  "excludeTitleKeywords": [],
  "companies": [],
  "excludeCompanies": [],
  "locations": []
}' |
apify call accountable_eel/bayt-jobs-lookup --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,accountable_eel/bayt-jobs-lookup"
        }
    }
}
```

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/kY8KhwCb6B5SMJnZ0/builds/nY8kl8IeWQHy7mIg8/openapi.json
