# EdJoin Jobs Scraper: K-12 District Jobs, Salaries & HR Emails (`getascraper/edjoin-scraper`) Actor

Extract EdJoin K-12 school job listings across California and US districts: titles, salary ranges, deadlines, and requirements. Every posting includes a direct HR contact email and full street address by default, no add-on fee. Filter to new postings and monitor on a schedule. No login needed.

- **URL**: https://apify.com/getascraper/edjoin-scraper.md
- **Developed by:** [GetAScraper](https://apify.com/getascraper) (community)
- **Categories:** Jobs, Lead generation, Education
- **Features:** Limited permissions
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.12 / 1,000 jobs

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

## 🎓 EdJoin Jobs Scraper: K-12 District Jobs, Salaries & HR Emails

<table width="100%" style="display:table;width:100%;border-collapse:separate;border-spacing:0;table-layout:fixed;margin-bottom:0">
<tr>
<td colspan="2" style="padding:14px 18px;background:#EAF1FB;border:none;border-top:3px solid #1D4E89;border-left:1px solid #D6D3D1;border-right:1px solid #D6D3D1;color:#1C1917;border-radius:10px 10px 0 0">
<span style="font-size:16px;font-weight:700;color:#1C1917">Pull K-12 school district job listings directly from EdJoin.</span> <span style="font-size:15px;color:#57534E">Direct HR contact emails, full street addresses, salary ranges, and deadlines across California and US school districts, ready for daily monitoring.</span>
</td>
</tr>
<tr>
<td colspan="2" style="padding:10px 14px;background:#1D4E89;border:none;border-left:1px solid #D6D3D1;border-right:1px solid #D6D3D1;color:#FFFFFF">
<span style="color:#FFFFFF;font-size:14px;font-weight:700;letter-spacing:0.5px">US EDUCATION JOBS</span>
<span style="color:#FFFFFF;font-size:13px">&nbsp;&nbsp;&bull;&nbsp;&nbsp;HigherEdJobs faculty and staff roles alongside EdJoin K-12 postings</span>
</td>
</tr>
<tr>
<td style="padding:10px 12px;border:none;border-left:1px solid #D6D3D1;border-bottom:1px solid #D6D3D1;vertical-align:top;width:50.0%;background:#FFFFFF;color:#1C1917">
<span style="overflow-wrap:break-word;word-break:break-word"><img src="https://apify-image-uploads-prod.s3.us-east-1.amazonaws.com/jNDbFabbVxMhnQNb4-actor-9yQdC0vf4jyI7aOjp-lO7Ah6KaOK-CompressJPEG.Online_img%28512x512%29_%2815%29.jpg" width="20" height="20" style="vertical-align:middle;border-radius:4px">&nbsp;<a href="https://apify.com/getascraper/higheredjobs-com-scraper" style="color:#1C1917;text-decoration:none;font-weight:700;font-size:13px">HigherEdJobs</a></span><br>
<span style="color:#57534E;font-size:11px">Academic faculty and staff jobs</span>
</td>
<td style="padding:10px 12px;border:none;border-left:1px solid #D6D3D1;border-right:1px solid #D6D3D1;border-bottom:1px solid #D6D3D1;vertical-align:top;width:50.0%;background:#EAF1FB;color:#1C1917">
<span style="overflow-wrap:break-word;word-break:break-word"><img src="https://apify-image-uploads-prod.s3.us-east-1.amazonaws.com/jNDbFabbVxMhnQNb4-actor-PV0zkoqhselkr6vUF-xXPIc0sKL7-CompressJPEG.Online_img%28512x512%29_%2812%29.jpg" width="20" height="20" style="vertical-align:middle;border-radius:4px">&nbsp;<a href="https://apify.com/getascraper/edjoin-scraper" style="color:#1D4E89;text-decoration:none;font-weight:700;font-size:13px">EdJoin</a></span><br>
<span style="color:#1D4E89;font-size:11px;font-weight:700">&#10148; You are here</span>
</td>
</tr>
</table>
<table width="100%" style="display:table;width:100%;border-collapse:separate;border-spacing:0;margin-top:0;margin-bottom:0">
<tr>
<td style="padding:24px 28px;background:#EAF1FB;border:1px solid #BFD3EA;border-top:none;color:#1C1917">
<span style="font-size:23px;font-weight:800;color:#1C1917;line-height:1.3">K-12 school district jobs with the HR email already included</span><br>
<span style="font-size:15px;color:#57534E;line-height:1.6">Salary ranges, deadlines, and full addresses pulled directly from EdJoin, with no add-on fee for the hiring contact.</span>
</td>
</tr>
</table>
<table width="100%" style="display:table;width:100%;border-collapse:separate;border-spacing:0;margin-top:0">
<tr>
<td style="padding:14px 12px;width:25%;background:#FFFFFF;border:1px solid #BFD3EA;vertical-align:top;border-top:none;color:#1C1917;border-radius:0 0 0 10px">
<span style="font-size:15px;font-weight:800;color:#1D4E89">✉️ HR emails, included</span><br>
<span style="font-size:12px;color:#57534E">Every posting ships with a hiring contact email. No add-on, no extra charge.</span>
</td>
<td style="padding:14px 12px;width:25%;background:#FFFFFF;border:1px solid #BFD3EA;border-left:none;vertical-align:top;border-top:none;color:#1C1917">
<span style="font-size:15px;font-weight:800;color:#1D4E89">📍 Full street address</span><br>
<span style="font-size:12px;color:#57534E">Postal code and street address on every posting, ready for mapping or outreach.</span>
</td>
<td style="padding:14px 12px;width:25%;background:#FFFFFF;border:1px solid #BFD3EA;border-left:none;vertical-align:top;border-top:none;color:#1C1917">
<span style="font-size:15px;font-weight:800;color:#1D4E89">💵 Structured pay data</span><br>
<span style="font-size:12px;color:#57534E">Salary ranges, work hours, and requirements as clean fields, not one long paragraph.</span>
</td>
<td style="padding:14px 12px;width:25%;background:#FFFFFF;border:1px solid #BFD3EA;border-left:none;vertical-align:top;border-top:none;color:#1C1917;border-radius:0 0 10px 0">
<span style="font-size:15px;font-weight:800;color:#1D4E89">🔔 Built for monitoring</span><br>
<span style="font-size:12px;color:#57534E">Filter to postings from the last N days and catch new vacancies first.</span>
</td>
</tr>
</table>

Get instant, structured access to K-12 education jobs across US school districts. Extract direct HR contact emails, full addresses, salary ranges, deadlines, and requirements in bulk.

### 🔍 What does EdJoin Scraper do?

The **EdJoin Scraper** extracts complete education vacancy listings from **EdJoin** (edjoin.org), the largest job board for public and private school districts in the United States.

It works in two steps:

1. **Search**: Finds postings that match your keyword and location directly from EdJoin's own job search system, so results stay fast and current.
2. **Detail pass**: Opens each posting to pull the hiring contact email, full requirements, and employer logo straight from the structured details EdJoin already publishes on the page.

With Apify, you can run this scraper through the Console or on a schedule, and send results straight to Google Sheets, Airtable, Make, or a webhook.

### 🎯 Why use EdJoin Scraper?

- **Reach school district hiring teams first**: Every job record already includes a direct HR contact email. No enrichment add-on, no extra charge.
- **Keep your education job board current**: Pull fresh EdJoin postings on a schedule and publish complete listings automatically, down to the street address.
- **Benchmark teacher and staff pay**: Compare salary ranges, work hours, and requirements across districts, counties, and states as clean fields, not one long paragraph.
- **Catch new vacancies the moment they post**: Filter to postings from the last N days and run the actor on a schedule for daily or weekly alerts.

### 🚀 How to use EdJoin Scraper

<table width="100%" style="display:table;width:100%;border-collapse:separate;border-spacing:0">
<tr>
<td style="padding:16px 14px;width:33%;background:#EAF1FB;border:1px solid #BFD3EA;border-radius:10px 0 0 10px;vertical-align:top;color:#1C1917">
<span style="font-size:12px;font-weight:800;color:#1D4E89;letter-spacing:1px">STEP 1</span><br>
<span style="font-size:14px;font-weight:700;color:#1C1917">Set up your search</span><br>
<span style="font-size:12px;color:#57534E">Enter a keyword like Special Education and a location like California.</span>
</td>
<td style="padding:16px 14px;width:33%;background:#EAF1FB;border:1px solid #BFD3EA;border-left:none;vertical-align:top;color:#1C1917">
<span style="font-size:12px;font-weight:800;color:#1D4E89;letter-spacing:1px">STEP 2</span><br>
<span style="font-size:14px;font-weight:700;color:#1C1917">Choose your detail level</span><br>
<span style="font-size:12px;color:#57534E">Turn on full details for HR emails and requirements, or keep it fast for a listings-only pass.</span>
</td>
<td style="padding:16px 14px;width:33%;background:#EAF1FB;border:1px solid #BFD3EA;border-left:none;border-radius:0 10px 10px 0;vertical-align:top;color:#1C1917">
<span style="font-size:12px;font-weight:800;color:#1D4E89;letter-spacing:1px">STEP 3</span><br>
<span style="font-size:14px;font-weight:700;color:#1C1917">Run and export</span><br>
<span style="font-size:12px;color:#57534E">Download results as JSON, CSV, Excel, or HTML, or send them straight to your tools.</span>
</td>
</tr>
</table>

***

### 📋 Input parameters

The scraper accepts these input settings:

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `startUrls` | array of URLs | No | Optional EdJoin search URLs to scrape directly. Overrides the keyword and location filters when set. |
| `keyword` | string | No | Search term for a role, specialty, or district, for example "Teacher" or "Special Education". |
| `location` | string | No | Geographic filter: city, county, state, or ZIP code, for example "California" or "San Diego". |
| `includeDescription` | boolean | No | Visit each posting's page for the full requirements, HR email, and employer logo. Turn off for a faster listings-only pass. |
| `dateWithinDays` | integer | No | Only return postings created within the last N days. Leave at 0 to include every posting. |
| `maxItems` | integer | No | Maximum number of job postings to collect in one run. |
| `maxConcurrency` | integer | No | Maximum number of requests handled in parallel. |
| `maxRequestRetries` | integer | No | Number of times a failed request is retried before it is skipped. |
| `proxyConfiguration` | enum | No | Proxy routing for the run. EdJoin allows standard crawling, so the default setting works for almost everyone. |

***

### 📤 Output structure

The scraper outputs normalized flat job rows, with empty fields omitted. Here is a sample record:

```json
{
  "posting_id": 2234074,
  "title": "Secretary II (School) at Cajon Park - Pos#30024578",
  "district_name": "Santee School District",
  "city": "Santee",
  "county_name": "San Diego",
  "state_name": "California",
  "postal_code": "92071-2674",
  "address": "9625 Cuyamaca St.",
  "job_type": "Clerical / Secretarial Staff / Office Tech.",
  "employment_type": "FULL_TIME",
  "salary_info": "Salary Classification: 27",
  "pay_range_from": "Salary Classification: 27/ Step A",
  "pay_range_to": "Salary Classification: Step E",
  "pay_range_unit": "Monthly",
  "single_rate": null,
  "single_rate_unit": null,
  "contact_email": "brandi.medrano@santeesd.net",
  "date_posted": "2026-06-06T07:00:00.000Z",
  "deadline": "2026-06-12T23:00:00.000Z",
  "work_hours": "203 work days / 8.0 hrs. / 7:00 a.m. - 3:30 p.m.",
  "requirements": "MINIMUM QUALIFICATIONS / CERTIFICATIONS / AND APPLICATION PROCEDURE: See job description for a complete list of qualifications and requirements at www.santeesd.net; under the Human Resources department. Applications, transcripts, certification(s), and / or documentation MUST be submitted for each position...",
  "required_skills": "First Aid, CPR and AED Certificate (All three trainings required) Online training certificates accepted. Typing Certificate 50 nwpm (net words per minute)",
  "logo": "https://edjoinprodstoragewest.blob.core.windows.net/customerlogos/logo133892042317467324.png",
  "url": "https://www.edjoin.org/Home/JobPosting/2234074",
  "scraped_at": "2026-06-07T05:22:15.341Z"
}
```

***

### 📊 Output fields explanation

| Field | Type | Description |
| --- | --- | --- |
| `posting_id` | Number | Unique identifier for the vacancy posting. |
| `title` | String | Job position title. |
| `district_name` | String | School district or hiring agency name. |
| `city` | String | Primary city. |
| `county_name` | String | County name where the position is located. |
| `state_name` | String | State name, for example California. |
| `postal_code` | String | Location ZIP or postal code. |
| `address` | String | Physical street address of the district. |
| `job_type` | String | Broad classification group. |
| `employment_type` | String | Full time, part time, or other employment status. |
| `salary_info` | String | Raw salary text as published. |
| `pay_range_from` | String | Stated lower bound of the pay schedule. |
| `pay_range_to` | String | Stated upper bound of the pay schedule. |
| `pay_range_unit` | String | Unit of the pay range, for example monthly or hourly. |
| `single_rate` | String | Stated flat pay rate when no range is given. |
| `single_rate_unit` | String | Unit for the flat pay rate, when one is given. |
| `contact_email` | String | Direct HR contact email address. |
| `date_posted` | String | Publication date. |
| `deadline` | String | Application closing date. |
| `work_hours` | String | Work shift, day, or calendar schedule. |
| `requirements` | String | Detailed qualifications description. |
| `required_skills` | String | Explicit certificates or skill requirements. |
| `logo` | String | Hiring organization logo URL. |
| `url` | String | Link to the original posting. |
| `scraped_at` | String | Timestamp of when the row was scraped. |

***

### 💰 Pricing

This Actor uses pay-per-result pricing: you are charged only for job listings actually saved to your dataset. Empty or filtered-out runs save no rows and cost nothing. There is no subscription, and volume discounts apply automatically at higher Apify usage tiers.

***

### ⭐ Enjoying EdJoin Scraper?

<table width="100%" style="display:table;width:100%;border-collapse:separate;border-spacing:0">
<tr>
<td style="padding:20px 24px 14px;background:#EAF1FB;border:1px solid #EAF1FB;border-left:5px solid #1D4E89;border-radius:10px 10px 0 0;color:#1C1917">
<span style="font-size:20px;letter-spacing:4px">⭐ ⭐ ⭐ ⭐ ⭐</span><br>
<span style="font-size:17px;font-weight:800;color:#1C1917">One run just surfaced direct HR emails across hundreds of district postings, with no add-on fee.</span><br>
<span style="font-size:14px;color:#57534E">A 5-star rating takes 10 seconds and helps other staffing agencies and recruiters find this actor. Your feedback also tells us what to build next.</span>
</td>
</tr>
<tr>
<td style="padding:0;background:#1D4E89;border:1px solid #1D4E89;border-left:5px solid #1D4E89;border-top:none;border-radius:0 0 10px 10px;text-align:center;color:#FFFFFF">
<a href="https://apify.com/getascraper/edjoin-scraper/reviews" style="display:block;padding:13px 16px;color:#FFFFFF;text-decoration:none;font-weight:800;font-size:15px;letter-spacing:0.3px">★&nbsp;&nbsp;Rate this Actor on Apify</a>
</td>
</tr>
</table>

***

### ❓ FAQ, disclaimers, and support

- **Is scraping EdJoin legal?**
  Yes. This scraper extracts publicly available recruitment listings that districts intend to share with the public. It does not access private applicant data or require logging in. Please comply with local regulations and keep concurrency at standard levels.
- **Can I run this on a schedule?**
  Yes. In the Apify Console, create a Schedule to trigger the actor daily, weekly, or monthly.
- **How can I submit suggestions or bugs?**
  Open an issue in the Issues tab on this Actor's page, or contact us through the Apify Console.

### 🔗 Other actors

- [Goodmoves jobs scraper: Scottish charity vacancies](https://apify.com/getascraper/goodmoves-jobs-scraper) ↗ - extracts Scottish charity sector job listings with OSCR charity numbers.
- [HigherEdJobs Scraper: Academic Jobs, Salaries, and Monitoring](https://apify.com/getascraper/higheredjobs-com-scraper) ↗ - extracts university and academic job postings across the US.
- [WTTJ Jobs Scraper: Raw JSON or RAG-Ready Chunks](https://apify.com/getascraper/welcome-to-the-jungle-jobs-scraper) ↗ - extracts job listings from Welcome to the Jungle.
- [CWJobs Scraper: UK tech jobs, salaries & employers](https://apify.com/getascraper/cwjobs-scraper) ↗ - extracts UK tech job listings with salary and location data.
- [Job Bank Canada Scraper & LMIA Job Monitor](https://apify.com/getascraper/jobbank-scraper) ↗ - extracts B2B job listings and employer contacts from Canada's national job directory.

# Actor input Schema

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

Optional EdJoin search URLs to scrape. If provided, it overrides custom search filters.

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

Search for specific jobs by role, specialty, or district (e.g., 'Special Education', 'Math Teacher').

## `location` (type: `string`):

Filter by city, county, state, or ZIP code (e.g., 'California', 'San Diego').

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

If enabled, visits each job's detailed page to extract full requirements and descriptions. Slower but richer data.

## `dateWithinDays` (type: `integer`):

Only include jobs posted within the last N days (0 = any time).

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

Maximum number of job postings to scrape in total.

## `maxConcurrency` (type: `integer`):

Maximum number of requests handled in parallel.

## `maxRequestRetries` (type: `integer`):

Number of times a request will be retried if it fails.

## `proxyConfiguration` (type: `object`):

Proxy settings for crawling. Enabling proxy is recommended for larger crawls to prevent connection throttling.

## Actor input object example

```json
{
  "startUrls": [],
  "keyword": "Teacher",
  "location": "California",
  "includeDescription": true,
  "dateWithinDays": 0,
  "maxItems": 5,
  "maxConcurrency": 8,
  "maxRequestRetries": 3,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# 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 = {
    "startUrls": [],
    "keyword": "Teacher",
    "location": "California",
    "dateWithinDays": 0,
    "maxItems": 5,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("getascraper/edjoin-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": [],
    "keyword": "Teacher",
    "location": "California",
    "dateWithinDays": 0,
    "maxItems": 5,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("getascraper/edjoin-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": [],
  "keyword": "Teacher",
  "location": "California",
  "dateWithinDays": 0,
  "maxItems": 5,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call getascraper/edjoin-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,getascraper/edjoin-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/PV0zkoqhselkr6vUF/builds/40qGd4VeXMgC8fSIk/openapi.json
