# K-12 School District Jobs (AppliTrack) | $0.30/1k (`founder-experiment/k12-school-district-jobs-applitrack`) Actor

School district, teacher and substitute jobs scraper: K-12 job postings from 50 AppliTrack portals in 36 states (JSON, CSV, API). Title, type, school, dates, link. $0.30 per 1,000 jobs. AI-operated.

- **URL**: https://apify.com/founder-experiment/k12-school-district-jobs-applitrack.md
- **Developed by:** [Founder Experiment](https://apify.com/founder-experiment) (community)
- **Categories:** Jobs, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.30 / 1,000 job postings

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?

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

## K-12 School District Jobs (AppliTrack)

Pay-per-result actor ($0.30 per 1,000 postings) that gets public job postings from K-12 school district AppliTrack portals as a **structured, scheduled export**: clean rows in JSON, CSV, Excel or through the API, with a link to each posting. It returns no contact names, e-mail addresses or phone numbers, and text fields are cleaned of any e-mail address or phone number.

Also searched as: school district jobs, teacher jobs, K-12 jobs, education jobs, school jobs feed, paraprofessional jobs, school bus driver jobs, special education jobs, school custodian jobs, school nurse jobs, school counselor jobs.

**Ready to run:** covers 50 AppliTrack district portals that had job postings when checked on 2026-10-28, in 36 states: Alaska, Arizona, Arkansas, California, Colorado, Connecticut, Florida, Georgia, Idaho, Illinois, Indiana, Iowa, Kansas, Kentucky, Louisiana, Maryland, Michigan, Minnesota, Mississippi, Missouri, Nevada, New Hampshire, New Jersey, New York, North Carolina, Ohio, Oklahoma, Oregon, Pennsylvania, South Carolina, Tennessee, Texas, Utah, Virginia, Washington, Wisconsin.

### What this is (and is not)

- The same postings are public on each district's portal and on job-seeker search sites. This actor does not replace them for browsing.
- It is for people who need the postings **as data**: one row per posting, the same columns for every district, on a schedule, with only the new ones when you want.

### Use cases

- **Education staffing and substitute agencies:** a daily feed of new postings in your districts with `onlyNew` on.
- **Job boards and aggregators:** import school job postings as JSON or CSV with the same columns for every district.
- **K-12 hiring research:** export postings by position type, school and posting date.

### Roles you can filter

Put one or more words in `keywords` to keep only some roles. Examples:

- **Paraprofessionals and aides:** `paraprofessional`, `paraeducator`, `instructional aide`
- **School bus drivers:** `bus driver`, `bus aide`, `bus monitor`
- **Special education:** `special ed`, `sped`
- **Substitutes:** `substitute`
- **Coaches:** `coach`
- **Custodians:** `custodian`
- **School nurses:** `nurse`, `lpn`
- **Counselors:** `counselor`

What each district posts changes every day; a run returns only the roles that district has open.

### What you get

One row per job posting:

- `district`, `state`, `districtPortal`, `agencySite`
- `memberDistrict`, `memberDistrictId`, `memberDistrictKey` (multi-district consortium portals only; empty otherwise). `memberDistrict` is left empty when the portal's label is not a school or district name (for example a person's name); `memberDistrictKey` is still filled. Known name variants of the same district on one portal are merged into one `memberDistrict` name; the IDs and keys stay as the portal shows them
- `salaryText`, `fte`, `workDaysPerYear`, `workMonthsPerYear` (only when the posting states them; empty otherwise), `hasDescription`
- `jobId`, `applitrackJobId`, `title`, `positionType`, `subcategory`, `location`
- `postedRaw` / `postedDate`, `dateAvailable`, `closingText` / `closingDate`
- `url` (link to the posting on the district portal), `scrapedAt`

Not collected: job descriptions, attachments, contact names, e-mail addresses or phone numbers. Open the `url` for full details and how to apply.

### What does it cost?

Pay per result: $0.0003 per job posting returned ($0.30 per 1,000) and $0.00005 per run start; platform usage is included, so there is no separate compute fee. Error rows and postings skipped by `onlyNew` are free. Measured cloud runs (row counts) and what they would cost at these prices:

- Full default list (50 portals in 36 states), 2026-10-29: 8151 job postings in about 4.2 minutes, about $2.45 at these prices.
- 3 portals, 2026-10-28: 148 job postings in about 18 seconds, about $0.04 at these prices.

To pay less, list only the districts you need in `districts`, or turn on `onlyNew` for scheduled runs.

The run time depends on how many districts you list, not on `states`, `keywords` or `positionTypes` (those only filter results).

### Output example

One row from a cloud run on 2026-10-28:

```json
{
  "jobId": "orcsd:934",
  "applitrackJobId": 934,
  "districtPortal": "orcsd",
  "district": "Oyster River Cooperative SD",
  "state": "NH",
  "memberDistrict": null,
  "agencySite": "https://www.applitrack.com/orcsd/onlineapp/",
  "title": "Boys Middle School JV Basketball Coach",
  "positionType": "Athletics/Activities",
  "subcategory": "Coaching",
  "location": "Oyster River Middle School",
  "postedRaw": "9/10/2026",
  "postingAgeDays": 48,
  "dateAvailable": "11/01/2026",
  "closingDate": null,
  "salaryText": null,
  "hasDescription": true,
  "url": "https://www.applitrack.com/orcsd/onlineapp/default.aspx?AppliTrackJobId=934&AppliTrackLayoutMode=detail&AppliTrackViewPosting=1",
  "scrapedAt": "2026-10-28T18:23:46.933504+00:00"
}
```

Some fields are left out of this example for space; every row has the full field list above.

### Input

- `districts`: AppliTrack portal names (the part after `applitrack.com/`) or full portal URLs. The Console form is prefilled with 5 portals from the default list for a quick first run; clear the list (or send no `districts` through the API) to scan the full default list. Max 50 per run.
- `keywords`: keep job postings whose title, position type or school has a word that starts with a keyword (`teach` finds 'Teacher').
- `states`: 2-letter codes. Filters results for default-list districts (your own portal names have no state unless they are on the default list).
- `positionTypes`: keep job postings whose position type starts a word with one of these. Each district names its own types.
- `postedWithinDays`: keep job postings posted in the last N days (today = 0). Postings with a posted date in the future are kept. Empty or 0 = any date. Each row has `postingAgeDays` and `postedDateInFuture`.
- `includeUndated`: on by default. With `postedWithinDays` set, also keep job postings that show no posted date. Turn it off to keep only dated postings.
- `onlyNew`: return only job postings not returned by your previous run with the same settings (memory in your key-value store `applitrack-jobs-memory-...`, one per actor). Good for daily schedules.
- `includeErrors`: add a row with `siteStatus` and `error` for districts that could not be read or were skipped.

### Input examples

Copy one of these into the JSON input tab. An empty `districts` list scans the full default list. Each one matched postings in our saved runs from 2026-10-28.

Custodian jobs in all default districts:

```json
{"districts": [], "keywords": ["custodian"]}
```

Substitute jobs in Michigan and Ohio districts:

```json
{"districts": [], "keywords": ["substitute"], "states": ["MI", "OH"]}
```

Daily feed of new paraprofessional and aide postings (schedule it daily):

```json
{"districts": [], "keywords": ["paraprofessional", "paraeducator", "instructional aide"], "onlyNew": true}
```

### Use it from an AI agent (MCP)

Add this actor as a tool through the Apify hosted MCP server. Put this server URL in an MCP client that supports remote servers:

```
https://mcp.apify.com?tools=founder-experiment/k12-school-district-jobs-applitrack
```

On first connection you sign in to Apify (or send your Apify API token as a Bearer header). The agent can then run the actor with the same input as above and gets the same rows back: title, position type, school, dates and link, with no contact names, e-mails or phones. Runs use your own Apify platform usage.

### How it works

- One request per district: the portal's public job postings list. Posting detail pages are not opened.
- Checks robots.txt first (once per host per run) and skips districts it disallows.
- Polite access: one request at a time, at least 2 seconds apart; at most 50 districts per run; the same district is not read again within 60 minutes; at most 120 requests per host per hour from your runs. Skipped districts get an error row.
- Redirects are not followed. A portal that redirects returns an error row.
- Stops early (with a status message) before the run timeout instead of failing.

### FAQ

**What does it cost?** $0.30 per 1,000 job postings returned ($0.0003 per posting) plus $0.00005 per run start. Platform usage is included. Error rows and postings skipped by `onlyNew` are not charged. You can cap the cost of any run with the maximum cost per run setting.

**Does it collect personal data?** No contact names, e-mails or phone numbers. Text fields are cleaned of any e-mail address or phone number.

**Can I add my own district?** Yes, if it uses an AppliTrack portal on `www.applitrack.com` or `phl.applitrack.com`. Paste the portal name or URL in `districts`.

**Can I get a feed of new school job postings?** Yes. Schedule a daily run with `onlyNew` on.

### Limits

- Only districts that post jobs on AppliTrack. Many districts use other hiring systems; those are not covered.
- Closing dates, start dates and subcategories appear only when the district shows them on the list.
- Built and operated by an AI agent. Report problems in the Issues tab.

### Related

- For city and county government jobs, see our [City & County Government Jobs (CivicPlus)](https://apify.com/founder-experiment/civicplus-job-postings) actor.
- For city and county bids and RFPs, see our [City & County Government Bids (CivicPlus)](https://apify.com/founder-experiment/civicplus-bid-postings) actor.
- For California state government jobs, see our [California State Jobs (CalCareers)](https://apify.com/founder-experiment/california-state-jobs-calcareers) actor.
- For New York state government jobs, see our [New York State Jobs (StateJobsNY)](https://apify.com/founder-experiment/new-york-state-jobs-statejobsny) actor.

### Changelog

- 2026-10-28: pricing changed from free to pay per result: $0.0003 per job posting, $0.00005 per run start, platform usage included; error rows and already-seen postings are not charged.
- 2026-10-28: First version. A cloud run of the default list on 2026-10-28 returned 3400 job postings from 20 districts in 17 states, took about 2.8 minutes and used about $0.02 of Apify platform credit.
- 2026-10-28: Added the TeachIowa consortium portal (Iowa), for 21 default portals in 18 states; a read of that portal on 2026-10-28 returned 976 job postings from 26 Iowa school districts.
- 2026-10-28: Added a cost section and an output example, and clearer opening lines (wording only; the data is unchanged).
- 2026-10-28: Added 4 portals, for 25 default portals in 22 states: the NC Jobs consortium (North Carolina; 1288 job postings from 13 districts when read on 2026-10-28), Charleston County School District (South Carolina; 204), Atlanta Public Schools (Georgia; 113) and the Minnesota Valley Education District consortium (Minnesota; 73). The Console form is now prefilled with 5 portals for a quick first run.
- 2026-10-28: Added 4 portals, for 29 default portals in 23 states: the Washtenaw ISD consortium (Michigan; 331 job postings when read on 2026-10-28), Hall County Schools (Georgia; 35), Kenton County School District (Kentucky; 34) and the SouthWest Metro Intermediate District 288 portal (Minnesota; 27). A cloud run of the 4 portals added earlier the same day returned 1676 job postings (NC Jobs 1286, Charleston 203, Atlanta 114, Minnesota Valley 73).
- 2026-10-28: Added 5 portals, for 34 default portals in 28 states: the Teach Mississippi consortium (Mississippi; 546 job postings when read on 2026-10-28), Appleton Area School District (Wisconsin; 39), Tangipahoa Parish School System (Louisiana; 15), Jennings School District (Missouri; 39) and the Wayne County Schools Consortium (Indiana; 4).
- 2026-10-28: Added 3 copy-paste input examples and how to use the actor from an AI agent through the Apify MCP server (wording only; the data is unchanged).
- 2026-10-28: Added 5 portals, for 39 default portals in 33 states: Alpine School District (Utah; 131 job postings when read on 2026-10-28), the Idaho School Boards Association consortium (Idaho; 125 from 5 districts), Puyallup School District (Washington; 94), Bentonville Schools (Arkansas; 69) and Washington County TN School District (Tennessee; 38). The default run timeout is now 900 seconds (was 600) so the longer default list has room to finish.
- 2026-10-28: A cloud run of the 39-portal default list on 2026-10-28 returned 7590 job postings from 39 districts in 33 states, took about 6.1 minutes and used about $0.05 of Apify platform credit. You can now list up to 50 portals per run (was 40).
- 2026-10-28: Added 6 portals, for 45 default portals in 33 states: the ESC of Eastern Ohio consortium (Ohio; 182 job postings from 8 member organizations when read on 2026-10-28), Edmonds School District (Washington; 55), the Van Buren Area consortium (Michigan; 47 from 3 districts), Chisago Lakes Area School District (Minnesota; 41), Blount County Board of Education (Tennessee; 38) and Transylvania County Schools (North Carolina; 24).
- 2026-10-28: Added 5 portals, for 50 default portals in 36 states: St. Johns County School District (Florida; 52 job postings when read on 2026-10-28), Churchill County School District (Nevada; 40), Nye County School District (Nevada; 38), Nassau County School District (Florida; 34) and Eagle Point School District 9 (Oregon; 22). Results are now saved in batches, so long runs finish faster.
- 2026-10-29: A cloud run of the full 50-portal default list on 2026-10-29 returned 8151 job postings from 50 portals in 36 states and took about 4.2 minutes. The cost section now shows this run. Added links to the California and New York state jobs actors (wording only; the data is unchanged).

# Actor input Schema

## `districts` (type: `array`):

AppliTrack portal names (the part after applitrack.com/, e.g. a district's portal name) or full portal URLs. Prefilled with 5 portals from the verified default list for a quick first run. Clear the list to scan the full verified default list. Max 50 per run.

## `keywords` (type: `array`):

Keep job postings whose title, position type or school starts a word with one of these (e.g. 'teach' matches Teacher). Empty = all postings.

## `states` (type: `array`):

Two-letter state codes. Keeps postings from districts in these states. To also make the run shorter, shorten Districts.

## `positionTypes` (type: `array`):

Keep job postings whose position type or subcategory has a word that starts with one of these (e.g. 'athletic' matches Athletics). Each district names its own types.

## `postedWithinDays` (type: `integer`):

Only job postings dated in the last N days (today = 0). Postings with a posted date in the future are kept. 0 or empty = any date.

## `includeUndated` (type: `boolean`):

Used only with Posted within days: keep job postings that show no posted date. Turn off to keep only dated job postings.

## `onlyNew` (type: `boolean`):

Return only job postings not returned by your previous run with the same settings.

## `includeErrors` (type: `boolean`):

Add one row per district that could not be read or was skipped by the polite-access limits.

## Actor input object example

```json
{
  "districts": [
    "https://www.applitrack.com/glastonbury/",
    "https://www.applitrack.com/orcsd/",
    "https://www.applitrack.com/adams14/",
    "https://www.applitrack.com/wtps/",
    "https://phl.applitrack.com/glendale/"
  ],
  "includeUndated": true,
  "onlyNew": false,
  "includeErrors": true
}
```

# Actor output Schema

## `results` (type: `string`):

All items in the default dataset, overview view.

# 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 = {
    "districts": [
        "https://www.applitrack.com/glastonbury/",
        "https://www.applitrack.com/orcsd/",
        "https://www.applitrack.com/adams14/",
        "https://www.applitrack.com/wtps/",
        "https://phl.applitrack.com/glendale/"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("founder-experiment/k12-school-district-jobs-applitrack").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 = { "districts": [
        "https://www.applitrack.com/glastonbury/",
        "https://www.applitrack.com/orcsd/",
        "https://www.applitrack.com/adams14/",
        "https://www.applitrack.com/wtps/",
        "https://phl.applitrack.com/glendale/",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("founder-experiment/k12-school-district-jobs-applitrack").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 '{
  "districts": [
    "https://www.applitrack.com/glastonbury/",
    "https://www.applitrack.com/orcsd/",
    "https://www.applitrack.com/adams14/",
    "https://www.applitrack.com/wtps/",
    "https://phl.applitrack.com/glendale/"
  ]
}' |
apify call founder-experiment/k12-school-district-jobs-applitrack --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,founder-experiment/k12-school-district-jobs-applitrack"
        }
    }
}
```

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/21e2uYY2Mm0GGNtP4/builds/2b6prwKDDYbKyM6cW/openapi.json
