# Naukri Jobs Scraper — India & Gulf (`valev-lab/naukri-scraper`) Actor

Scrape Naukri.com and Naukrigulf jobs by keyword, city, or job URL. Titles, companies, salaries, skills, and descriptions in one schema. No login. From $1.00 per 1,000 jobs.

- **URL**: https://apify.com/valev-lab/naukri-scraper.md
- **Developed by:** [Daniel Valev](https://apify.com/valev-lab) (community)
- **Categories:** Jobs, Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.60 / 1,000 job listings

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?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

Scrape jobs from [Naukri.com](https://www.naukri.com/) (India) and [Naukrigulf.com](https://www.naukrigulf.com/) (UAE, Saudi Arabia, Qatar, and the wider Gulf). Search by **keyword**, **city**, **job URL**, or **job ID**. Get titles, companies, experience, salaries, skills, and descriptions in one schema — ready for Sheets, a database, or an AI workflow. **No Naukri account or API key.**

### What does Naukri Jobs Scraper do?

This Actor reads public job posts and returns one structured row per job. Use it as a **Naukri API alternative** and a **Naukrigulf scraper** for recruiting, hiring-market research, and lead lists of companies that are hiring.

A **listing** row is the search result: title, company, location, experience, skills, and a short description. A **detail** row replaces it when you want the full description, education, company profile, published salary, Naukri AmbitionBox ratings, or Naukrigulf compensation. You choose that per run, so a broad search stays cheap.

Provide a keyword, extra cities, start URLs, or job IDs. Duplicate jobs are stored once. Set `maximumJobs` to cap the run.

### Who is it for?

- **Recruiters and talent teams** — Build sourced lists for India and Gulf roles without copying from the browser.
- **HR and talent intelligence** — Track which companies are hiring, for which titles, and at what published experience.
- **Staffing agencies** — Watch a keyword or city and collect only jobs that appeared or changed since yesterday.
- **Sales teams** — Find companies hiring for a tool or skill, then export the company name and job link.
- **Analysts and AI workflows** — Feed clean JSON into Sheets, a warehouse, or an agent. Compact mode keeps the short row.

### Why scrape Naukri and Naukrigulf?

- **Both boards, one schema** — India and the Gulf in the same fields. Run one board or both.
- **No login** — Public job pages only. No Naukri or Naukrigulf account.
- **Pay for the depth you use** — Listing rows for discovery. Detail rows only when you need the full text.
- **Salary and skills** — Experience range, skill list, and salary when the employer published them. Hidden salaries stay marked hidden.
- **AmbitionBox on Naukri details** — Rating, review count, role salary range, and benefits from the job payload. No separate AmbitionBox crawl.
- **Job monitoring** — Schedule a run and pay later cycles only for new and updated jobs.
- **Apify platform** — Schedule, API, webhooks, and Zapier, Make, or n8n. Download JSON, CSV, Excel, or HTML.

### What data can you extract?

| Field | Description |
| --- | --- |
| `source` / `jobId` / `url` / `title` | Board, id, public job URL, and title |
| `company` | Name, id, logo, website, and profile text on detail rows |
| `location` / `workMode` | City, country, and office / remote / hybrid when the job says so |
| `experience` | Minimum, maximum, and the text range (for example 8–12 years) |
| `salary` | Min, max, currency, lakhs for INR, and `isHidden` when the employer hid pay |
| `skills` | Skills from the job. Preferred and other skills on Naukri detail rows |
| `description` | Short text on listings. Full text, HTML, or Markdown on detail rows |
| `education` / `classification` | Degrees, industry, and role on detail rows |
| `engagement` | Vacancies, and Naukri apply and view counts when present |
| `ambitionBox` | Naukri rating, reviews, benefits, and role salary. Detail rows |
| `candidate` | Naukrigulf nationality and gender requirement. Not a person's data |
| `postedAt` | Posting time in UTC |
| `contact` | Recruiter name, email, or phone **only if you opt in** |
| `changeType` | `NEW`, `UPDATED`, or `UNCHANGED` when monitoring is on |

### How to scrape Naukri jobs

1. Open **Naukri Jobs Scraper** on Apify and click **Try for free**.
2. For Gulf jobs, set the board to Naukrigulf, a keyword such as `software engineer`, and a city such as `dubai`.
3. For India, set the board to Naukri and a keyword such as `developer`. Leave location empty.
4. Set **Maximum jobs**. Start with 20 while you check the rows.
5. Turn on **Fetch job details** only when you need the full description, salary block, or AmbitionBox.
6. Click **Start**. Download JSON, CSV, Excel, or HTML, or send the dataset to an integration.

No code is required in Console. Developers can use the **API** tab or `apify call`.

### How much does it cost to scrape Naukri jobs?

Pricing is [pay-per-event](https://docs.apify.com/platform/actors/running/pay-per-event). You pay for rows you actually receive. There is no monthly fee from this Actor.

| Event | Free / no discount | What you pay for |
| --- | ---: | --- |
| **Job listing** | $0.001 / job ($1.00 / 1,000) | A search-result row |
| **Job detail** | $0.0025 / job ($2.50 / 1,000) | A full row. Replaces the listing charge for that job |
| **Contact found** | $0.002 / contact ($2.00 / 1,000) | Only when you opt in and a name, email, or phone is present |

Volume discounts on higher Apify plans:

| Plan | Listing / 1,000 | Detail / 1,000 | Contact / 1,000 |
| --- | ---: | ---: | ---: |
| No discount (Free) | $1.00 | $2.50 | $2.00 |
| Bronze | $0.80 | $2.00 | $2.00 |
| Silver | $0.70 | $1.80 | $2.00 |
| Gold | $0.60 | $1.50 | $2.00 |

**Example (Free plan):** 50 Dubai listing rows ≈ `50 × $0.001 = $0.05`. The same 50 jobs with details ≈ `$0.125`.

Duplicates, blocked pages, empty searches, and unchanged monitored jobs are **not** charged. Apify compute and proxy are billed by the platform separately.

> Put these prices in Console **Publishing → Monetization** before the Actor is public. `job-listing` is the primary event. Do not also enable the default dataset-item charge, or every row is billed twice.

### Input

See the **Input** tab for the form.

| Field | Default | Notes |
| --- | --- | --- |
| `platform` | `naukri` | `naukri`, `naukrigulf`, or `both`. An empty run uses Naukrigulf |
| `searchQuery` | — | One keyword, such as `software engineer` or `nurse` |
| `searchQueries` | — | Several keywords. Replaces the single query. Results are deduplicated |
| `location` / `cities` | — | Naukrigulf cities (`dubai`, `abu dhabi`, `riyadh`, `doha`). Each extra city is its own search |
| `startUrls` | — | A Naukrigulf jobs URL, a `jid-` job URL, or a Naukri `job-listings` URL |
| `jobIds` | — | Job IDs or job URLs. Always fetched as detail rows. Overrides search |
| `maximumJobs` | `100` | Cap for the whole run. The empty sample run saves 5 |
| `fetchDetails` | `false` | Full description, education, company profile, salary, AmbitionBox |
| `includeContacts` | `false` | Recruiter contact published on the job. Off by default. Billed separately |
| `descriptionFormat` | `text` | `text`, `html`, `markdown`, or `all` from the same HTML |
| `outputMode` | `full` | `compact` keeps title, company, city, experience, salary label, skills, and date |
| `incremental` | `false` | Later runs bill only new and updated jobs |
| `proxyConfiguration` | Residential | India for Naukri, UAE for Naukrigulf, unless you set a country |

**Tips**

- Job IDs win over pasted URLs, and pasted URLs win over keywords.
- A Naukri search with a city is skipped. Naukri does not offer that filter yet, and the Actor will not silently return all of India.
- `keyword`, `limit`, `maxItems`, and `jobBoard` are accepted as aliases for older inputs. The field on this form wins when both are set.

### Output

Download the dataset as **JSON, CSV, Excel, or HTML**. Example listing row from a Dubai software-engineer search:

```json
{
  "source": "naukrigulf",
  "jobId": "071026000143",
  "url": "https://www.naukrigulf.com/senior-full-stack-software-engineer-jobs-in-dubai-uae-in-dicetek-llc-8-to-12-years-m-cd-41691-jid-071026000143",
  "title": "Senior Full Stack Software Engineer",
  "detailLevel": "listing",
  "company": { "id": "41691", "name": "Dicetek LLC" },
  "location": { "cities": ["Dubai"], "country": "United Arab Emirates", "raw": "Dubai - United Arab Emirates (UAE)" },
  "experience": { "min": 8, "max": 12, "text": "8-12" },
  "skills": { "all": ["REST APIs", "Java", "Spring Boot"] },
  "postedAt": "2026-10-07T04:00:00.000Z"
}
```

Turn on **Fetch job details** for the full description, `salary.isHidden`, currency, education, and company text. Naukri detail rows add AmbitionBox rating, benefits, and role salary when the job page includes them.

`compact` mode keeps `source`, `jobId`, `url`, `title`, `company.name`, `location.cities`, `workMode`, `experience.text`, `salary.label`, `skills.all`, and `postedAt`.

A `RUN_SUMMARY` record in the run key-value store reports how many rows were saved, how many were details, and whether the run was empty, partial, or blocked.

### Tips for better runs

- Start with `maximumJobs` of 20 and listing rows. Turn on details after the titles look right.
- Use Naukrigulf plus a city when the brief is Dubai, Abu Dhabi, Riyadh, or Doha.
- Use several `searchQueries` for a family of titles (`data analyst`, `business analyst`) instead of one vague word.
- Schedule a daily run with **Only new and updated jobs** for a hiring watch. The first run is the baseline and is billed in full. The next run bills the jobs that are new or whose title, company, salary, experience, location, or description changed.
- Paste a job URL when you already have the posting and only want that row.

### For developers and AI agents

Smallest Gulf search:

```json
{ "platform": "naukrigulf", "searchQuery": "software engineer", "location": "dubai", "maximumJobs": 20 }
```

India keyword, listing only:

```json
{ "platform": "naukri", "searchQuery": "developer", "maximumJobs": 20 }
```

One known job:

```json
{ "platform": "naukrigulf", "jobIds": ["071026000143"] }
```

Add `"outputMode": "compact"` when the short row is enough. Leave `includeContacts` false unless the task asks for recruiter details.

### Limitations

- **Naukri city, freshness, salary band, and experience filters are not available yet.** Search Naukri by keyword. Filter Gulf jobs by city.
- **Naukri returns at most 3,000 jobs per keyword** (150 pages). Raise `maximumJobs` only up to what you need.
- **Salaries are often hidden**, especially on Naukri. The row says `isHidden: true` instead of inventing a number.
- **Naukri detail rows** need a short session warmup. If a detail page is blocked, the listing row is still saved and the block is counted in the run summary.
- **Arabic job text is not a separate output.** Gulf pages are returned as published.
- **Company overview URLs** are skipped with a log line. Use a keyword or a job URL.
- Recruiter emails are not guessed from company websites.

### FAQ

#### Is this a Naukri API?

It is an **API alternative**. You get structured Naukri and Naukrigulf jobs through Apify Console, the REST API, or an integration, without a Naukri developer account. It is not an official Naukri or Info Edge API.

#### Do I need a Naukri account?

No. The Actor reads public job listings only.

#### Can I scrape Naukri jobs in Bangalore?

Not by city. A Naukri keyword search covers India and does not accept a location filter yet. For Dubai and other Gulf cities, set the board to Naukrigulf and fill **Location**.

#### How do I get salary, description, and AmbitionBox data?

Turn on **Fetch job details**. AmbitionBox rating, benefits, and role salary are included when Naukri puts them on the job. They are not a second website crawl. If the employer hid the salary, `salary.isHidden` is true.

#### Can I extract recruiter emails from Naukri?

Only when you turn on **Include recruiter contacts**, and only if the employer published a name, email, or phone on that job. The field is absent otherwise, including as an empty placeholder. Those rows are billed as `contact-found`. Do not enable this without a lawful reason.

#### How do I monitor new Naukri or Naukrigulf jobs?

Turn on **Only new and updated jobs** and keep the same search and **State key**. Day one stores the baseline. Later scheduled runs return and charge the new and changed jobs.

#### Can one run cover India and the Gulf?

Yes. Set the board to **Both**. Use a location only if you accept that the Naukri half is skipped when a city is set. For both boards with a city, run Naukri by keyword in one task and Naukrigulf with a city in another.

#### What if the dataset is empty?

If the board returned a normal empty page, the run succeeds and the summary says `VALID_EMPTY`. Widen the keyword or confirm the search in a browser. A blocked run with zero rows fails and the summary says why.

### Legal and ethics

> This Actor collects job information that employers have published on Naukri and Naukrigulf. It does not log into either site. Recruiter names, emails, and phone numbers are personal data: they are off by default, omitted entirely when off, and stored only if you opt in. AmbitionBox reviewer names are never stored. Personal data is protected by the GDPR in the EU and by other laws worldwide. Scrape and use results only for a legitimate purpose. If you are unsure, consult your lawyers. Respect each site's terms and applicable hiring and privacy rules.

### Support

- Use the **Issues** tab on this Actor’s Store page for bugs and feature requests.
- Use the **API** tab for programmatic runs, webhooks, and dataset access.
- Built for scheduled hiring watches on the Apify platform.

# Actor input Schema

## `platform` (type: `string`):

Used for keyword search. Job URLs and job IDs choose the board from the value itself. A bare job ID with Both is skipped because the boards share numeric IDs.

## `searchQuery` (type: `string`):

Job title or skill, for example software engineer, data analyst, nurse, or accountant. Ignored when Search queries is not empty.

## `searchQueries` (type: `array`):

Several keywords. Each one is a separate search, and duplicate jobs are stored once.

## `location` (type: `string`):

Naukrigulf city, for example dubai, abu dhabi, riyadh, doha, or qatar. Naukri does not accept a city filter yet: a Naukri search that includes a location is skipped instead of returning all of India.

## `cities` (type: `array`):

Naukrigulf only. Each city is its own search, crossed with the keywords.

## `startUrls` (type: `array`):

Naukrigulf SEO URLs (...-jobs-in-dubai) and job URLs ending in jid-ID. Naukri job-listings URLs that end in a job ID. Company overview URLs are logged and skipped.

## `jobIds` (type: `array`):

Job IDs or full job URLs. These are fetched as detail rows. A bare ID needs the job board to be Naukri or Naukrigulf, not Both.

## `maximumJobs` (type: `integer`):

Cap on stored rows for the whole run. The empty health-check run uses 5.

## `maxJobsPerSearch` (type: `integer`):

Optional cap for each keyword or URL. Leave empty to use only the run cap.

## `fetchDetails` (type: `boolean`):

Open each job and store a detail row instead of a listing row. Adds the full description, education, company profile, AmbitionBox data on Naukri, and Naukrigulf compensation.

## `includeContacts` (type: `boolean`):

Off by default. When on, a contact published on the job itself (name, email, phone) is stored and billed as contact-found. This is personal data: use it only with a lawful reason. Contacts are omitted entirely, including as null, when this is off. Reviewer names from AmbitionBox are never stored.

## `descriptionFormat` (type: `string`):

Converted locally from the same HTML. No extra request.

## `outputMode` (type: `string`):

Compact keeps title, company, location, experience, salary label, skills, and posted time.

## `includeRaw` (type: `boolean`):

Attach the source JSON under raw. Full output only.

## `incremental` (type: `boolean`):

The first run stores the baseline and is billed in full. Later runs bill NEW and UPDATED rows. UNCHANGED rows are skipped unless Emit unchanged is on.

## `stateKey` (type: `string`):

Name of the saved baseline. Leave empty to derive one from the search. A second run with the same key within 30 minutes is refused.

## `emitUnchanged` (type: `boolean`):

Also store UNCHANGED rows. They are still not billed as a separate event; the row uses the normal listing or detail event.

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

Reserved for request parallelism. Pages of one search stay in order.

## `maxRequestRetries` (type: `integer`):

Retries after a blocked response before the session is retired.

## `deepSearch` (type: `boolean`):

Reserved. Naukri stops at 3,000 jobs per query, but the parameters needed to slice a query were not confirmed, so this does not send extra requests.

## `extraUrlParams` (type: `array`):

Advanced query parameters appended to the job API request. Parameters whose names start with geoIp are dropped.

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

Residential proxy. Naukri uses India and Naukrigulf uses the UAE unless you set a country here.

## Actor input object example

```json
{
  "platform": "naukrigulf",
  "searchQuery": "software engineer",
  "searchQueries": [],
  "location": "dubai",
  "cities": [],
  "jobIds": [],
  "maximumJobs": 5,
  "fetchDetails": false,
  "includeContacts": false,
  "descriptionFormat": "text",
  "outputMode": "full",
  "includeRaw": false,
  "incremental": false,
  "stateKey": "",
  "emitUnchanged": false,
  "maxConcurrency": 5,
  "maxRequestRetries": 5,
  "deepSearch": false,
  "extraUrlParams": [],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `dataset` (type: `string`):

No description

## `runSummary` (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 = {
    "platform": "naukrigulf",
    "searchQuery": "software engineer",
    "location": "dubai",
    "maximumJobs": 5
};

// Run the Actor and wait for it to finish
const run = await client.actor("valev-lab/naukri-scraper").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 = {
    "platform": "naukrigulf",
    "searchQuery": "software engineer",
    "location": "dubai",
    "maximumJobs": 5,
}

# Run the Actor and wait for it to finish
run = client.actor("valev-lab/naukri-scraper").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 '{
  "platform": "naukrigulf",
  "searchQuery": "software engineer",
  "location": "dubai",
  "maximumJobs": 5
}' |
apify call valev-lab/naukri-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,valev-lab/naukri-scraper"
        }
    }
}
```

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/XqhRimpCffvYY2EVo/builds/Cp8oPl1lpXwBRydxh/openapi.json
