# Coursera Course & Specialization Catalog Scraper (`nimbryxo-studio/coursera-course-and-specialization-catalog-scraper`) Actor

Search Coursera's course and specialization catalog by keyword, difficulty or partner university, with rating, learner count, enrollment type and course links.

- **URL**: https://apify.com/nimbryxo-studio/coursera-course-and-specialization-catalog-scraper.md
- **Developed by:** [Nimbryxo-studio](https://apify.com/nimbryxo-studio) (community)
- **Categories:** AI, Jobs, Other
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.49 / 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/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

## Coursera Course & Specialization Catalog Scraper

Coursera publishes tens of thousands of learning products: individual courses, multi-course
specializations, professional certificates, guided projects, degrees and shorter credentials. This
actor turns that public catalog into structured records you can filter, compare and export. Give it
a keyword, a category, a university, a slug or a URL, and it returns the matching products with
ratings, skills, providers, level, duration, language coverage, access flags and direct links.

Optional detail enrichment adds the parts that only exist on each product page: instructors,
module-by-module syllabus, lecture durations, total enrollment, monthly page views, star
distribution, top reviews, learning objectives and recommended background.

### What this actor does

- Keyword search across every Coursera learning product type
- Category (topic) browse and partner/university browse
- Slug, URL and product-ID lookups
- All 10 live product types: courses, specializations, guided projects, projects, professional
  certificates, degrees, graduate certificates, MasterTrack certificates, university certificates
  and postgraduate diplomas
- Filters for level, duration band, cost label, topic, content language, subtitle language,
  hands-on learning format, tool/software, partner, skill and Coursera Plus inclusion
- Best-match and newest ordering
- Optional instructor, syllabus, enrollment, page-view, rating-breakdown and review fields
- Search rank and page metadata so repeated runs can be compared

### Modes

| Mode | Required input | What it does |
|---|---|---|
| `search` | `query` | Keyword search with every filter |
| `byCategory` | `topics` | Browse one or more subject areas; query is optional |
| `byPartner` | `partners` | Browse a university or company; query is optional |
| `bySlug` | `slugs` | Look up products by slug (a full URL also works) |
| `byUrl` | `startUrls` | Product URLs return one detail record; search or `/courses?query=` URLs become catalog queries |
| `byIds` | `productIds` | Look up `course~...` and `s12n~...` product IDs |
| `browse` | none | Top products with filters and no keyword |
| `searchSpecializations` | `query` | Legacy alias for a search limited to specializations and professional certificates |

Lookup modes (`bySlug`, `byUrl`, `byIds`) always return detail fields. Search modes return detail
fields only when `includeDetails` is true.

### Input

| Field | Type | Default | Notes |
|---|---|---|---|
| `mode` | dropdown | `search` | One of the eight modes above |
| `query` | text | empty | Required for `search` and `searchSpecializations`; optional narrowing for `byCategory` and `byPartner` |
| `startUrls` | URL list | empty | Product, search or `/courses?query=` URLs |
| `slugs` | text list | empty | Slugs such as `machine-learning`; full URLs accepted |
| `productIds` | text list | empty | `course~...`, `s12n~...`, or a bare course ID |
| `productTypes` | multi-select | all | 10 product types |
| `difficulties` | multi-select | all | Beginner, Intermediate, Advanced, Mixed |
| `durations` | multi-select | all | Less than 2 hours through 1-4 years |
| `costs` | multi-select | all | Free, Free Trial, Paid, Preview |
| `topics` | multi-select | all | 11 Coursera subject areas |
| `languages` | multi-select | all | 67 content languages |
| `subtitleLanguages` | multi-select | all | 67 subtitle languages |
| `handsOnLearningTypes` | multi-select | all | Dialogues, guided projects, coding labs, cloud sandboxes, Gen AI playgrounds |
| `tools` | multi-select | all | 10 tool/software values |
| `partners` | text list | empty | Names are matched to the live partner filter; partial names resolve when possible |
| `skills` | text list | empty | Matched to the live skill filter |
| `courseraPlusStatus` | dropdown | any | Included or not included in Coursera Plus |
| `freeOnly` | boolean | false | Adds the Free cost filter |
| `sortBy` | dropdown | Best match | Best match or Newest |
| `maxItems` | integer | 50 | 1-1000 |
| `includeDetails` | boolean | false | Adds one product-page request per record |

Every filter is applied by Coursera's own catalog search. The actor does not post-filter a fixed
page, so broad filters are not silently narrowed by a hidden default.

### Examples

#### Beginner machine learning courses, full detail

```json
{
  "mode": "search",
  "query": "machine learning",
  "productTypes": ["COURSE"],
  "difficulties": ["BEGINNER"],
  "maxItems": 25,
  "includeDetails": true
}
```

#### Spanish data-science specializations from a partner

```json
{
  "mode": "byPartner",
  "partners": ["IBM"],
  "topics": ["Data Science"],
  "languages": ["Spanish"],
  "productTypes": ["SPECIALIZATION"],
  "maxItems": 20
}
```

#### Look up a course by its URL

```json
{
  "mode": "byUrl",
  "startUrls": [
    {"url": "https://www.coursera.org/learn/machine-learning"}
  ]
}
```

#### Look up several products by ID

```json
{
  "mode": "byIds",
  "productIds": [
    "course~8UjeMk-mEeit4g4GsxE4dg",
    "s12n~nOOfCDWeEeuiZgo2K4rorQ"
  ]
}
```

#### Browse free courses with subtitles in Spanish

```json
{
  "mode": "browse",
  "productTypes": ["COURSE"],
  "costs": ["Free"],
  "subtitleLanguages": ["Spanish"],
  "maxItems": 30
}
```

### Output per product

Every record carries `recordType`, `productType`, `productTypeLabel`, `productId`, `slug`, `name`,
`siteName`, `sourceUrl`, `productUrl` and `scrapedAt`. Course records also keep the familiar
`courseId`, `courseUrl` and `photoUrl` fields; specialization records keep `specializationId`,
`specializationUrl`, `logoUrl`, `courseIds` and `numCourses`.

List-level fields:

`tagline`, `description`, `partnerName`, `partnerNames`, `partnerIds`, `partnerLogos`, `avgRating`,
`numRatings`, `reviewCount`, `difficultyLevel`, `duration`, `durationLabel`, `skills`, `tools`,
`handsOnLearningTypes`, `isCourseFree`, `isCreditEligible`, `isNewContent`,
`isPartOfCourseraPlus`, `enrollmentType`, `badges`, `fullyTranslatedLanguages`,
`subtitlesOnlyLanguages`, `primaryLanguageCodes`, `subtitleLanguageCodes`, `workload`,
`certificates`, `topics`, `subtopics`, `topicIds`, `subtopicIds`, `courseType`, `searchQuery`,
`searchRank`, `page`, `totalResults`.

Detail fields (`includeDetails` or a lookup mode):

`instructors`, `modules`, `totalDuration`, `totalDurationSeconds`, `totalEnrollmentCount`,
`learnerCount`, `pageViewsLastMonth`, `contentSatisfactionScore`,
`contentSatisfactionRatingsCount`, `averageInstructorRating`, `instructorRatingCount`,
`ratingCountsByStar`, `topReviews`, `learningObjectives`, `recommendedBackground`,
`specializations` (course membership), `courses` (specialization membership), `numAssignments`,
`learningHoursPerWeek`, `totalLearningMonths`, `careerOutcomes`, `projectsOverview`,
`professionalCertificateType`, `headline`, `subheader`, `courseStatus`, `launchedAt`.

A `module` contains its week number, title, description, lecture count, total duration in seconds
and a `lectures` array with title, type, ISO duration and duration in seconds. A `topReview`
contains author, rating, date and text. Empty fields are omitted at every depth; booleans are kept
even when false.

### Data source and reliability

The actor reads Coursera's public catalog through the same endpoints the public website uses:

- The catalog search endpoint at `https://www.coursera.org/graphql-gateway?opname=Search` for
  keyword search, facets, sorting and pagination.
- Public batch endpoints (`courses.v1`, `onDemandSpecializations.v1`) for description, workload,
  certificates, languages and subject areas.
- Public product pages for the optional detail fields.

No account, cookie, API key or proxy setup is needed. Results are deduplicated by product ID. The
actor retries transient HTTP errors with exponential backoff and, if a cloud exit is ever blocked,
falls back to an Apify datacenter proxy automatically. Runs stop on the requested item count, the
end of the source or an exhausted result window; there is no wall-clock cut.

### Use cases

- **Curriculum research** - map which universities and companies teach a subject and at what level
- **Competitive analysis** - compare ratings, enrollment signals, duration and skills across course providers
- **Learning and development** - build internal training shortlists filtered by topic, language and difficulty
- **Edtech market intelligence** - track new specializations, professional certificates and guided projects
- **Academic research** - export a reproducible catalog slice with search rank and page metadata

### FAQ

**Do I need a Coursera account?** No. Every request is cookieless and unauthenticated.

**How many records can one run return?** Up to 1,000. Coursera's own search window is 10,000
products; the actor never needs more than 1,000 for a run and partitions by filters when you need
different slices of a large topic.

**Why do some records lack a rating or review count?** Coursera does not publish ratings for every
new or low-traffic product. The field is omitted rather than filled with zero.

**Why is `enrollmentType` shown as AUDIT or VERIFIED?** Coursera's current public catalog no longer
exposes the old enrollment-form value. The actor keeps the historic values meaningful by deriving
them from `isCourseFree` (free products become AUDIT, others VERIFIED). The authoritative access
signals are `isCourseFree`, `isPartOfCourseraPlus` and `isCreditEligible`.

**What does `includeDetails` cost?** One extra product-page request per record. It is the only
setting that adds per-record requests; leave it off for fast catalog exports.

**Can I get exact prices or discounts?** No. Coursera does not publish a stable price in the public
catalog payload; it depends on region, session and promotions. Free/paid/trial/preview labels and
Coursera Plus inclusion are available.

**Can I get every review for a course?** The product page exposes a curated set of top reviews
(typically 12-20). Bulk review export is outside this catalog actor's scope.

**Do degree and certificate pages have the same detail fields?** Degrees and graduate certificates
use a different Coursera page template with sparse public metadata. They are returned from the
search catalog with list-level fields; course, project, specialization and professional-certificate
pages have the full detail set.

**Why did a slug or ID return nothing?** Some legacy products are retired or moved. Try the
product URL in `byUrl`, or use a search query to find the current slug. Unsupported ID prefixes are
reported in the run log.

**A slug exists as both a course and a guided project. Which one is returned?** A bare slug is
ambiguous; `bySlug` follows the first catalog hit. Use `byUrl` with the full product URL when you
need a specific product type.

**Is this affiliated with Coursera?** No. This is an independent, third-party actor that reads
public catalog data. It is not operated by or affiliated with Coursera, Inc.

### Limitations

- Coursera's search index returns at most 10,000 products per query. The actor caps runs at 1,000
  records; use filters (product type, topic, level, duration, language, partner) to cover a large
  topic in several runs.
- Exact price and discount data are not part of the public catalog payload.
- Bulk/all reviews are not available from the catalog page; only the page's top reviews are
  returned.
- Degree and graduate-certificate detail pages expose a different, sparse schema; those product
  types are list-level only.
- One legacy professional certificate was missing from the public batch endpoint during research;
  the actor falls back to the product page for such IDs and reports a shortfall in the status
  message if the page is also gone.

### Responsible use

Use the actor for lawful catalog research and export. Respect Coursera's terms, copyright and
privacy rules, and do not republish course content. The actor collects public catalog metadata and
top review excerpts, not learner records or paid course materials.

# Actor input Schema

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

What to fetch. `bySlug`, `byUrl` and `byIds` always return detail fields for the looked-up products.

## `query` (type: `string`):

Keyword search (mode=search, searchSpecializations). Optional narrowing keyword for byCategory and byPartner.

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

Course, specialization, professional certificate, guided project, degree or certificate page, or a Coursera search / courses URL. Search URLs are converted into catalog filters.

## `slugs` (type: `array`):

Course or specialization slugs, e.g. `machine-learning`. A full Coursera URL is also accepted.

## `productIds` (type: `array`):

Coursera product IDs such as `course~8UjeMk-mEeit4g4GsxE4dg` or `s12n~nOOfCDWeEeuiZgo2K4rorQ`. Bare course IDs are also accepted.

## `productTypes` (type: `array`):

Limit results to these Coursera product types. Leave empty for every type.

## `difficulties` (type: `array`):

Only include products at these difficulty levels.

## `durations` (type: `array`):

Only include products in these duration bands.

## `costs` (type: `array`):

Only include products with these cost labels.

## `topics` (type: `array`):

Only include products in these subject areas (mode=byCategory requires at least one).

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

Only include products available in these content languages.

## `subtitleLanguages` (type: `array`):

Only include products with subtitles in these languages.

## `handsOnLearningTypes` (type: `array`):

Only include products with these hands-on learning formats.

## `tools` (type: `array`):

Only include products that teach these tools or software skills.

## `partners` (type: `array`):

Partner or university names, e.g. `IBM`, `Google`, `Stanford Online`, `DeepLearning.AI`. Matched to the live Coursera partner filter; partial names such as `Stanford` are resolved to the closest partner.

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

Skill names, e.g. `Python Programming`, `Machine Learning`. Matched to the live skill filter; partial names are resolved when possible.

## `courseraPlusStatus` (type: `string`):

Filter by Coursera Plus inclusion.

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

Only return products whose Coursera cost label is Free. The older audit/verified filter is no longer exposed by Coursera; access flags are included in every record.

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

Result order for search, browse, byCategory and byPartner modes.

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

Maximum number of records to return (1-1000).

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

Fetch each product page to add instructors, syllabus/modules, total enrollment, page views, rating breakdown, top reviews, learning objectives, recommended background and membership. Slower: one extra request per record. Lookup modes (bySlug/byUrl/byIds) always return detail fields.

## Actor input object example

```json
{
  "mode": "search",
  "query": "machine learning",
  "startUrls": [],
  "slugs": [],
  "productIds": [],
  "productTypes": [
    "COURSE"
  ],
  "difficulties": [],
  "durations": [],
  "costs": [],
  "topics": [],
  "languages": [],
  "subtitleLanguages": [],
  "handsOnLearningTypes": [],
  "tools": [],
  "partners": [],
  "skills": [],
  "courseraPlusStatus": "",
  "freeOnly": false,
  "sortBy": "BEST_MATCH",
  "maxItems": 3,
  "includeDetails": false
}
```

# Actor output Schema

## `records` (type: `string`):

Dataset containing the scraped Coursera courses, specializations and other learning products.

# 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",
    "query": "machine learning",
    "startUrls": [],
    "slugs": [],
    "productIds": [],
    "productTypes": [
        "COURSE"
    ],
    "difficulties": [],
    "durations": [],
    "costs": [],
    "topics": [],
    "languages": [],
    "subtitleLanguages": [],
    "handsOnLearningTypes": [],
    "tools": [],
    "partners": [],
    "skills": [],
    "courseraPlusStatus": "",
    "freeOnly": false,
    "sortBy": "BEST_MATCH",
    "maxItems": 3,
    "includeDetails": false
};

// Run the Actor and wait for it to finish
const run = await client.actor("nimbryxo-studio/coursera-course-and-specialization-catalog-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",
    "query": "machine learning",
    "startUrls": [],
    "slugs": [],
    "productIds": [],
    "productTypes": ["COURSE"],
    "difficulties": [],
    "durations": [],
    "costs": [],
    "topics": [],
    "languages": [],
    "subtitleLanguages": [],
    "handsOnLearningTypes": [],
    "tools": [],
    "partners": [],
    "skills": [],
    "courseraPlusStatus": "",
    "freeOnly": False,
    "sortBy": "BEST_MATCH",
    "maxItems": 3,
    "includeDetails": False,
}

# Run the Actor and wait for it to finish
run = client.actor("nimbryxo-studio/coursera-course-and-specialization-catalog-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",
  "query": "machine learning",
  "startUrls": [],
  "slugs": [],
  "productIds": [],
  "productTypes": [
    "COURSE"
  ],
  "difficulties": [],
  "durations": [],
  "costs": [],
  "topics": [],
  "languages": [],
  "subtitleLanguages": [],
  "handsOnLearningTypes": [],
  "tools": [],
  "partners": [],
  "skills": [],
  "courseraPlusStatus": "",
  "freeOnly": false,
  "sortBy": "BEST_MATCH",
  "maxItems": 3,
  "includeDetails": false
}' |
apify call nimbryxo-studio/coursera-course-and-specialization-catalog-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nimbryxo-studio/coursera-course-and-specialization-catalog-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/z5wasRpKZDqZTdNyM/builds/2Tpf5PUHl0dObidV5/openapi.json
