# Edjoin Scraper (/w EMAILS) (`memo23/edjoin-scraper`) Actor

Empower your recruitment process with data-driven insights. Our Edjoin Scraper transforms scattered job listings into a comprehensive talent acquisition strategy for schools and districts.

- **URL**: https://apify.com/memo23/edjoin-scraper.md
- **Developed by:** [Muhamed Didovic](https://apify.com/memo23) (community)
- **Categories:** Jobs, Lead generation
- **Stats:** 18 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $1.00 / 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.

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

## Apify Edjoin Scraper

Unlock the power of educational job listings with our comprehensive Edjoin Scraper. Extract detailed job information from Edjoin.org to streamline your job search or recruitment process in the education sector.

### Overview

This Apify actor allows you to scrape detailed job listings from Edjoin.org, including job titles, locations, salary information, and application details. It's perfect for job seekers, educational recruiters, and researchers looking to gather insights from the educational job market.

### Features

- Detailed Job Listings: Extract comprehensive information about each job posting.
- Customizable Search: Use Edjoin's search parameters to target specific job types, locations, or keywords.
- Pagination Handling: Automatically navigate through multiple pages of search results.
- Concurrent Scraping: Efficiently scrape multiple listings with adjustable concurrency.
- Proxy Support: Built-in proxy configuration to enhance scraping reliability and avoid blocks.

### How to Use

1. Set Up: Ensure you have an Apify account and access to the Apify platform.
2. Configure Input: Set the Edjoin search URL with your desired parameters (see Input Configuration section).
3. Adjust Settings: Configure options like maximum items, concurrency, and proxy settings as needed.
4. Run the Scraper: Execute the scraper on the Apify platform.
5. Data Collection: The scraper will output detailed data about the job listings matching your search criteria.

### Input Configuration

Here's an example of how to set up the input for the Apify Edjoin Scraper:

```json
{
    "startUrls": [
        {
            "url": "https://www.edjoin.org/Home/Jobs?rows=50&page=1&sort=postingDate&sortVal=0&order=DESC&keywords=program&location=california&searchType=&regions=&jobTypes=&days=0&empType=&catID=0&onlineApps=null&recruitmentCenterID=0&stateID=0&regionID=null&districtID=0&searchID=0"
        }
    ],
    "maxItems": 50,
    "maxConcurrency": 100,
    "minConcurrency": 1,
    "maxRequestRetries": 20
}
```

#### Input Fields Explanation

- `startUrls`: Array containing the Edjoin search URL with your desired parameters.
- `maxItems`: Maximum number of job listings to scrape (default: 50).
- `maxConcurrency`: Maximum number of pages processed simultaneously (default: 100).
- `minConcurrency`: Minimum number of pages processed simultaneously (default: 1).
- `maxRequestRetries`: Number of retries for failed requests (default: 20).

### Output Structure

The output data includes detailed information about each job listing. Here's a sample of the structure:

```json
{
    "title": "Program Specialist - Speech and Language Support and Compliance - Available this school year",
    "district": "Pleasant Valley School District ",
    "city": "Camarillo",
    "county": "Ventura",
    "state": "California",
    "location": "Ventura County, CA",
    "date": "/Date(1728000000000)/",
    "url": "https://www.edjoin.org/Home/JobPosting/2005234",
    "Application Deadline": "10/24/2024 5:00 PM Pacific",
    "Date Posted": "10/4/2024",
    "Contact": "Renita Lauderdale 805-389-2100 1301",
    "Number of Openings": "1",
    "Salary": "",
    "Add'l Salary Info": "$108,883 - $124,560 plus a $500 Master stipend and/or $1000 Doctorate Stipend",
    "Length of Work Year": "199 Days",
    "Employment Type": "Full Time",
    "contact": "Renita Lauderdale",
    "contactEmail": "rlauderdale@pleasantvalleysd.org",
    "offsiteUrl": "https://"
}
```

#### Output Fields Explanation

- `title`: Full title of the job posting.
- `district`: School district offering the position.
- `city`, `county`, `state`: Location details of the job.
- `location`: Formatted location string.
- `date`: Posting date in Unix timestamp format.
- `url`: Direct link to the job posting on Edjoin.
- `Application Deadline`: Deadline for submitting applications.
- `Date Posted`: Date when the job was posted.
- `Contact`: Contact information for inquiries.
- `Number of Openings`: Number of available positions.
- `Salary`: Base salary information (if provided).
- `Add'l Salary Info`: Additional salary details or benefits.
- `Length of Work Year`: Duration of the work year.
- `Employment Type`: Full-time, part-time, etc.
- `contact`: Name of the contact person.
- `contactEmail`: Email address for the contact person.
- `offsiteUrl`: External application URL (if applicable).

### Explore More Scrapers

If you found this Edjoin Scraper useful, be sure to check out our other powerful scrapers and actors at [memo23's Apify profile](https://apify.com/memo23). We offer a wide range of tools to enhance your web scraping and automation needs across various platforms and use cases.

### Support

- For issues or feature requests, please use the [Issues](https://console.apify.com/actors/Tar9v1qiOIvzeFWVR/issues) section of this actor.
- If you need customization or have questions, feel free to contact the author:
  - Author's website: <https://muhamed-didovic.github.io/>
  - Email: <muhamed.didovic@gmail.com>

### Additional Services

- Request customization or whole dataset: <muhamed.didovic@gmail.com>
- If you need anything else scraped, or this actor customized, email: <muhamed.didovic@gmail.com>
- For API services of this scraper (no Apify fee, just usage fee for the API), contact: <muhamed.didovic@gmail.com>

### 🤖 For AI Agents & LLM Apps

Compact reference for AI agents calling this actor via the [Apify MCP server](https://mcp.apify.com) or the Apify API (actor: `memo23/edjoin-scraper`).

**Purpose:** Scrape education-sector job listings from Edjoin.org — title, district, location, salary, deadlines, contact, and application details — by keyword/location search or from Edjoin search-result URLs.

**Minimal input:**

```json
{ "searchKeyword": "teacher", "maxItems": 50 }
```

Alternatively, pass Edjoin search-result URLs inline via `startUrls` (e.g. `{ "startUrls": [{ "url": "https://www.edjoin.org/Home/Jobs?keywords=program&location=california" }], "maxItems": 50 }`) instead of the keyword search.

**Output:** one dataset row per job posting — title, district, city, county, state, location, date, url, Application Deadline, Date Posted, Contact, Number of Openings, Salary, Add'l Salary Info, Length of Work Year, Employment Type, contact, contactEmail, offsiteUrl.

**Behaviors an agent should know:**

- Two input modes: `startUrls` (Edjoin search-result URLs) or `searchKeyword` + `searchLocation`; if `startUrls` is provided, the filter search is ignored.
- Always set `maxItems` to cap output; it defaults to 20.
- `collectDescriptionFields` fetches the full description for each job (extra requests per posting), off by default.
- `enrichEmails` (and dependent `qualifyByPayment`) are opt-in best-effort employer email enrichment, off by default.
- `maxConcurrency`, `minConcurrency`, and `maxRequestRetries` tune throughput and retries; `proxy` defaults to Apify Residential proxy.
- Pay-per-event billing — see the Pricing tab on the actor page.

### ⚠️ Disclaimer

This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by the San Joaquin County Office of Education (operator of EDJOIN / edjoin.org) or any of its affiliates. All trademarks mentioned are the property of their respective owners.

The scraper accesses only publicly available job-posting pages on edjoin.org — no authenticated endpoints, paid features, or content behind a login wall. Users are responsible for ensuring their use complies with edjoin.org's Terms of Service, applicable data-protection law (GDPR, CCPA, etc.), and any contractual obligations of their own organization.

### SEO Keywords

Edjoin scraper, scrape Edjoin, Edjoin.org scraper, Edjoin API, Apify Edjoin, education jobs scraper, teaching jobs scraper, school district jobs scraper, k-12 jobs data, teacher recruitment data, education job listings export, education job market analysis, education sector hiring data, california teaching jobs, school employment data, education recruitment intelligence

# Actor input Schema

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

URLs to start with. If provided, Search by filters will be ignored.

## `searchKeyword` (type: `string`):

Job keyword to search for (e.g. teacher).

## `searchLocation` (type: `string`):

Location to search in.

## `collectDescriptionFields` (type: `boolean`):

Whether to collect the full description for each job.

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

Maximum number of items to scrape.

## `enrichEmails` (type: `boolean`):

If enabled, tries to find a contact email for each employer by discovering the organisation's website (Clearbit) and reading its contact/about pages. Adds contactEmail + contactWebsite columns plus a detailed emailEnrichment object. Best-effort.

## `qualifyByPayment` (type: `boolean`):

Requires "Enrich with contact emails". Scans each business's website — reusing the pages already fetched for email discovery, so no extra cost or time — for payment processors and e-commerce platforms (Stripe, Shopify, PayPal, Paddle, Lemon Squeezy, WooCommerce, Square, Chargebee and more). Adds takesPayments (is this a real paying business?), paymentProcessors (which stack), stripeLiveKey (the public key if exposed) and paymentConfidence. Turn raw contacts into monetization-qualified leads. No extra charge — included with each enriched company.

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

Maximum number of pages that can be processed at the same time.

## `minConcurrency` (type: `integer`):

Minimum number of pages that will be processed at the same time.

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

Number of times the crawler will retry a failed request before giving up.

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

Specifies proxy servers that will be used by the scraper in order to hide its origin.<br><br>For details, see <a href='https://apify.com/apify/web-scraper#proxy-configuration' target='_blank' rel='noopener'>Proxy configuration</a> in README.

## Actor input object example

```json
{
  "startUrls": [],
  "searchKeyword": "teacher",
  "collectDescriptionFields": false,
  "maxItems": 20,
  "enrichEmails": false,
  "qualifyByPayment": false,
  "maxConcurrency": 100,
  "minConcurrency": 1,
  "maxRequestRetries": 20,
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# 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": [],
    "searchKeyword": "teacher",
    "proxy": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("memo23/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": [],
    "searchKeyword": "teacher",
    "proxy": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("memo23/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": [],
  "searchKeyword": "teacher",
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call memo23/edjoin-scraper --silent --output-dataset

```

## MCP server setup

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