# Cutshort Jobs Scraper: India Tech Jobs With Salary (`precious_bathmat/cutshort-job-scraper`) Actor

Scrape India tech and startup jobs from Cutshort: title, company size and stage, salary range, experience, skills, cities and remote. Reads every city page per keyword and adds a hiring report with skills, salaries and employers. No login.

- **URL**: https://apify.com/precious_bathmat/cutshort-job-scraper.md
- **Developed by:** [Mariam Ahmed](https://apify.com/precious_bathmat) (community)
- **Categories:** Jobs, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 jobs

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?

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

## Cutshort Jobs Scraper: India Tech Jobs With Salary

Scrape **India tech and startup jobs from Cutshort** with no login and no API key, and get a **hiring report for every keyword**:

- **Every job**: title, company with **size, stage (bootstrapped, funded, profitable), type and founding year**, cities, **remote / on site**, **years of experience**, **salary range in rupees per year**, skills, job type (full time, internship), posted date, link
- **More than one page per keyword**: Cutshort shows 50 jobs per page, so the Actor reads the keyword's page **for every city** (Bangalore, Pune, Hyderabad, Mumbai, Delhi NCR, Chennai and more) **plus the remote page**, and merges them: **several hundred unique jobs per keyword**
- **Report per keyword**: live jobs on Cutshort, top cities, **most-asked skills**, top hiring companies with size and stage, experience asked, **salary percentiles in lakh**, remote share, agency-posted share and freshness

### What does this Cutshort scraper do?

```
Cutshort · "python" · 4,255 live jobs · 16 pages read · 515 unique jobs
 Bangalore 29% · skills: Python, AWS, SQL, Java, JavaScript
 Median 4 years asked · salary midpoint median 16.3 lakh · 9% fully remote
```

1. Enter **skills or roles** ("python", "react", "devops", "product manager", "sales").
2. Optionally pick **cities**, **remote only** or a **minimum salary**.
3. You get the **jobs as rows** (newest posted first) and **one report per keyword**.

```mermaid
flowchart LR
    A[Skill or role] --> B[Keyword page<br/>all India]
    B --> C[City pages<br/>about 14]
    B --> D[Remote page]
    B --> E[Merge and<br/>remove duplicates]
    C --> E
    D --> E
    E --> F[Jobs]
    E --> G[Report<br/>skills, salary,<br/>employers]
```

### Who is it for?

- **Recruiters and staffing agencies in India**: who is hiring for a skill, in which city, at what salary and seniority
- **Sales teams selling to startups** (HR tech, payroll, training, dev tools): growing companies with their size and funding stage
- **Job seekers and career coaches**: open jobs for a skill with real salary ranges, remote options and the skills that come up most
- **Edtech and bootcamps**: which skills employers ask for next to each other, and what they pay
- **Analysts**: salary and demand signals for tech roles across Indian cities

### What data do you get?

**Jobs** (dataset, one row per job)

| Field | What it tells you |
|---|---|
| `title`, `url`, `keyword`, `foundOn` | The job, and which pages (city, remote, all India) it appeared on |
| `company`, `companyUrl`, `companyType`, `companySize`, `companyStage`, `companyFounded`, `companyFollowers` | The employer |
| `hiringForClient` | `true` when a recruitment agency posted it for a client |
| `locations`, `remote`, `jobTypes` | Where and how |
| `minExperienceYears`, `maxExperienceYears` | Experience asked |
| `salaryCurrency`, `salaryMinPerYear`, `salaryMaxPerYear`, `salaryText` | Pay, in rupees per year |
| `skills`, `postedAt` | Skills on the ad and when it was posted |

**Report** (`REPORTS`, one per keyword)

| Field | What it tells you |
|---|---|
| `liveJobsOnCutshort`, `jobsRead`, `pagesRead`, `jobsSaved` | Market size and how much was read |
| `topLocations`, `topSkills`, `topHiringCompanies` | Where, what and who (agency posts left out of employers) |
| `experience` | Median years asked and jobs per experience band |
| `salaryInr` | 25th / median / 75th percentile salary midpoint in lakh, median top of range |
| `remote`, `jobTypes`, `companyStages`, `companySizes`, `agencyPostedPercent`, `freshness` | The rest of the picture |

### Example: 25 October 2026

Five keywords, every city page plus remote: **2,419 jobs and 5 reports in 89 seconds**, 78 page requests, no proxy needed.

| Keyword | Live jobs | Unique jobs read | Top city | Median years | Salary midpoint median (lakh) | Fully remote | Agency posted |
|---|---|---|---|---|---|---|---|
| python | 4,255 | 515 | Bangalore (29%) | 4 | 16.3 | 9% | 21% |
| react | 3,894 | 559 | Bangalore (22%) | 3 | 15.0 | 8% | 17% |
| java | 4,269 | 535 | Bangalore (29%) | 4 | 16.4 | 8% | 25% |
| product manager | 639 | 282 | Bangalore (26%) | 3 | 20.0 | 5% | 23% |
| sales | 3,376 | 528 | Bangalore (20%) | 1 | 8.5 | 2% | 28% |

- **Product managers are paid the most** of the five (median midpoint 20 lakh); sales roles start lowest (8.5 lakh, median 1 year asked).
- **React jobs most often pair with Node.js, JavaScript and Angular**; Java with Spring Boot and Microservices.
- **One in four jobs is posted by a recruitment agency**, which the `hiringForClient` flag lets you filter out.

### Pricing

**$0.001 per job saved** and **$0.02 per report** (one per keyword).

- One keyword, about 500 jobs with the report: **about $0.52**
- One keyword, report only plus 20 jobs: **$0.04**
- The run above (2,419 jobs, 5 reports): **$2.52**

### Good to know

- **Not every live job**: each Cutshort page shows 50 jobs that Cutshort picks, and they are **not only the newest** (in testing, the median job had been posted 100 to 430 days earlier). Reading every city page gives several hundred unique jobs per keyword; `liveJobsOnCutshort` is Cutshort's own total.
- **Keywords** must match a Cutshort page: single skills ("python", "aws", "docker", "flutter") and common roles ("product manager", "devops", "sales", "digital marketing", "backend developer") work. "react", "node", "machine learning", "ux" and similar are mapped to Cutshort's own page names. If there is no page, the run summary says so.
- **Salary** is in **rupees per year** and shown on most jobs. When the lower end is hidden, `salaryMinPerYear` is empty and `salaryText` shows what Cutshort displays.
- **Privacy**: recruiter names and photos and company descriptions are not collected.
- **Proxy**: requests go direct. Apify datacenter proxy is used only if Cutshort answers "too many requests"; a block stops the run.
- Data comes from **public job pages on cutshort.io**. **Not affiliated with Cutshort.**

### Input

| Field | Meaning |
|---|---|
| **Skills or roles** | One search each (required) |
| **Cities** | Optional; empty = all India |
| **Read every city page** | On by default (with no cities chosen) |
| **Include the remote jobs page** | On by default |
| **Remote jobs only** | Off by default |
| **Minimum salary (lakh per year)** | Optional |
| **Jobs per keyword** | 1 to 2,000 saved, newest posted first (default 500) |
| **Reports** | On by default |

### Integrations

Export to JSON, CSV, Excel or Google Sheets, or connect through the Apify API, webhooks, Make, Zapier and n8n. **Schedule it weekly** to follow salaries and hiring per skill. For more India jobs, see the [Hirist & IIMJobs Scraper](https://apify.com/precious_bathmat/hirist-iimjobs-job-scraper), the [Instahyre Jobs Scraper](https://apify.com/precious_bathmat/instahyre-job-scraper) and the [Internshala Scraper](https://apify.com/precious_bathmat/internshala-scraper).

# Actor input Schema

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

One search each, e.g. "python", "react", "devops", "product manager", "sales", "digital marketing". Cutshort has a page per skill and per common role.

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

Optional: only these cities, e.g. "Bangalore", "Pune", "Hyderabad", "Mumbai", "Gurgaon", "Chennai", "Remote". Empty = all India.

## `allCities` (type: `boolean`):

With no cities chosen, also read the keyword's page for every city Cutshort lists (about 14) and merge them. Each page shows 50 jobs, so this gives several hundred jobs instead of 50.

## `includeRemote` (type: `boolean`):

Also read the keyword's remote jobs page.

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

Only the keyword's remote jobs page.

## `minSalaryLakh` (type: `integer`):

Optional: only jobs whose salary range goes up to at least this many lakh rupees a year (20 = ₹20,00,000).

## `maxJobsPerKeyword` (type: `integer`):

Most jobs to save per keyword, newest first (1 to 2,000).

## `includeReports` (type: `boolean`):

One hiring report per keyword: live jobs on Cutshort, top cities, most-asked skills, hiring companies with size and stage, experience, salary percentiles, remote share and freshness.

## Actor input object example

```json
{
  "keywords": [
    "python"
  ],
  "allCities": true,
  "includeRemote": true,
  "remoteOnly": false,
  "maxJobsPerKeyword": 500,
  "includeReports": true
}
```

# Actor output Schema

## `jobs` (type: `string`):

One row per job: title, company with size and stage, locations, remote, experience, salary, skills, posted date, link.

## `reports` (type: `string`):

Per keyword: top cities, skills, hiring companies, experience, salary percentiles, remote share and freshness.

## `reportsCsv` (type: `string`):

One flat row per keyword.

## `summary` (type: `string`):

Requests, problems and the limits of the data.

# 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"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("precious_bathmat/cutshort-job-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"] }

# Run the Actor and wait for it to finish
run = client.actor("precious_bathmat/cutshort-job-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"
  ]
}' |
apify call precious_bathmat/cutshort-job-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,precious_bathmat/cutshort-job-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/uyQ1yOD4tu4sXJwO8/builds/rNpd4LyyXMx8Sb7XU/openapi.json
