# Cutshort Jobs Scraper (`piotrv1001/cutshort-jobs-scraper`) Actor

The Cutshort Jobs Scraper extracts Indian tech jobs from Cutshort.io by skill, role and city, capturing skills, experience ranges, remote policy, displayed salaries split into currency and period, company details and full descriptions — ideal for tech recruiting and salary research.

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

## Pricing

from $1.50 / 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.

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

Extract tech job openings from Cutshort, one of India's biggest boards for startup and tech jobs. The **Cutshort Jobs Scraper** collects jobs by skill or role (Python, React, DevOps, Data Science…) and city. Each job comes with its skill list, experience range, remote policy, company details, full description and the salary exactly as Cutshort shows it, split into currency, period, minimum and maximum.

### ✨ Features

- 🧑‍💻 **Search by skill or role**: type `Python`, `React`, `Machine Learning` or `Product Management`. Each term is matched to the Cutshort job list of the same name. Terms with no list are skipped, and the log suggests close matches.
- 📍 **14 Indian cities**: Bangalore, Mumbai, Delhi NCR, Hyderabad, Pune, Chennai and more. If a skill has no list for your city, it is skipped. It is never widened to all of India without telling you.
- 💰 **Salary as displayed**: `₹10L - ₹20L / yr` becomes `INR`, `YEAR`, `1000000`, `2000000`. Monthly salaries stay monthly, "Upto" salaries keep only a maximum, and "Best in industry" stays undisclosed. No salary is guessed.
- 🌍 **Strict remote filter**: keeps only jobs the employer marks as *remote only*. Remote-friendly jobs are dropped.
- 🎓 **Experience filter**: keeps jobs whose experience range overlaps yours. A 1–4 year job matches 2–5.
- 🗓️ **Posted-after filter**: lists are sorted newest first, so the run stops as soon as it reaches older jobs.
- 🏢 **Company data**: name, Cutshort company page, website, LinkedIn, size, type, founding year and logo.
- ✅ **Optional job-page check**: adds whether the job is still open and the recruiter's latest hiring activity. That activity date is kept separate from the posting date.
- 🔗 **URL input**: paste any Cutshort job list (`/jobs/...`) or single job page (`/job/...`).
- 🧾 **Run summary**: for each list, the run saves the number of jobs on Cutshort, pages read, jobs scanned, jobs matching your filters and why the run stopped. It goes to the `RUN_SUMMARY` record.

### 🛠️ How It Works

1. **Enter skills or roles**, e.g. `Python`. Optionally pick a city or paste Cutshort URLs.
2. **Set filters** (remote only, experience, posted after) and the **maximum number of jobs**.
3. **Run the scraper.** Jobs from all lists are merged, and a job that appears in several lists is saved and charged once.

### 💵 Pricing

You pay per job saved. No monthly fee.

| Event       | Price                    | What you get                                                                                                                                                  |
| ----------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Job listing | **$1.50 per 1,000 jobs** | Title, company details, skills with Cutshort skill IDs, locations, remote policy, experience range, displayed salary, job type, posted date, full description |
| Job detail  | **$2.00 per 1,000 jobs** | Everything in a listing plus whether the job is still open, the recruiter's latest hiring activity date and role tags (only with **Check job pages**)         |

Duplicates, jobs dropped by filters and job URLs that are no longer online are free.

### 📊 Sample Output Data

```json
[
    {
        "jobId": "6ab3bf0c3cb9791c346260e4",
        "url": "https://cutshort.io/job/FULL-STACK-DEVELOPER-PHP-PYTHON-REACT-JS-Chennai-Zealous-Healthcare-Services-46oRmohw",
        "title": "FULL STACK DEVELOPER – PHP/PYTHON & REACT.JS",
        "companyName": "Zealous Healthcare Services",
        "companyId": "6a5e680dfdc50f9ac5ff8eec",
        "companyUrl": "https://cutshort.io/company/jobs-at-zealous-healthcare-services-94-bkrjfhtW",
        "companyWebsite": "https://zealoushealthcare.com",
        "companyLinkedin": "http://www.linkedin.com/company/zealous-healthcare",
        "companyLogo": "https://cdn.cutshort.io/public/images/default_company_picture.jpg",
        "companyType": "Services",
        "companySize": "20-100",
        "companyFounded": 2007,
        "hiringForClient": false,
        "skills": ["Python", "PHP", "React.js", "Javascript", "HTML/CSS", "css3", "MySQL"],
        "skillIds": {
            "00360": "Python",
            "00333": "PHP",
            "00368": "React.js",
            "00237": "Javascript",
            "00212": "HTML/CSS",
            "06727": "css3",
            "00300": "MySQL"
        },
        "remoteType": "remote_not_okay",
        "locations": ["Chennai"],
        "locationsText": "Chennai",
        "roleTypes": ["full_time"],
        "experienceMin": 1,
        "experienceMax": 4,
        "salaryText": "₹3L - ₹8L / yr",
        "salaryCurrency": "INR",
        "salaryPeriod": "YEAR",
        "salaryMin": 300000,
        "salaryMax": 800000,
        "salaryDisclosed": true,
        "postedAt": "2026-09-23T11:59:08.109Z",
        "descriptionText": "🚀 WE’RE HIRING | FULL STACK DEVELOPER – PHP/PYTHON & REACT.JS\n📍 Location: Chennai, Tamil Nadu – On-site\n💼 Experience: 1–4 Years\n...",
        "descriptionHtml": "<p>🚀 WE’RE HIRING | FULL STACK DEVELOPER – PHP/PYTHON &amp; REACT.JS</p>...",
        "sourceQuery": "Python",
        "sourceList": "https://cutshort.io/jobs/python-jobs",
        "scrapedAt": "2026-09-23T12:22:04.757Z"
    }
]
```

With **Check job pages** enabled, each job also has `jobValid` (true/false), `hiringActivityAt` (the recruiter's latest activity) and `roleTags` (e.g. `["fullstack"]`).

### 📝 Good to Know

- **`remoteType`** is set by the employer: `remote_only`, `remote_okay` (remote-friendly) or `remote_not_okay`. Some descriptions add location conditions, so read `descriptionText` before treating a job as fully remote.
- **Skills come from the employer's tags.** A job in the Python list has Python among its skills, but Python may not be the main skill for the role.
- **`postedAt` is the posting date from the job list.** `hiringActivityAt` (job-page check only) is the recruiter's latest activity and can be months later. Cutshort lists also include older postings, so use **Posted after** or **Check job pages** when you need current openings.
- **Single job pages** have no structured location list: `locations` is `null` and `locationsText` holds the displayed locations. They also have no list posting date.
- **Salary figures are the displayed ones.** When Cutshort shows "Best in industry", every salary field except `salaryText` is empty.
- **Totals move while you scrape.** The run summary records the Cutshort total at the first and last page, so you can tell a complete list from a partial one.

Find your next tech hire or map India's startup job market with the **Cutshort Jobs Scraper**! 🚀

# Actor input Schema

## `skills` (type: `array`):

Cutshort skills or roles to collect jobs for, e.g. `Python`, `React`, `DevOps`, `Data Science`, `Product Management`. Each one is matched to the Cutshort job list of the same name; terms that match no list are skipped with suggestions in the log.

## `city` (type: `string`):

Only jobs from this city's list. Leave on All India for every location. When Cutshort has no list for a skill in this city, that skill is skipped rather than widened to all of India.

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

Cutshort job list pages (e.g. `https://cutshort.io/jobs/reactjs-jobs-in-pune`) or single job pages (`https://cutshort.io/job/...`). Filters below apply to job lists; single job pages are always saved with full details.

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

Keep only jobs the employer marks as remote only. Jobs that are merely remote-friendly (`remote_okay`) are dropped. The label comes from the employer; check `descriptionText` for location conditions.

## `experienceMin` (type: `integer`):

Keep jobs whose experience range overlaps your range, e.g. 2 keeps a 1–4 year job.

## `experienceMax` (type: `integer`):

Keep jobs whose experience range overlaps your range, e.g. 5 keeps a 3–8 year job but drops an 8–12 year job.

## `postedAfter` (type: `string`):

Keep only jobs posted on or after this date. Lists run newest first, so the scraper stops once it reaches older jobs.

## `includeDetails` (type: `boolean`):

Also open each job page to add whether the job is still open (`jobValid`), the recruiter's latest hiring activity date and role tags. Slower and charged as a job detail instead of a job listing.

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

Maximum number of jobs to save, counted after filters.

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

Proxy settings. The default Apify Proxy works well.

## Actor input object example

```json
{
  "skills": [
    "Python"
  ],
  "city": "",
  "remoteOnly": false,
  "includeDetails": false,
  "maxItems": 50,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

No description

## `summary` (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 = {
    "skills": [
        "Python"
    ],
    "maxItems": 50,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("piotrv1001/cutshort-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 = {
    "skills": ["Python"],
    "maxItems": 50,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("piotrv1001/cutshort-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 '{
  "skills": [
    "Python"
  ],
  "maxItems": 50,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call piotrv1001/cutshort-jobs-scraper --silent --output-dataset

```

## MCP server setup

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