# CutShort Jobs Scraper (`seemuapps/cutshort-jobs-scraper`) Actor

Scrape CutShort.io India tech and startup jobs with salary bands, skills, experience, full description, recruiter and funding stage.

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

## Pricing

$3.00 / 1,000 job listing 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

## CutShort Jobs Scraper

Extract India tech and startup job listings from CutShort.io — title, both salary bands (the displayed range **and** the hidden internal floor), skills, experience range, full description, recruiter name, remote type and company funding stage. Paste listing or job URLs, or search by skill + city. No login required.

### What you get

Every job comes out as one dataset row with:

- **Job**: `jobId`, `title`, `url`, `postedAt`, `roleTypes` (full time / internship), `remoteType` (`remote_only`, `remote_okay`, `remote_not_okay`)
- **Salary**: `salaryText` as shown on the site, plus numeric `salaryMin` / `salaryMax` (displayed band), `salaryFloorInternal` (hidden internal floor — see below), `salaryHidden` (true when the site shows "Best in industry" but a numeric band still exists), `currency`
- **Requirements**: `experienceMin` / `experienceMax` in years, `skills[]`
- **Description**: `description` as clean plain text and `descriptionHtml` as the original markup
- **Company**: `company`, `companyUrl`, `companyType` (Product / Services), `companySize`, `fundingStage` (Bootstrapped / Raised funding / Profitable), `companyFounded`, `companyWebsite`, `companyLinkedin`, `companyLogo`
- **Recruiter**: `recruiterName` (the person who posted the job), `postedByCompany` and `hiringForClient` (true when an agency posts on behalf of the `company`)
- **Location**: `locations[]` and `locationsText`
- **Extras with "Fetch job pages" on**: `lastActiveAt` (when the recruiter last confirmed the role is open) and `validThrough`

Export the dataset to JSON, CSV, Excel or Google Sheets straight from the Apify console.

### What "hidden salary floor" means

CutShort stores two lower bounds for every salary band. The one shown on the page (`salaryMin`) is the "vanity" figure; the one actually used for matching candidates (`salaryFloorInternal`) is often lower — frequently ₹0, meaning the company will consider candidates below the advertised minimum. Roughly 1 in 10 listings also hides the band entirely ("Best in industry"); those rows come out with `salaryHidden: true` and the numeric band still filled in.

### Use cases

- Salary benchmarking — compare advertised vs. internal salary floors by skill, city and funding stage
- Recruiter and agency lead generation — `recruiterName`, `postedByCompany` and `companyLinkedin` for every posting
- Startup market research — track which funded, bootstrapped or profitable companies are hiring for which stacks
- Job-alert automation — run on a schedule and diff `jobId` against your previous dataset
- Competitive hiring intelligence — monitor a competitor's listing page or the remote page for your stack

### How to use

You can drive the scraper with URLs, with keywords, or both.

**Option A — Start URLs**

1. Paste one or more CutShort URLs into **Start URLs**:
   - a listing page such as `https://cutshort.io/jobs/reactjs-jobs-in-bangalore-bengaluru` or `https://cutshort.io/jobs/remote-python-jobs` — the scraper walks every page of it (50 jobs per page)
   - an individual job page such as `https://cutshort.io/job/FullStack-Tech-Lead-Bengaluru-Bangalore-...`
2. Set **Max items** (default 200; 0 = unlimited) and run.

**Option B — Skills / roles + City**

1. Enter keywords in **Skills / roles**, e.g. `react`, `python`, `data science`, `devops`, `product manager`, `ui ux`
2. Optionally enter a **City** — Bangalore, Mumbai, Delhi NCR / Gurgaon / Noida, Hyderabad, Pune, Chennai, Kolkata, Ahmedabad, Jaipur, Kochi, Coimbatore, Indore, Chandigarh or Bhubaneswar have dedicated pages
3. Optionally tick **Remote-friendly only** or set a **Minimum salary** in INR lakhs per year
4. Run — results appear in the **Dataset** tab

Pasted job URLs are always scraped first, so they are never squeezed out by **Max items**.

#### The fixed-page limitation (please read)

CutShort does not offer public free-text search. What it publishes is a fixed catalogue of about 3,700 role / skill pages, each optionally combined with one of 14 cities or a "remote" prefix. This scraper downloads that catalogue at the start of every run and maps each keyword to the closest page — `react` → `reactjs-jobs`, `data scientist` → `datascience-jobs`, `qa` → `qa-software-testing-jobs`, and so on. The run log shows exactly which page each keyword resolved to.

Consequences:

- A very specific phrase ("senior staff platform engineer fintech") will be matched to the nearest generic page, not searched literally.
- Cities outside the 14 above fall back to the all-India page for that skill, filtered by location text (fully remote jobs are kept, since they are open to that city too).
- Filters (**Remote-friendly only**, **Minimum salary**) are applied to the jobs on those pages, so a strict filter can return fewer rows than **Max items**.

If a keyword resolves to the wrong page, paste the listing URL you want directly into **Start URLs** instead.

### Output format

Each dataset record:

```json
{
  "jobId": "6a96814a4d5d592b26935e3d",
  "title": "FullStack Tech Lead",
  "url": "https://cutshort.io/job/FullStack-Tech-Lead-Bengaluru-Bangalore-GOSUPER-EDTECH-enMigpyj",
  "company": "GOSUPER EDTECH",
  "companyUrl": "https://cutshort.io/company/jobs-at-gosuper-edtech-45-TBZSiFNp",
  "companyType": "Product",
  "companySize": "0-20",
  "fundingStage": "Bootstrapped",
  "companyFounded": 2023,
  "companyWebsite": "https://gosuperedtech.com",
  "companyLinkedin": "https://linkedin.com/company/gosuperedtech",
  "companyLogo": "https://cdnv2.cutshort.io/company-static/.../company_logo.png",
  "hiringForClient": false,
  "postedByCompany": "GOSUPER EDTECH",
  "locations": ["Bengaluru (Bangalore)"],
  "locationsText": "Bengaluru (Bangalore)",
  "remoteType": "remote_not_okay",
  "roleTypes": ["full_time"],
  "salaryText": "₹8L - ₹12L / yr",
  "currency": "INR",
  "salaryMin": 800000,
  "salaryMax": 1200000,
  "salaryFloorInternal": 0,
  "salaryMaxInternal": 1200000,
  "salaryHidden": false,
  "experienceMin": 3,
  "experienceMax": 5,
  "skills": ["React.js", "Generative AI", "Agile/Scrum", "Google Cloud Platform (GCP)", "NodeJS (Node.js)", "SQL"],
  "description": "Role Overview\nAs a Senior Fullstack Developer at GoSuper, you'll help build and ship features across both web and mobile platforms. …",
  "descriptionHtml": "<p><strong>Role Overview</strong></p><p>As a Senior Fullstack Developer …</p>",
  "recruiterName": "Vanitha F",
  "postedAt": "2026-09-01T07:39:54.000Z",
  "lastActiveAt": "2026-09-04T06:17:39.878Z",
  "validThrough": "2026-12-03T06:21:49.423Z",
  "sourceSlug": "reactjs-jobs-in-bangalore-bengaluru",
  "scrapedAt": "2026-09-06T03:25:17.769Z"
}
```

Salary figures are absolute annual amounts in `currency` (₹800000 = ₹8 LPA). `sourceSlug` tells you which listing page a job came from; it is `null` for jobs scraped from a pasted job URL. Jobs scraped from a pasted job URL carry the displayed salary band only — `salaryFloorInternal` is exposed exclusively on listing pages.

### Pricing

Pay per result — you are charged once for every job row written to the dataset. Rows dropped by your filters cost nothing.

# Actor input Schema

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

CutShort listing pages (https://cutshort.io/jobs/reactjs-jobs-in-bangalore-bengaluru) and/or individual job pages (https://cutshort.io/job/...). Listing pages are paginated automatically. Leave empty to search by skill / role instead.

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

Skill or role keywords, e.g. 'react', 'python', 'data science', 'devops', 'product manager'. Each keyword is matched to the closest CutShort listing page (the site only publishes a fixed set of role pages, not free-text search).

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

Optional city, e.g. 'Bangalore', 'Mumbai', 'Delhi NCR', 'Hyderabad', 'Pune', 'Chennai'. Applied to the Skills / roles search; cities without a dedicated page fall back to the all-India page filtered by location text.

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

Keep only jobs marked remote or remote-okay; drop on-site-only jobs.

## `minSalary` (type: `integer`):

Keep only INR jobs whose displayed salary range reaches at least this many lakhs per year (e.g. 12 = ₹12 LPA). Jobs without a numeric salary or in another currency are dropped when this is set. 0 = no filter.

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

Maximum number of jobs to return in this run across all listing pages and job URLs. 0 = unlimited.

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

Listing pages already include the full description and salary bands. Enable this to also open every job page (5 at a time) for lastActiveAt and validThrough dates.

## Actor input object example

```json
{
  "startUrls": [
    "https://cutshort.io/jobs/reactjs-jobs-in-bangalore-bengaluru"
  ],
  "skills": [
    "react"
  ],
  "city": "Bangalore",
  "remoteOnly": false,
  "minSalary": 0,
  "maxItems": 200,
  "fetchDetails": false
}
```

# Actor output Schema

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

One job listing per record with salary bands, skills, experience, full description, recruiter, remote type and company funding stage.

# 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 = {
    "startUrls": [
        "https://cutshort.io/jobs/reactjs-jobs-in-bangalore-bengaluru"
    ],
    "skills": [
        "react"
    ],
    "city": "Bangalore"
};

// Run the Actor and wait for it to finish
const run = await client.actor("seemuapps/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 = {
    "startUrls": ["https://cutshort.io/jobs/reactjs-jobs-in-bangalore-bengaluru"],
    "skills": ["react"],
    "city": "Bangalore",
}

# Run the Actor and wait for it to finish
run = client.actor("seemuapps/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 '{
  "startUrls": [
    "https://cutshort.io/jobs/reactjs-jobs-in-bangalore-bengaluru"
  ],
  "skills": [
    "react"
  ],
  "city": "Bangalore"
}' |
apify call seemuapps/cutshort-jobs-scraper --silent --output-dataset

```

## MCP server setup

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