# NCES School & District Data — CCD, LEA, EDGE (`commanding_hotdog/nces-k12-schools-districts-intelligence`) Actor

Download official NCES CCD K-12 school and district data with multi-year support, LEA relationships, raw source fields, EDGE geography, ArcGIS boundaries, release tracking, and change detection.

- **URL**: https://apify.com/commanding\_hotdog/nces-k12-schools-districts-intelligence.md
- **Developed by:** [qingwa](https://apify.com/commanding_hotdog) (community)
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.15 / actor start

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

## NCES K-12 Schools & Districts Intelligence

Apify Actor for reproducible, auditable public-school and LEA intelligence built from official NCES CCD data, with optional NCES EDGE geography and ArcGIS district geometry.

### What it returns

The Actor can return:

- public K-12 school records;
- public LEA/district records;
- school-to-LEA relationship records;
- multiple school years in one request;
- preliminary, final, or revised release selection;
- normalized fields plus complete official source rows;
- optional EDGE geographic enrichment;
- optional ArcGIS district geometry;
- year-over-year `ADDED`, `REMOVED`, and `CHANGED` records;
- `RUN_SUMMARY` in the default Key-Value Store.

The default Dataset contains one JSON item per selected entity or relationship. Official data is never silently discarded: normalized fields are separate from `raw_record`, and component-level rows are retained in `raw_records_by_component`.

### Minimal input

```json
{
  "entity_types": ["schools"],
  "school_years": ["2023-24"],
  "ncessch_ids": ["010000500870"],
  "include_raw_record": true,
  "max_results": 100
}
```

For a joined school/district/relationship result:

```json
{
  "entity_types": ["schools", "districts", "relationships"],
  "school_years": ["2023-24", "2024-25"],
  "states": ["AL"],
  "include_raw_record": true,
  "include_edge": true,
  "include_geometry": true,
  "output_mode": "normalized",
  "max_results": 100
}
```

The exact accepted fields, enumerations, and limits are defined in `.actor/input_schema.json` and are validated again at runtime. A schema-valid request can still produce an explicit business failure when an official source is unavailable or a requested release is not found.

### Output modes

- `normalized`: stable normalized fields plus source and raw-field metadata;
- `raw`: normalized identity and complete original component rows;
- `flat`: flattened output for spreadsheet-oriented workflows;
- `summary`: a compact run-level summary item.

Every successful run writes `RUN_SUMMARY` to the default Key-Value Store. It includes status, record counts, source metadata, release metadata, component success/failure, warnings, truncation state and reasons, and change counts. If changes are enabled, the `CHANGES` key contains the change records.

### Data integrity and semantics

- School identity is `NCESSCH + school_year`.
- District identity is `LEAID + school_year`.
- Relationship identity is `NCESSCH + LEAID + school_year`.
- CCD values are not overwritten by EDGE values; enrichment uses explicit `edge_*` fields.
- School and district EDGE source labels are kept distinct.
- Missing, suppressed, not applicable, not reported, and numeric zero values are not collapsed into one value.
- A limit is reported as truncation only when records were actually cut off. Targeted ID early-stop is reported separately as `target_early_stop`.
- Empty results, component failures, partial success, and source errors remain visible in the summary; they are not reported as ordinary successful data runs.

### Official sources

- NCES CCD Data Tables API: <https://nces.ed.gov/ccd/datatables/api>
- NCES CCD downloadable files: <https://nces.ed.gov/ccd/data.html>
- NCES EDGE geospatial data: <https://nces.ed.gov/programs/edge/>
- ArcGIS geometry is queried only when geometry enrichment is requested and the district identifier is available.

Each downloaded source retains its official URL, filename, SHA-256, school year, release version/status and retrieval metadata. The Actor uses bounded retries for 429, 5xx and recoverable network failures; permanent HTTP errors fail explicitly.

### Local verification

This project is tested before deployment and does not require an Apify run for the local acceptance matrix:

```bash
pytest -q
python3 -m compileall -q src tests scripts
python3 scripts/run_local_acceptance.py
python3 scripts/run_local_resource_benchmark.py
python3 scripts/run_local_merge_benchmark.py
python3 scripts/run_local_docker_contract.py
python3 -m json.tool .actor/actor.json >/dev/null
python3 -m json.tool .actor/input_schema.json >/dev/null
python3 -m json.tool .actor/output_schema.json >/dev/null
apify validate-schema .actor/input_schema.json
```

The local suite covers output modes, multi-year behavior, changes, partial failures, truncation, invalid input, empty results, release selection, retries, download limits, ZIP/CSV edge cases, EDGE/ArcGIS no-match behavior, source hashes, Docker startup, and representative synthetic resource measurements.

The resource reports are engineering measurements on synthetic CCD-like fixtures. They are not a nationwide cost estimate and must not be used alone to set pricing.

### Limitations

- Cross-run change detection requires a previous baseline supplied through the programmatic pipeline; a previous Dataset is not automatically imported as a baseline.
- Full nationwide requests can require substantial download time and storage because official CCD components are distributed as downloadable files.
- `max_results` is a safety limit, not a guarantee that every source file is scanned when targeted identifiers allow deterministic early stopping.
- EDGE and ArcGIS enrichment is optional and can legitimately have no matching geography for a valid CCD entity.
- Official-source availability, release catalog changes, and upstream file revisions can affect a run; those conditions are recorded in `RUN_SUMMARY` rather than hidden.

### Release status

The code and local test suite are maintained separately from Store visibility, pricing, and public listing configuration. Deployment is performed only after the local gate passes, followed by one minimal online regression that reads the Run, Dataset, and `RUN_SUMMARY` instead of relying on process exit code alone.

# Actor input Schema

## `entity_types` (type: `array`):

Choose schools, districts, or year-aware school-district relationships.

## `school_years` (type: `array`):

NCES school years such as 2023-24.

## `output_mode` (type: `string`):

Choose normalized, raw, flat, or summary output.

## `include_raw_record` (type: `boolean`):

Keep complete official source fields in each output record.

## `include_edge` (type: `boolean`):

Add optional EDGE geographic enrichment.

## `include_geometry` (type: `boolean`):

Add optional district boundary geometry.

## `include_changes` (type: `boolean`):

Compare current records with the supplied previous\_records baseline.

## `previous_records` (type: `array`):

Optional prior normalized records used for added, removed, and changed detection.

## `release_status` (type: `string`):

Select official NCES release status.

## `release_version` (type: `string`):

Optional exact official release version, for example v.2a.

## `charter_status` (type: `string`):

Optional official charter status code

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

Optional two-letter state abbreviations.

## `state_fips` (type: `array`):

Optional two-digit state FIPS codes.

## `counties` (type: `array`):

Optional county names.

## `county_fips` (type: `array`):

Optional five-digit county FIPS codes.

## `ncessch_ids` (type: `array`):

Optional 12-digit school identifiers used for early component filtering.

## `leaid_ids` (type: `array`):

Optional 7-digit district identifiers used for early component filtering.

## `max_results` (type: `integer`):

Maximum number of output records.

## `max_results_per_state` (type: `integer`):

Optional per-state output cap.

## `max_pages` (type: `integer`):

Optional API pagination cap.

## `max_runtime_seconds` (type: `integer`):

Maximum permitted runtime for a run.

## Actor input object example

```json
{
  "entity_types": [
    "schools"
  ],
  "school_years": [
    "2023-24"
  ],
  "output_mode": "normalized",
  "include_raw_record": true,
  "include_edge": false,
  "include_geometry": false,
  "include_changes": false,
  "release_status": "final",
  "max_results": 10000,
  "max_pages": 100,
  "max_runtime_seconds": 300
}
```

# Actor output Schema

## `defaultDataset` (type: `string`):

No description

## `runSummary` (type: `string`):

No description

## `runSummaryStatus` (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("commanding_hotdog/nces-k12-schools-districts-intelligence").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("commanding_hotdog/nces-k12-schools-districts-intelligence").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 commanding_hotdog/nces-k12-schools-districts-intelligence --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,commanding_hotdog/nces-k12-schools-districts-intelligence"
        }
    }
}
```

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/nz1EcZ6jhlTMi70h8/builds/Z4M0rfixY6Zn6iDvI/openapi.json
