# Idealist Scraper \[$2.5/1K💰] | Nonprofit Jobs | Volunteer (`ahmed_jasarevic/idealist-scraper`) Actor

Scrape Idealist nonprofit jobs, internships, volunteer opportunities, events and organization profiles — with structured salary ranges where published. Built for nonprofit recruiting and social-impact research. $2.50 per 1,000 listings.

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

## Pricing

from $2.40 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
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

## Idealist Scraper

Scrape Idealist's public listings — nonprofit jobs, internships, volunteer opportunities, events and organization profiles — with structured salary ranges where published, keyless and browser-free, at $2.50 per 1,000 listings.

**Built for:**

- Nonprofit recruiters and talent teams monitoring the social-impact job market
- Volunteer and event organizers benchmarking opportunities by cause, place and pay
- Research on nonprofit hiring, compensation and organization landscapes
- Building a mission-driven jobs database with location, salary and focus-area fields
- Career platforms that curate NGO, advocacy and social-impact roles

### Collect Nonprofit Jobs & Volunteer Opportunities With Salary Data

Pick the record types you want — `JOB`, `INTERNSHIP`, `VOLOP` (volunteer), `EVENT`, `ORG` — plus a free-text query (`fundraising`, `climate`, `program manager`), locale (`en`/`es`), sort (`relevance`/`newest`) and any combination of filters: US state or country, geo radius, organization type, areas of focus, functions, onsite/remote/hybrid, employment type and seniority. Every listing is one row: `title`, `organization`, `city`/`state`/`country`, coordinates, `publishedAt`, taxonomy fields (`areasOfFocus`, `functions`, `keywords`), and — when pay is published — a structured `salary` object (`minimum`, `maximum`, `period`, `currency`) plus the `compdb` compensation taxonomy (`familyId`, `jobTitleId`, `level`, `synonymName`). `hasSalaryOnly: true` collects just the pay-transparent listings.

### How It Works

![How the Idealist Scraper works: Algolia searches become job, internship, volunteer, event and organization rows.](https://api.apify.com/v2/key-value-stores/oeuA0kLOyhbRM4fzt/records/how-it-works-idealist-scraper)

Idealist's React app embeds its public Algolia configuration, including the search key. The Actor posts directly to the `idealist7-production` index, 100 records per page, with filters for type, location, cause, function, level, remote work and salary.

Each row covers one listing with organization, location, salary range, cause areas, functions, job type, professional level, description and source URL.

Idealist's site is a client-rendered React app whose search results never appear in the served HTML — but the page embeds the whole configuration of the Algolia search backend the front end itself queries, including its public search key. The actor issues plain HTTP POSTs to that Algolia index (`idealist7-production`, ~345k records; `newest` sort switches index) with the site's own embedded configuration — no cookies, no login, no browser:

```
POST https://NSV3AUESS7-dsn.algolia.net/1/indexes/idealist7-production/query
Headers:
  x-algolia-application-id: <app id embedded in the page>
  x-algolia-api-key: <public search key embedded in the page>
Body: { "query": "program manager", "hitsPerPage": 100, "page": 0,
        "filters": "type:JOB AND locale:en AND state:\"NY\"" }
```

Algolia sits outside Idealist's CDN/anti-bot layer and answers with clean JSON, so a CheerioCrawler is used purely as the HTTP + pagination + retry + proxy engine. Result types come from the index's own `type` facet. The authenticated `/data/*` endpoints are **not** used, and the org/compdb indexes that require a session key are **not** readable with the public key (documented limitation below).

### Input Parameters

| Field | Type | Required | Default | Notes |
| --- | --- | --- | --- | --- |
| `listingTypes` | array | Yes | `["JOB","VOLOP"]` | Any of `JOB`, `INTERNSHIP`, `VOLOP`, `EVENT`, `ORG`. |
| `query` | string | No | `""` | Free-text search: `program manager`, `fundraising`, `climate`… |
| `locale` | string | No | `en` | `en` or `es` (content language). |
| `sort` | string | No | `relevance` | `relevance` or `newest`. |
| `state` / `country` | string | No | `""` | US state code (`NY`, `CA`) or ISO country code (`US`, `GB`, `CA`). |
| `latitude` / `longitude` / `radiusKm` | number | No | — | Geo search around a point (`radiusKm` default `0` = disabled). |
| `orgType` | array | No | `[]` | `NONPROFIT`, `CORPORATION`, `GOVERNMENT`, `CONSULTANT`, `COMMUNITY`, `RECRUITER`, `GROUP`. |
| `areasOfFocus` | array | No | `[]` | e.g. `EDUCATION`, `HOUSING_HOMELESSNESS`, `HUMAN_RIGHTS_CIVIL_LIBERTIES`, `HEALTH`, `ENVIRONMENT`, `ARTS_CULTURE`. |
| `functions` | array | No | `[]` | e.g. `DEVELOPMENT_FUNDRAISING`, `ADVOCACY`, `EDUCATION`, `LEGAL`, `MARKETING_COMMUNICATIONS`. |
| `locationType` | array | No | `[]` | `ONSITE`, `REMOTE`, `HYBRID`. |
| `jobType` | array | No | `[]` | `FULL_TIME`, `PART_TIME`, `CONTRACT`, `TEMPORARY` (JOB only). |
| `professionalLevel` | array | No | `[]` | `ENTRY_LEVEL`, `PROFESSIONAL`, `MANAGERIAL`, `DIRECTOR`, `EXECUTIVE`, `NONE`. |
| `hasSalaryOnly` | boolean | No | `false` | Only listings that publish a pay range. |
| `upcomingOnly` | boolean | No | `false` | Only events/volunteer opportunities ending in the future. |
| `includeDescription` | boolean | No | `true` | Full description text; `false` keeps output compact. |
| `maxItemsPerType` | integer | No | `100` | Records per selected listing type. |
| `maxItems` | integer | No | `300` | Global cap across types. |
| `maxPagesPerType` | integer | No | `10` | Pagination safety cap (100 records per page). |
| `proxy` | object | No | disabled | Optional; Algolia does not block datacenter IPs. |

### Output Fields

- **Common:** `id`, `type`, `title`, `url`, `organization`, `organizationId`, `organizationType`, `city`, `state`, `country`, `latitude`, `longitude`, `locationType`, `publishedAt`, `areasOfFocus`, `keywords`, `functions`, `jobType`, `professionalLevel`, `hasSalary`, `description` (unless disabled)
- **Pay:** `salary` (`minimum`, `maximum`, `period`, `currency`) and `compdb` (`synonymName`, `familyId`, `jobTitleId`, `level`)
- **JOB extras:** duties/skills in `description`; **VOLOP:** schedule (start/end), remote/onsite, skills, perks (training, stipend, housing, academic credit); **EVENT:** start/end date & time, timezone, venue; **ORG:** mission, geo coordinates, org type, focus areas, hiring/seeking-volunteers flags

### Example Input

```json
{
  "listingTypes": ["JOB"],
  "query": "program manager",
  "state": "NY",
  "hasSalaryOnly": true,
  "maxItems": 100
}
```

### Example Output

```json
{
  "id": "6a8ba154c1264176976dae7aef51c51b",
  "type": "JOB",
  "title": "Assistant Executive Director of Annual Giving",
  "url": "https://www.idealist.org/en/nonprofit-job/6a8ba154...-assistant-executive-director-of-annual-giving",
  "organization": "St. Mary's University of San Antonio",
  "organizationId": "cb4e55210509419baed1a166757b1de7",
  "organizationType": "NONPROFIT",
  "city": "San Antonio",
  "state": "TX",
  "country": "US",
  "latitude": 29.449561,
  "longitude": -98.560832,
  "locationType": "ONSITE",
  "publishedAt": "2026-10-19T16:19:09.000Z",
  "areasOfFocus": ["EDUCATION"],
  "keywords": ["Development/Fundraising"],
  "functions": ["DEVELOPMENT_FUNDRAISING"],
  "jobType": ["FULL_TIME"],
  "professionalLevel": "NONE",
  "hasSalary": false,
  "salary": null,
  "compdb": {
    "synonymName": "Assistant Director, Annual Giving",
    "familyId": "2ad95559ae3f459d8c1fe5938d6312b5",
    "level": 5
  }
}
```

### Automate Mission-Driven Job Monitoring With Schedules & Webhooks

- **Weekly new-roles run:** schedule `listingTypes: ["JOB"]` with `sort: "newest"` and diff rows by `id` for postings since the previous run.
- **Volunteer & event pipelines:** schedule `VOLOP`/`EVENT` with `upcomingOnly: true` so expired opportunities drop out of every run automatically.
- **Compensation tracking:** run `hasSalaryOnly: true` monthly to follow how many social-impact roles publish pay and at what ranges.
- Recurring, re-run-heavy usage also improves this actor's Store recommendation signals.

### Related Actors

- [Idealist Scraper - Nonprofit & Social Impact Jobs | $3/1K](https://apify.com/santamaria-automations/idealist-scraper) — the most-used Idealist actor on the Store.
- [Idealist Nonprofit Jobs Scraper](https://apify.com/parseforge/idealist-nonprofit-jobs-scraper) — Idealist nonprofit-jobs extraction.
- [Idealist Jobs Scraper](https://apify.com/piotrv1001/idealist-jobs-scraper) — lighter Idealist jobs option.
- [Charity & Nonprofit Mega Pack Scraper](https://apify.com/parseforge/charity-nonprofit-mega-pack-scraper) — multi-source charity/nonprofit coverage, of which Idealist is one source.
- [CharityJob Scraper — UK Nonprofit & Charity Sector Jobs](https://apify.com/studio-amba/charityjob-scraper) — UK-focused charity jobs, complementary to Idealist's global reach.

### Frequently Asked Questions

#### Why use this actor instead of the official API?

Idealist does have an official Listings API (`api-sandbox.idealist.org/listings-api`), and it's a good one — but access is granted manually: you request a key by emailing support@idealist.org, must display Idealist's attribution/branding in your product, should space sequential requests at ≥250 ms, and fetch incrementally with `since`. This actor reads the same public listings through the site's own search backend with no key request, no attribution obligation and no pacing rule — and covers all five record types (jobs, internships, volunteer opportunities, events, organization profiles) including the filters and salary fields listed above.

#### Is there an Idealist API?

Yes — official, as described above (sandbox URL, key issued by email, attribution required, JSON REST with an `Accept: application/json` header mandatory). If you're building a public product that displays Idealist data with attribution, the official API is a legitimate path; if you want keyless, immediately usable access in a data pipeline, use this actor.

#### Can I get salary data from Idealist?

Yes, within what Idealist publishes: every listing that shows a pay range carries a structured `salary` object, and all job records carry `compdb` compensation-taxonomy fields (family, level, synonym name). Set `hasSalaryOnly: true` to collect only pay-transparent listings. One honest limitation: Idealist's dedicated compensation-database indexes are not readable with the site's public search key, so full salary-explorer data (which needs an authenticated session) is out of scope.

#### How do I find remote nonprofit jobs?

Set `locationType: ["REMOTE"]` (or `["HYBRID"]`), optionally combined with `country`/`state` or the geo filters for roles tied to a place. Remote flags come from the listings themselves.

#### What record types can I collect in one run?

Any combination of `JOB`, `INTERNSHIP`, `VOLOP` (volunteer), `EVENT` and `ORG` (organization profiles) — each type paginates to `maxItemsPerType`, with `maxItems` as the global stop. Free accounts get a capped preview (20 items); paid accounts get the full caps.

### For AI Agents & LLM Apps

**Purpose:** returns Idealist listings — nonprofit jobs, internships, volunteer opportunities, events and org profiles — with salary and taxonomy fields, keyless, no browser.

**Minimal input:**

```json
{ "listingTypes": ["JOB"], "query": "fundraising", "maxItems": 25 }
```

**Pay-transparent jobs variant:**

```json
{ "listingTypes": ["JOB"], "hasSalaryOnly": true, "sort": "newest", "maxItems": 50 }
```

**Output fields:** id, type, title, url, organization, organizationId, organizationType, city, state, country, latitude, longitude, locationType, publishedAt, areasOfFocus, keywords, functions, jobType, professionalLevel, hasSalary, salary (minimum, maximum, period, currency), compdb (synonymName, familyId, jobTitleId, level), description.

**Behaviors an agent should know:**

- `listingTypes` is required (defaults to `["JOB","VOLOP"]`) — pass the types you want explicitly.
- Caps stack: `maxItemsPerType` (100) per type, `maxItems` (300) global, `maxPagesPerType` (10 × 100 records) safety stop.
- `includeDescription` defaults to `true`; set `false` for compact rows.
- `sort: "newest"` switches the underlying index; `locale` affects both content and index.
- Free accounts are capped at a 20-item preview per run regardless of input.
- `salary` is `null` unless the listing publishes pay — check `hasSalary` first; org/compdb indexes beyond the search key are not readable.

**Billing:** pay-per-event — `result` at $0.0025 per saved record, plus a run-start event.

### Legal & Compliance Disclaimer

This actor is an independent tool and is not affiliated with, endorsed by, or sponsored by Idealist.org. It reads only the public listings Idealist's own front end queries (through the search configuration embedded in its public pages) — no login, no authenticated `/data/*` endpoints, no session cookies. Listings can reference named individuals and organizations; users are responsible for their own compliance with Idealist's Terms of Service and applicable data-protection law (e.g. GDPR for EU data subjects) when storing, redistributing or automating access to the collected data.

### SEO Keywords

idealist scraper, idealist api, nonprofit jobs api, scrape idealist, idealist job listings, nonprofit job data, volunteer opportunities data, idealist alternative api, ngo jobs data, remote nonprofit jobs, charity jobs data, social impact jobs, nonprofit organization database, idealist listings api, nonprofit internships data, event listings data, salary transparency jobs, us nonprofit jobs data, advocacy jobs data, idealist data export

# Actor input Schema

## `listingTypes` (type: `array`):

Which Idealist records to collect. JOB = paid nonprofit jobs, INTERNSHIP = internships, VOLOP = volunteer opportunities, EVENT = event listings, ORG = nonprofit organization profiles.

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

Free-text search, e.g. "program manager", "fundraising", "climate".

## `locale` (type: `string`):

Content language of the listings.

## `sort` (type: `string`):

Sort by search relevance or by most recently published.

## `state` (type: `string`):

Filter by US state code, e.g. "NY", "CA", "IL".

## `country` (type: `string`):

Filter by ISO country code, e.g. "US", "GB", "CA".

## `latitude` (type: `string`):

Optional. Center of a geo search. Use together with longitude and radius.

## `longitude` (type: `string`):

Optional. Center of a geo search. Use together with latitude and radius.

## `radiusKm` (type: `integer`):

Optional. Radius in kilometres for the geo search.

## `orgType` (type: `array`):

Filter listings by the type of the posting organization.

## `areasOfFocus` (type: `array`):

Filter by area of focus codes, e.g. EDUCATION, HOUSING_HOMELESSNESS, HUMAN_RIGHTS_CIVIL_LIBERTIES, HEALTH, ENVIRONMENT, ARTS_CULTURE.

## `functions` (type: `array`):

Filter by function codes, e.g. DEVELOPMENT_FUNDRAISING, ADVOCACY, EDUCATION, LEGAL, MARKETING_COMMUNICATIONS.

## `locationType` (type: `array`):

Onsite, remote or hybrid listings.

## `jobType` (type: `array`):

Employment type filter for JOB listings.

## `professionalLevel` (type: `array`):

Seniority filter for JOB listings.

## `hasSalaryOnly` (type: `boolean`):

Return only listings that publish a pay range (useful for compensation / salary-explorer analysis).

## `upcomingOnly` (type: `boolean`):

Return only events and volunteer opportunities whose end date is in the future.

## `includeDescription` (type: `boolean`):

Include the full listing/organization description text. Disable to keep the output compact.

## `maxItemsPerType` (type: `integer`):

Maximum number of records collected for each selected listing type.

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

Maximum number of records collected across all selected listing types.

## `maxPagesPerType` (type: `integer`):

Safety cap on pagination depth per listing type (100 records per page).

## `proxy` (type: `object`):

Select proxies to be used by your crawler.

## Actor input object example

```json
{
  "listingTypes": [
    "JOB",
    "VOLOP"
  ],
  "query": "",
  "locale": "en",
  "sort": "relevance",
  "state": "",
  "country": "",
  "latitude": "",
  "longitude": "",
  "radiusKm": 0,
  "orgType": [],
  "areasOfFocus": [],
  "functions": [],
  "locationType": [],
  "jobType": [],
  "professionalLevel": [],
  "hasSalaryOnly": false,
  "upcomingOnly": false,
  "includeDescription": true,
  "maxItemsPerType": 100,
  "maxItems": 300,
  "maxPagesPerType": 10,
  "proxy": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `results` (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 = {
    "listingTypes": [
        "JOB",
        "VOLOP"
    ],
    "orgType": [],
    "areasOfFocus": [],
    "functions": [],
    "locationType": [],
    "jobType": [],
    "professionalLevel": [],
    "proxy": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("ahmed_jasarevic/idealist-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 = {
    "listingTypes": [
        "JOB",
        "VOLOP",
    ],
    "orgType": [],
    "areasOfFocus": [],
    "functions": [],
    "locationType": [],
    "jobType": [],
    "professionalLevel": [],
    "proxy": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("ahmed_jasarevic/idealist-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 '{
  "listingTypes": [
    "JOB",
    "VOLOP"
  ],
  "orgType": [],
  "areasOfFocus": [],
  "functions": [],
  "locationType": [],
  "jobType": [],
  "professionalLevel": [],
  "proxy": {
    "useApifyProxy": false
  }
}' |
apify call ahmed_jasarevic/idealist-scraper --silent --output-dataset

```

## MCP server setup

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