# Naukri Job Scraper: Salaries, Contacts & Company Ratings (`trakk/naukri-jobs-scraper`) Actor

Scrape Naukri.com jobs by keyword, city, experience, salary, work mode and freshness. Every job comes with parsed salary and experience ranges, skills, the company rating and review count, the real employer behind consultancy postings, and any recruiter email or phone the posting names.

- **URL**: https://apify.com/trakk/naukri-jobs-scraper.md
- **Developed by:** [Kelopr\_bk](https://apify.com/trakk) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## Naukri Job Scraper — Jobs, Salaries, Contacts & Company Ratings

Pull job listings from **Naukri.com**, India's largest job board, by keyword, city, experience, pay,
work mode and freshness — and get every posting back as one clean row with the numbers already parsed.

No login. No cookies. No setup.

***

### Why this one

Naukri publishes almost everything as display text: `8-14 Lacs PA`, `3-8 Yrs`, `Not Disclosed`. Most
scrapers hand you that text and leave the work to you. This one gives you the label **and** the parsed
values, so the data is usable the moment it lands.

It also answers three questions the raw listing does not:

- **Is the pay real?** `salaryDisclosed` separates published salaries from hidden ones, so your averages
  are not silently poisoned by zeros.
- **Who is actually hiring?** Consultancies place a large share of Indian job ads under their own name.
  `isConsultantPosting` and `hiringForCompany` tell you when you are looking at an agency and who the role
  is really for.
- **Is the employer any good?** Every row carries the company's AmbitionBox rating and review count.

***

### What one job looks like

```json
{
  "jobId": "011125005678",
  "title": "Area Sales Manager",
  "url": "https://www.naukri.com/job-listings-area-sales-manager-...",
  "companyName": "Onsite Teams",
  "companyUrl": "https://www.naukri.com/onsite-teams-jobs-careers-4589122",
  "companyLogo": "https://img.naukimg.com/logo_images/groups/v1/4589122.gif",
  "companyRating": 4.1,
  "companyReviewsCount": 132,
  "companyAddress": "F67, Plot 2, Manish Global Mall, Sector 22, Dwarka, New Delhi",

  "location": "Hybrid - New Delhi, Gurugram",
  "locations": ["New Delhi", "Gurugram"],
  "workMode": "Hybrid",

  "salaryLabel": "8-14 Lacs PA",
  "salaryDisclosed": true,
  "salaryMinPerYear": 800000,
  "salaryMaxPerYear": 1400000,
  "salaryCurrency": "INR",

  "experienceLabel": "3-8 Yrs",
  "experienceMinYears": 3,
  "experienceMaxYears": 8,

  "skillsPreferred": ["Field Sales"],
  "skillsOther": ["Sales", "Enterprise Sales"],
  "jobRole": "Area Sales Manager (B2B)",
  "roleCategory": "Enterprise & B2B Sales",
  "functionalArea": "Sales & Business Development",
  "industry": "IT Services & Consulting",
  "employmentType": "Full Time, Permanent",
  "educationUG": ["Any Graduate"],

  "applyCount": 87,
  "viewCount": 411,
  "vacancies": 1,
  "postedAt": "2026-08-13 13:09:02",
  "postedLabel": "Today",
  "isConsultantPosting": false,
  "isWalkIn": false,

  "contactEmails": ["dhruv.tomar@onsiteteams.com"],
  "contactWebsites": ["https://onsiteteams.com/"]
}
```

**59 fields** in total, including the full description in text and HTML.

***

### The fields worth paying for

#### Salary you can actually sort on

`salaryMinPerYear` and `salaryMaxPerYear` come back as plain INR numbers — lakhs and crores already
converted. `salaryDisclosed` marks the rows where the employer really published a figure.

Most Indian listings hide pay. Filter to `salaryDisclosed = true` and you get a clean benchmark instead of
an average dragged to zero.

#### Recruiter contacts, when the posting names them

Applications usually route through Naukri, but consultancy ads routinely paste a recruiter's details into
the description. When they do, you get them structured:

```json
"contactEmails": ["hiring@acme.co.in"],
"contactPhones": [{ "raw": "+91 98765 43210", "digits": "919876543210" }],
"contactWebsites": ["https://acme.co.in/careers"],
"contactSocialProfiles": { "linkedin": ["https://linkedin.com/company/acme"] }
```

Nothing is invented — these appear only when the posting actually contains them.

#### Signals nobody else surfaces

- `diversityTag` / `isExclusiveRole` — Naukri marks roles reserved for specific groups, e.g. *"For women"*
- `skillsPreferred` vs `skillsOther` — the must-haves separated from the nice-to-haves
- `isWalkIn` — walk-in interviews, which hire on a completely different timeline
- `applyCount` and `viewCount` — how much competition a posting already has
- `appliesOffsite` — whether applying leaves Naukri for the company's own site

#### The market behind your search

Every run also saves a breakdown of the **whole** result set — not just the rows you paid for:

```json
{
  "totalJobsAvailable": 28571,
  "breakdown": {
    "salaryRanges": [{ "label": "6-10 Lakhs", "count": 26445 }, ...],
    "cities":       [{ "label": "Bengaluru",  "count": 8112  }, ...],
    "departments":  [...], "industries": [...], "workModes": [...]
  }
}
```

Size a market, then decide how much of it to scrape. It lands in the run's key-value store as
`SUMMARY-<your-keyword>`.

***

### Input

| field | what it does |
|---|---|
| `keywords` | one search phrase per entry — each is searched separately |
| `location` | city or region, as typed on Naukri |
| `jobIds` | scrape specific postings directly, skipping search |
| `maxItems` | stops the run once this many jobs are saved |
| `sortBy` | relevance · newest first · salary high→low · salary low→high |
| `jobAgeDays` | last 24 hours · 3 days · week · 15 days · 30 days |
| `experienceYears` | jobs open to a candidate with this many years |
| `workMode` | work from office · remote · hybrid |
| `salaryBand` | one of Naukri's pay bands, from 0-3 up to 75-100 lakhs |
| `fetchJobDetails` | off = faster and cheaper, search fields only |
| `dedupe` | one row per job ID across all your keywords |

Bad input never costs you a run: it is rejected before a single request, with a message naming the field
and the fix.

***

### Recipes

**Fresh remote jobs, best paid first**

```json
{ "keywords": ["python developer"], "workMode": "remote",
  "jobAgeDays": "7", "sortBy": "salaryHighToLow", "maxItems": 200 }
```

**Direct employers only — skip the agencies**

```json
{ "keywords": ["data analyst"], "location": "Bengaluru", "maxItems": 300 }
```

Then keep rows where `isConsultantPosting` is `false`.

**Recruiter leads**

```json
{ "keywords": ["urgent hiring"], "location": "Mumbai", "maxItems": 300 }
```

Then keep rows that have `contactEmails` or `contactPhones`.

**Salary benchmark for a role**

```json
{ "keywords": ["devops engineer"], "maxItems": 500 }
```

Filter to `salaryDisclosed = true`, then average `salaryMinPerYear` and `salaryMaxPerYear`.

**Track one company's hiring**

```json
{ "keywords": ["Infosys"], "jobAgeDays": "7", "maxItems": 200 }
```

***

### Output

Three ready-made views, exportable to **CSV, Excel, JSON or XML**, or readable straight from the API:

- **Jobs** — title, company, location, salary, experience, rating, link
- **Salary & experience** — the parsed numeric ranges
- **Contacts & employer** — agency flag, real employer, recruiter contacts

***

### FAQ

**Do I need a Naukri account?** No. Nothing here needs a login or cookies.

**Why is salary often "Not Disclosed"?** Because most Indian employers hide it. `salaryDisclosed` tells you
which rows carry real figures.

**Why do some jobs have no contacts?** Because the posting did not include any — applications normally go
through Naukri itself. Consultancy ads are where contacts usually show up.

**Why only one work mode or pay band at a time?** Naukri itself accepts a single value for each. The input
mirrors what the site can actually do, rather than pretending and returning nothing.

**How fresh is the data?** Every run is live — nothing is served from a cache.

**Does it cover Naukri Gulf?** Not yet. This scraper targets naukri.com (India).

**How much does it cost?** You pay per job saved, and the price on this page is all-in.

**Something looks wrong?** The run summary lists every issue, and skipped items go to a separate `errors`
dataset with the reason — nothing fails silently.

# Actor input Schema

## `keywords` (type: `array`):

One search phrase per entry, e.g. python developer. Each keyword is searched separately.

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

City or region as typed on Naukri, e.g. Bengaluru. Leave empty for all of India.

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

Scrape specific postings directly by their Naukri job ID, skipping search.

## `maxItems` (type: `integer`):

The run stops once this many jobs are saved.

## `sortBy` (type: `string`):

How Naukri should order the results.

## `jobAgeDays` (type: `string`):

Only keep jobs published inside this window.

## `experienceYears` (type: `integer`):

Match jobs open to a candidate with this many years of experience.

## `workMode` (type: `string`):

Naukri filters on one work mode at a time.

## `salaryBand` (type: `string`):

Naukri offers fixed pay bands and accepts one at a time.

## `fetchJobDetails` (type: `boolean`):

Adds the full description, exact salary figures, role, industry, education, vacancies, applicant count and the real employer behind consultancy postings. Turn off for a faster, cheaper run.

## `includeSearchSummary` (type: `boolean`):

Stores how the whole result set splits by salary, city, department, industry and work mode — the totals behind your search, not just the rows you paid for.

## `dedupe` (type: `boolean`):

Naukri repeats postings across keywords; this keeps one row per job ID.

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

Indian residential routing is used by default, which is what Naukri serves best.

## `maxRetries` (type: `integer`):

How many times a failed request is retried before the job is skipped.

## `requestTimeoutSecs` (type: `integer`):

Maximum time for a single network request.

## Actor input object example

```json
{
  "keywords": [
    "python developer"
  ],
  "jobIds": [],
  "maxItems": 20,
  "sortBy": "relevance",
  "jobAgeDays": "any",
  "workMode": "",
  "salaryBand": "",
  "fetchJobDetails": true,
  "includeSearchSummary": true,
  "dedupe": true,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "IN"
  },
  "maxRetries": 3,
  "requestTimeoutSecs": 25
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

## `salary` (type: `string`):

No description

## `contacts` (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 = {
    "keywords": [
        "python developer"
    ],
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("trakk/naukri-jobs-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 = {
    "keywords": ["python developer"],
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("trakk/naukri-jobs-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 '{
  "keywords": [
    "python developer"
  ],
  "maxItems": 20
}' |
apify call trakk/naukri-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,trakk/naukri-jobs-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/ba4feWNEMqLmoGecw/builds/LR9Njzzo6imou56Su/openapi.json
