# Scholarship Scraper (bold.org) (`fetchsmith/scholarship-scraper`) Actor

Scrape scholarship listings from bold.org to JSON/CSV: award amount, number of awards, deadline, essay prompt, criteria, education level and applicant count, with a computed applicants-per-award ratio. ~28 typed fields. Filter by free-text topic, amount, deadline window and education level.

- **URL**: https://apify.com/fetchsmith/scholarship-scraper.md
- **Developed by:** [Fetch Smith](https://apify.com/fetchsmith) (community)
- **Categories:** Education, Other, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.50 / 1,000 result items

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

## Scholarship Scraper (bold.org)

Scrape **scholarship listings from bold.org** — the largest single scholarship platform — into JSON, CSV or Excel. No login, no browser, no proxy.

Every row is a complete scholarship: award amount, number of awards, deadline, essay prompt, judging criteria, education levels, donor, and the **number of people who have already applied** — plus a computed `applicantsPerAward` ratio so you can see at a glance which awards are actually winnable.

**Pay per result: $0.0005 per scholarship. No start fee** — a run that returns nothing costs nothing, and scholarships removed by your filters are never charged.

### What you can do with it

- **Build a scholarship feed for a school, newsletter or app** — crawl `by-major`, `by-state`, `by-type` and `by-demographics` categories and get a de-duplicated list.
- **Find the winnable ones** — sort your dataset by `applicantsPerAward`; a $1,000 award with 40 applicants beats a $10,000 award with 12,000.
- **"Closing this month" lists** — set `deadlineBefore` to the end of the month and `openOnly: true`.
- **Filter by money** — `minAwardAmount: 5000` keeps only the serious awards.
- **Search by topic** — `searchQuery: "nursing"` finds the matching categories for you, so you do not have to know bold.org's category slugs.
- **Prep essays in bulk** — `essayTopic` gives the actual essay question(s) as plain text, with `essayMinLength` / `essayMaxLength`.
- **Segment by audience** — `educationLevels: ["highschool"]` for graduating seniors, `["graduate"]` for grad students.

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `categoryTypes` | array | `["by-major"]` | Which category families to crawl: `by-major`, `by-state`, `by-type`, `by-demographics`, `by-year` |
| `maxCategoryPages` | integer | `20` | How many category pages to fetch (≈30 scholarships each) |
| `maxResults` | integer | `200` | Hard cap on rows returned — also your cost cap |
| `startUrls` | array | — | Specific bold.org category **or** individual scholarship URLs, instead of sitemap discovery |
| `searchQuery` | string | — | Free-text filter, e.g. `nursing` or `first generation`. Every word must appear in the name, description, category, slug or criteria (the word "scholarship" is ignored). Also crawls matching category pages first |
| `openOnly` | boolean | `true` | Drop scholarships whose deadline has passed (rolling deadlines are always kept) |
| `minAwardAmount` | integer | — | Minimum single-award size in USD |
| `deadlineAfter` | string | — | Only deadlines on/after this date (`YYYY-MM-DD`) |
| `deadlineBefore` | string | — | Only deadlines on/before this date (`YYYY-MM-DD`) |
| `educationLevels` | array | — | `highschool`, `undergraduate`, `graduate` |
| `includeEssayPrompt` | boolean | `true` | Include the essay question(s) as plain text |

#### Example input

```json
{
  "categoryTypes": ["by-major", "by-type"],
  "maxCategoryPages": 10,
  "maxResults": 200,
  "minAwardAmount": 1000,
  "deadlineBefore": "2026-12-31",
  "educationLevels": ["highschool"]
}
```

### Sample output

```json
{
  "name": "Pamela Branchini Memorial Scholarship",
  "slug": "pamela-branchini-memorial-scholarship",
  "url": "https://bold.org/scholarships/pamela-branchini-memorial-scholarship/",
  "description": "This scholarship seeks to honor the life of Pamela Branchini by supporting students who are pursuing degrees in the fine arts.",
  "category": "Arts",
  "deadline": "2026-11-05T23:59:59Z",
  "isRollingDeadline": false,
  "announcementDate": "2026-12-06T00:00:00.000Z",
  "awardAmount": 1000,
  "awardAmounts": [1000, 1000],
  "totalAwardAmount": 2000,
  "numberOfAwards": 2,
  "numberOfApplicants": 665,
  "applicantsPerAward": 332.5,
  "educationLevels": ["highSchool", "undergraduate", "graduate"],
  "acceptsHighSchool": true,
  "criteria": ["Ambition", "Need", "Boldest Bold.org Profile"],
  "requiresEssay": true,
  "essayTopic": "Tell us about a piece of art you made and what it means to you.",
  "essayMinLength": 400,
  "essayMaxLength": 600,
  "isMultiYear": false,
  "donorName": "Dan Branchini and the Glitter Team at Community Lutheran",
  "donorProfileUrl": "https://bold.org/profile/bruce-ewing/",
  "imageUrl": "https://static.bold.org/pamelabranchinimemorialscholarship....jpeg",
  "publishedAt": "2026-05-06T19:31:45.646Z",
  "updatedAt": "2026-09-10T00:40:38.001Z",
  "sourceUrl": "https://bold.org/scholarships/by-major/art-scholarships/",
  "scrapedAt": "2026-09-10T10:21:03.552Z"
}
```

### FAQ

**Do I need a proxy or a browser?**
No. bold.org ships the full scholarship records inside the initial HTML response, so this Actor is plain HTTP — fast, cheap and it runs fine on the smallest memory setting.

**How many scholarships can I get?**
One category page yields about 30 complete records in a single request, and there are 500+ category pages across the five category families. Raise `maxCategoryPages` and `maxResults` together; results are de-duplicated by scholarship ID across categories, so overlapping categories never bill you twice for the same scholarship.

**Why did I get fewer rows than `maxResults`?**
Either the crawl ran out of category pages (raise `maxCategoryPages`), or your filters removed them. The log prints how many records were found and how many survived filtering on every page. Filtered-out records are not charged.

**What is `applicantsPerAward`?**
`numberOfApplicants / numberOfAwards`, rounded to one decimal — bold.org publishes the live applicant count, so this is a real competitiveness signal, not an estimate. It is `null` when either number is unavailable.

**Is the data live?**
Yes, each run fetches the pages fresh. `updatedAt` is bold.org's own last-modified timestamp for the scholarship, and `scrapedAt` is when we read it.

**Is this allowed?**
Only public pages are read, and only paths that bold.org's `robots.txt` permits — it disallows query-string URLs (`Disallow: /*?*`), so this Actor never requests one. No login, no personal data about applicants: the applicant *count* is a public number on the listing page.

**How does this compare to other bold.org scrapers?**
Depth. This Actor returns ~28 typed fields per scholarship — including `numberOfAwards`, `numberOfApplicants`, `applicantsPerAward`, the essay prompt(s), judging criteria and donor — versus the 11 fields typical of other bold.org Actors, where `amount` is usually a plain string with no award-count or applicant data at all. All four filters (`searchQuery`, `minAwardAmount`, `deadlineAfter`/`deadlineBefore`, `educationLevels`) are verified against real runs: each one measurably changes which rows come back, not just a passthrough flag.

**Can I scrape one specific scholarship?**
Yes — put its page URL in `startUrls`, e.g. `https://bold.org/scholarships/chris-jackson-scholarship/`.

# Actor input Schema

## `categoryTypes` (type: `array`):

Which bold.org scholarship category families to crawl. Category pages are discovered from bold.org's sitemap, so no query-string URLs are ever requested. Ignored when you supply Start URLs.

## `maxCategoryPages` (type: `integer`):

How many category pages to fetch. Each page returns about 30 complete scholarship records in one request, so 20 pages is roughly 600 records before de-duplication.

## `maxResults` (type: `integer`):

Stop after this many scholarships have been returned. This is also your cost cap: you are charged per returned scholarship only.

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

Specific bold.org URLs to scrape instead of sitemap-discovered categories. Accepts category pages (https://bold.org/scholarships/by-major/nursing-scholarships/) and individual scholarship pages (https://bold.org/scholarships/<slug>/). Do not include query strings — bold.org's robots.txt disallows them.

## `searchQuery` (type: `string`):

Free-text filter, e.g. "nursing" or "first generation". Every word must appear in the scholarship's name, description, category, slug or criteria (the word "scholarship" itself is ignored). It also reorders sitemap-discovered category pages so matching ones are crawled first. Filtered-out records are never charged.

## `openOnly` (type: `boolean`):

Skip scholarships whose deadline has already passed. Rolling-deadline scholarships are always kept.

## `minAwardAmount` (type: `integer`):

Only return scholarships whose largest single award is at least this many dollars. Leave empty for no minimum.

## `deadlineAfter` (type: `string`):

Only return scholarships with a deadline on or after this date (YYYY-MM-DD).

## `deadlineBefore` (type: `string`):

Only return scholarships with a deadline on or before this date (YYYY-MM-DD). Useful for building 'closing this month' lists.

## `educationLevels` (type: `array`):

Only return scholarships open to at least one of these levels. Leave empty for all levels.

## `includeEssayPrompt` (type: `boolean`):

Include the scholarship's essay question(s) as plain text in the essayTopic field.

## Actor input object example

```json
{
  "categoryTypes": [
    "by-major"
  ],
  "maxCategoryPages": 20,
  "maxResults": 200,
  "startUrls": [],
  "openOnly": true,
  "educationLevels": [],
  "includeEssayPrompt": true
}
```

# Actor output Schema

## `dataset` (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 = {};

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

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

```

## MCP server setup

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