# NCS (India) Vocational Training Courses Scraper (`crawlerbros/ncs-vocational-training-scraper`) Actor

Scrape India's National Career Service (NCS) / Skill India Digital Hub vocational and skilling course catalog. Search by keyword, sector, language, occupation, and program sponsor. Get full course descriptions, duration, price, certification, and enrollment stats.

- **URL**: https://apify.com/crawlerbros/ncs-vocational-training-scraper.md
- **Developed by:** [Crawler Bros](https://apify.com/crawlerbros) (community)
- **Categories:** Jobs, Automation, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#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

## NCS (India) Vocational Training Courses Scraper

Scrape India's [National Career Service (NCS)](https://www.ncs.gov.in) / [Skill India Digital Hub](https://betacloud.ncs.gov.in) vocational and skilling course catalog — the Government of India's official skilling platform run with the National Skill Development Corporation (NSDC). Search by keyword, industry sector, language, occupation, and program sponsor. Get full course descriptions, learning outcomes, NSQF level, duration, price, certification details, and enrollment stats. No auth, no proxy, no cookies required.

### What this actor does

- **Two modes:** `search` (keyword/sector/language/occupation/price filters) and `byIds` (exact course ID lookup)
- **59 industry sectors** — from Healthcare to IT-ITeS to Agriculture to Handicrafts
- **9 languages** — English, Hindi, Bengali, Gujarati, Kannada, Malayalam, Tamil, Telugu, Urdu
- **Rich filters:** occupation, domain, program sponsor (Govt. of India / NSDC Academy / State Govt. / CSR / etc.), learning-partner type, price range, free-only
- **Optional image rehosting:** the upstream course-image URL is a short-lived signed link; enable `includeCourseImage` to get a stable, permanently-accessible copy
- **Empty fields are omitted**

### Output per course

- `id`, `code`, `readableCode` — Skill India Digital Hub identifiers
- `title`, `shortDescription`, `longDescription`, `learningOutcome`
- `language`, `courseCategory` (Skill Course / Learning Path / Specialization / Professional Certification / Diploma / Degree / K-12 Course), `learningPartnerType`
- `programBy`, `programs[]`, `initiativeOfs[]`
- `domains[]`, `occupations[]` — taxonomy tags
- `sectorIds[]`, `sectorNames[]` — resolved from the sector master list
- `nsqfLevel` — National Skills Qualification Framework level
- `nosCodes[]`, `qpCodes[]` — National Occupational Standard / Qualification Pack codes
- `tags[]`
- `durationMinutes`, `durationUnit`, `durationDescription`
- `price`, `isFree`, `pendingAmount`, `credit`
- `certificateEnabled`, `certificateType`
- `eligibilityCriteria[]` — enrollment requirements as `{criterion, value}` pairs, e.g. `{"criterion": "Educational Qualification", "value": "10th Pass"}`, `{"criterion": "Age Requirement", "value": "Above 18"}`
- `enrollmentCount`, `ratingAverage`, `ratingTotal`
- `isCapstoneProject` — whether the course includes a hands-on capstone project
- `learnerIdentifier` — how learners are identified for enrollment (e.g. `MOBILE`, `EMAIL`)
- `hasExternalPayment` — set when the course routes payment through an external processor
- `createdBy`, `createdDate`, `updatedDate`, `startDate`, `endDate`
- `courseUrl` / `sourceUrl` — canonical course detail page
- `courseImageUrl` — stable rehosted cover image (only when `includeCourseImage: true`)
- `recordType: "vocationalCourse"`, `scrapedAt`

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | string | `search` | `search` or `byIds` |
| `keyword` | string | `cyber` | Free-text search on title/description (matches exact substrings, not tokenized words) |
| `courseIds` | array | – | Exact course UUIDs (mode=byIds) |
| `sectors` | array | – | Industry sector filter (multi-select, matches any) |
| `languages` | array | – | Course language filter (multi-select, matches any) |
| `occupation` | string | – | Case-insensitive substring match on occupation tags |
| `domain` | string | – | Case-insensitive substring match on domain tags (270+ values, finer-grained than sector) |
| `programBy` | select | – | Program sponsor |
| `learningPartnerType` | select | – | Learning partner category |
| `courseCategory` | select | – | Learning-product type — Skill Course / Learning Path / Specialization / Professional Certification / Diploma / Degree / K-12 Course |
| `nsqfLevel` | select | – | National Skills Qualification Framework level (0–10) |
| `freeOnly` | bool | `false` | Only price = 0 courses |
| `minPrice` / `maxPrice` | int | – | Price range in INR |
| `includeCourseImage` | bool | `false` | Rehost course cover image to a stable URL |
| `maxItems` | int | `50` | Hard cap (1–500) |

#### Example: free cybersecurity courses in Hindi

```json
{
  "mode": "search",
  "keyword": "cyber",
  "languages": ["Hindi"],
  "freeOnly": true
}
```

#### Example: Healthcare-sector courses sponsored by NSDC Academy

```json
{
  "mode": "search",
  "sectors": ["35"],
  "programBy": "NSDC Academy",
  "maxItems": 100
}
```

#### Example: lookup specific course IDs

```json
{
  "mode": "byIds",
  "courseIds": ["20b0db73-4f3b-4738-bdb1-f681b2fdfee1"]
}
```

### Use cases

- **Career counseling platforms** — surface government-backed skilling courses by sector/language
- **Skill-gap research** — analyze the national vocational-training catalog by occupation and NSQF level
- **Education aggregators** — build a searchable index of free/low-cost government skilling programs
- **Policy analysis** — track program-sponsor distribution (Govt. of India vs State vs CSR) across sectors
- **Multilingual access initiatives** — find courses available in a learner's preferred Indian language

### Limitations

- The upstream catalog currently totals roughly 150 published courses; `maxItems` above that will simply return everything available.
- `occupation`, `domain`, `programBy`, `learningPartnerType`, `courseCategory`, `nsqfLevel`, `freeOnly`, and price filters are applied client-side on top of the server-side `keyword`/`sectors`/`languages` search. The upstream API silently ignores a `domain` request parameter (confirmed live: identical result counts for a real domain, an unrelated domain, and a bogus string), and does not support `occupation`/`programBy`/etc. as native filters either — client-side filtering is more reliable than guessing at undocumented server parameter names.
- General NCS job-listing search (as opposed to vocational-training courses) is out of scope for this actor.

### FAQ

**What's the Skill India Digital Hub?** The Government of India's unified platform (built with NSDC) for discovering NSQF-aligned vocational training and skilling courses, most run by the Ministry of Skill Development & Entrepreneurship, State Governments, or NSDC Academy partners.

**Why is `courseImageUrl` sometimes missing?** By default the actor doesn't fetch cover images (faster runs). The upstream image link is a short-lived signed AWS S3 URL that expires within minutes of being issued, so the actor never emits it directly — set `includeCourseImage: true` to have the actor download and rehost the image to a permanent Apify-hosted URL instead.

**What does NSQF level mean?** The National Skills Qualifications Framework level (1–10) indicating the competency/complexity tier of the qualification, roughly comparable to other countries' national qualification frameworks.

**Is proxy or login required?** No. The actor calls the same public backend API the Skill India Digital Hub website itself uses for its course catalog.

**How fresh is the data?** Real-time — every run queries the live catalog API directly.

# Actor input Schema

## `mode` (type: `string`):

What to fetch.

## `keyword` (type: `string`):

Free-text search against course title and description (mode=search). The upstream API matches on exact substrings, not tokenized words — e.g. `cyber` matches "Cybersecurity", but `cyber security` (with a space) will not.

## `courseIds` (type: `array`):

Exact Skill India Digital Hub course UUIDs to look up.

## `sectors` (type: `array`):

Filter by one or more industry sectors (matches any).

## `languages` (type: `array`):

Filter by one or more course languages (matches any).

## `occupation` (type: `string`):

Case-insensitive substring match against the course's occupation tags (e.g. `Cyber Security`, `Data Analytics`, `Cooking`).

## `domain` (type: `string`):

Case-insensitive substring match against the course's domain tags (e.g. `Plumbing Contractor`, `Plastic Manufacturing`, `Future Skills`) — a finer-grained taxonomy than Sector, with 270+ upstream values. Applied client-side; the upstream API silently ignores a server-side `domain` filter.

## `programBy` (type: `string`):

Filter by who runs the program.

## `learningPartnerType` (type: `string`):

Filter by the category of learning partner delivering the course.

## `courseCategory` (type: `string`):

Filter by learning-product type, e.g. a short Skill Course vs. a multi-term Degree.

## `nsqfLevel` (type: `string`):

Filter by National Skills Qualification Framework level (0 = not applicable/unrated, 1-10 = increasing skill/qualification depth).

## `freeOnly` (type: `boolean`):

Only keep courses with price = 0.

## `minPrice` (type: `integer`):

Drop courses cheaper than this (in INR).

## `maxPrice` (type: `integer`):

Drop courses more expensive than this (in INR).

## `includeCourseImage` (type: `boolean`):

Fetch each course's cover image and rehost it to a stable Apify-hosted URL (the upstream image URL is a short-lived signed link that expires within minutes). Slower (1 extra request per record).

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

Hard cap on emitted records.

## Actor input object example

```json
{
  "mode": "search",
  "keyword": "cyber",
  "courseIds": [],
  "sectors": [],
  "languages": [],
  "occupation": "",
  "domain": "",
  "programBy": "",
  "learningPartnerType": "",
  "courseCategory": "",
  "nsqfLevel": "",
  "freeOnly": false,
  "minPrice": 0,
  "includeCourseImage": false,
  "maxItems": 50
}
```

# Actor output Schema

## `courses` (type: `string`):

Dataset containing all scraped NCS / Skill India Digital Hub courses.

# 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 = {
    "mode": "search",
    "keyword": "cyber",
    "courseIds": [],
    "sectors": [],
    "languages": [],
    "occupation": "",
    "domain": "",
    "programBy": "",
    "learningPartnerType": "",
    "courseCategory": "",
    "nsqfLevel": "",
    "freeOnly": false,
    "minPrice": 0,
    "includeCourseImage": false,
    "maxItems": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawlerbros/ncs-vocational-training-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 = {
    "mode": "search",
    "keyword": "cyber",
    "courseIds": [],
    "sectors": [],
    "languages": [],
    "occupation": "",
    "domain": "",
    "programBy": "",
    "learningPartnerType": "",
    "courseCategory": "",
    "nsqfLevel": "",
    "freeOnly": False,
    "minPrice": 0,
    "includeCourseImage": False,
    "maxItems": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("crawlerbros/ncs-vocational-training-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 '{
  "mode": "search",
  "keyword": "cyber",
  "courseIds": [],
  "sectors": [],
  "languages": [],
  "occupation": "",
  "domain": "",
  "programBy": "",
  "learningPartnerType": "",
  "courseCategory": "",
  "nsqfLevel": "",
  "freeOnly": false,
  "minPrice": 0,
  "includeCourseImage": false,
  "maxItems": 50
}' |
apify call crawlerbros/ncs-vocational-training-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,crawlerbros/ncs-vocational-training-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/e6Juwm7KBFe9iGGiu/builds/P1fif4zVhofl2IDFA/openapi.json
