CRDC Data Source Reference

SkillDev tools

CRDC — OCR civil rights collection for U.S. public schools; Portal families have topic-specific coverage from 2011 through 2022. Discipline, course access, harassment, restraint/seclusion by race/sex/disability/EL. Use for civil rights and equity analysis. Official evidence identifies 2013-14 as a universe collection; 2020-21 is COVID-impacted.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the CRDC Data Source Reference skill

What this skill tells your AI

The instructions your AI receives, as published by daaf-contribution-community/daaf in .claude/skills/education-data-source-crdc/SKILL.md and read by ahel’s review.

Civil Rights Data Collection (CRDC) — mandatory OCR collection measuring educational opportunity and civil rights compliance in U.S. public schools. Portal dataset families have topic-specific coverage from 2011 through 2022; use them for school discipline disparities, course access equity, harassment, restraint/seclusion, or chronic absenteeism by race, sex, disability, and English learner status. The 2013-14 collection was officially a universe collection covering 16,758 districts and 95,507 schools; this skill does not make an unverified coverage claim for 2011-12. The 2020-21 collection is COVID-impacted and not directly comparable to ordinary years.

The Civil Rights Data Collection is a mandatory biennial survey of all U.S. public schools measuring educational opportunity and civil rights compliance. It is the only national source for school-level discipline disparities, course access equity, harassment, and restraint/seclusion data disaggregated by race, sex, disability, and English learner status.

CRITICAL: Value Encoding

The Education Data Portal uses integer codes, not the string codes shown in OCR documentation. Always filter using integers.

VariableString Code (Raw)Portal Integer
Race: WhiteWH1
Race: BlackBL2
Race: HispanicHI3
Sex: MaleM1
Sex: FemaleF2

See ./references/variable-definitions.md for complete encoding tables.

What is CRDC?

The Civil Rights Data Collection is a mandatory OCR collection of public schools and districts that measures educational opportunity and civil rights compliance:

  • Collector: U.S. Department of Education, Office for Civil Rights (OCR)
  • Purpose: Enforce civil rights laws, identify discrimination, monitor equity
  • Coverage: Collection-specific; official evidence establishes 2013-14 as a universe collection. Verify 2011-12 against its own authoritative documentation rather than applying a blanket early-year label.
  • Cadence: Usually organized by school-year collection cycles, historically often biennial, but not governed by an odd/even parity rule; 2020-21 and 2021-22 are consecutive collections
  • Disaggregation: Race/ethnicity, sex, disability status, English learner status
  • History: Collected since 1968 (as Elementary and Secondary School Civil Rights Survey)
  • Portal coverage (v2 mirror, build validated 2026-08-06): Topic-specific families spanning 2011 through 2022 (content-based year range confirmed in the v2 build); year availability differs by topic
  • Available through: Education Data Portal mirrors

Reference File Structure

FilePurposeWhen to Read
civil-rights-context.mdLegal framework (Title VI, IX, Section 504, IDEA)Understanding why data is collected
data-elements.mdAll data categories and what's collectedPlanning analysis, identifying variables
collection-methodology.mdSampling, universe, timeline, reportingUnderstanding coverage limitations
variable-definitions.mdKey variables, codes, disaggregation categoriesCoding data, interpreting values
data-quality.mdKnown issues, suppression, state variationsAddressing limitations in analysis
historical-changes.mdEvolution across collection yearsTime series analysis, year comparison

Decision Trees

What CRDC data do I need?

Research topic?
├─ School discipline
│   ├─ Suspensions (ISS/OSS) → ./references/data-elements.md#discipline
│   ├─ Expulsions → ./references/data-elements.md#discipline
│   ├─ Referrals to law enforcement → ./references/data-elements.md#discipline
│   ├─ School-related arrests → ./references/data-elements.md#discipline
│   └─ Preschool suspensions → ./references/data-elements.md#discipline
├─ Restraint and seclusion
│   └─ Physical restraint, mechanical, seclusion → ./references/data-elements.md#restraint-seclusion
├─ Harassment and bullying
│   ├─ Allegations by type → ./references/data-elements.md#harassment
│   └─ Disciplined for harassment → ./references/data-elements.md#harassment
├─ Course access and enrollment
│   ├─ AP/IB courses → ./references/data-elements.md#advanced-courses
│   ├─ Gifted/talented → ./references/data-elements.md#gifted-talented
│   ├─ Math/science courses → ./references/data-elements.md#course-access
│   └─ Computer science → ./references/data-elements.md#course-access
├─ Chronic absenteeism
│   └─ Students missing 15+ days → ./references/data-elements.md#chronic-absenteeism
├─ Special populations
│   ├─ Students with disabilities (IDEA) → ./references/data-elements.md#students-with-disabilities
│   ├─ English learners → ./references/data-elements.md#english-learners
│   └─ Preschool enrollment → ./references/data-elements.md#preschool
├─ School staffing
│   ├─ Teacher experience/certification → ./references/data-elements.md#staffing
│   └─ Counselors, nurses, etc. → ./references/data-elements.md#staffing
└─ School safety
    └─ Offenses, violence, weapons → ./references/data-elements.md#school-offenses

Understanding the legal context?

Civil rights law question?
├─ Race/ethnicity discrimination → ./references/civil-rights-context.md#title-vi
├─ Sex/gender discrimination → ./references/civil-rights-context.md#title-ix
├─ Disability discrimination → ./references/civil-rights-context.md#section-504
├─ Special education services → ./references/civil-rights-context.md#idea
├─ Age discrimination → ./references/civil-rights-context.md#age-discrimination-act
└─ OCR enforcement process → ./references/civil-rights-context.md#ocr-enforcement

Data quality concerns?

Data quality issue?
├─ Missing or suppressed data → ./references/data-quality.md#suppression
├─ Definition inconsistencies → ./references/data-quality.md#definition-variation
├─ Year-to-year comparability → ./references/historical-changes.md
├─ COVID-19 impact (2020-21) → ./references/data-quality.md#covid-impact
├─ Underreporting concerns → ./references/data-quality.md#underreporting
└─ State-level variations → ./references/data-quality.md#state-variations

Quick Reference: CRDC Data Categories

Collection Years

School YearCoverage statusScale / Portal noteKey Notes
2011-12Not re-verified in this correction cyclePortal families include 2011 for some topicsConsult collection-specific authoritative documentation before generalizing
2013-14Universe16,758 districts; 95,507 schools (First Look figure; the revised target population was 95,958 schools)Official first-look evidence explicitly calls this a universe collection
2015-16Universe collection~96,000 schoolsChronic absenteeism added
2017-18Universe collection~96,000 schoolsExpanded variables
2020-21Universe collection~97,500 schoolsCOVID-impacted year
2021-22Universe collection~98,000 schools; selected Portal topics reach 2022Consecutive collection after 2020-21
2023-24No Portal data establishedNo Portal CRDC 2024 data as of the probes: original 2026-08-06 probe errored (HTTP 500; exact endpoint not recorded), and a 2026-08-07 re-probe of https://educationdata.urban.org/api/v1/schools/crdc/enrollment/2024/ returned HTTP 404 — either way zero rowsDo not infer 2024 data from the count of dataset families

Cadence: CRDC is organized by school-year collection cycles and is often described as biennial, but there is no valid odd/even-year rule. Portal year labels represent the terminal year of the school year; 2020 and 2021 are consecutive available collection labels. Re-probed 2026-08-06: chronic-absenteeism/2022/race/sex/ returned rows (HTTP 200), while a direct 2024 CRDC enrollment probe returned no rows (the original 2026-08-06 probe errored HTTP 500 with the exact endpoint not recorded; a 2026-08-07 re-probe of https://educationdata.urban.org/api/v1/schools/crdc/enrollment/2024/ returned HTTP 404).

Source verification (accessed 2026-07-21): Official 2013-14 first look, Portal endpoint catalog, and Portal bulk manifest.

Data Categories

CategoryDescriptionDisaggregation
EnrollmentStudent counts by grade levelRace, sex, disability, LEP
DisciplineSuspensions, expulsions, arrestsRace, sex, disability, LEP
Restraint/SeclusionPhysical/mechanical restraint, seclusionRace, sex, disability
HarassmentAllegations and discipline by typeRace, sex, disability
Course AccessAP, IB, math, science, CS offeringsSchool-level, enrollment by race/sex
Chronic Absenteeism15+ days missedRace, sex, disability, LEP
StaffingTeachers, counselors, nurses, etc.FTE counts, qualifications
OffensesViolence, weapons, drugs at schoolType of offense
RetentionStudents retained in gradeRace, sex, disability

Key Identifiers

IDFormatLevelExampleNotes
crdc_id12-digit stringSchool010000201705Primary CRDC identifier; always present
ncessch12-digit stringSchool010000201705NCES school ID, joins to CCD; may be null for some entries
leaid7-digit stringDistrict0100002NCES district ID, joins to CCD; always present

Note: The OCR-internal combokey (e.g., AL-0010-00002) does NOT appear as a column in Portal data. Use crdc_id or ncessch for school-level identification.

WARNING: String Type Override Required. When reading CRDC data from CSV, ncessch, leaid, and crdc_id must be read as String (pl.Utf8) via schema_overrides. Polars infers these as Int64, silently destroying leading zeros for ~19% of rows (FIPS 01-09 states: AL, AK, AZ, AR, CA, CO, CT). In R, readr::read_csv() has the identical failure mode — apply the same guard with col_types = cols(ncessch = col_character(), leaid = col_character(), crdc_id = col_character()). Parquet files preserve whatever dtype the file was written with — and that dtype is not uniformly String across CRDC files. A 2026-08-07 per-file audit found id typing is heterogeneous even within the 2020 vintage (e.g. school_characteristics all String, but enrollment_k12_2020 crdc_id and harass_bully_students_2020 all three ids are Int64). Do not assume a parquet read yields String ids — inspect the schema and normalize/cast on read. See references/data-quality.md § Identifier Typing for the per-file evidence.

Race/Ethnicity (Portal Integer Codes)

CodeCategory
1White
2Black or African American
3Hispanic/Latino of any race
4Asian
5American Indian or Alaska Native
6Native Hawaiian or Other Pacific Islander
7Two or more races
99Total

Empirically observed values: Codes 1-7 and 99 appear in CRDC data. Additional codes (8 Nonresident alien, 9 Unknown, 20 Other) are defined in the codebook but are not observed in practice for K-12 CRDC datasets. See variable-definitions.md for the full codebook listing.

Sex (Portal Integer Codes)

CodeCategory
1Male
2Female
3Non-binary/other (newer collections; rows exist but mostly contain -1 or -2 values)
99Total

Disability Status (Portal Integer Codes)

CodeCategory
0Students without disabilities
1Students with disabilities (served under IDEA)
2Students with Section 504 only
3Students not served under IDEA (includes 504-only and non-disabled)
4Students with disabilities (combined: IDEA + Section 504)
99Total

Note: Not all disability codes appear in every dataset. Enrollment data typically has [1, 2, 99]; discipline data has [0, 1, 2, 4, 99]. Verify codes against the live codebook for your specific dataset.

English Learner Status (Portal Integer Codes)

CodeCategory
1English learner (EL/LEP)
99All students

Missing Data Codes

CodeMeaningWhen Used
-1MissingData not reported by school/district
-2Not applicableItem doesn't apply to this entity
-3SuppressedData suppressed for privacy (small cell sizes)
-9Skip patternQuestion not asked in this collection year (rare; check codebook)
nullNot availableValue absent from dataset (e.g., ncessch is null for some schools)

Verify these codes against the live codebook for your specific dataset. Use get_codebook_url() from fetch-patterns.md.

Data Access

Datasets for CRDC are available via the Education Data Portal mirror system. See datasets-reference.md for canonical paths, mirrors.yaml for mirror configuration, and fetch-patterns.md for fetch code patterns including fetch_from_mirrors() and fetch_yearly_from_mirrors().

Portal bulk family inventory observed 2026-07-21 (24 families: 10 year-sharded, 14 multi-year/single-file):

Dataset familyPathTypeCodebook
Disciplinecrdc/schools_crdc_discipline_k12_{year}Yearlycrdc/codebook_schools_crdc_discipline
AP/IB Enrollmentcrdc/schools_crdc_apib_enrollSinglecrdc/codebook_schools_crdc_ap-ib-enrollment
Enrollmentcrdc/schools_crdc_enrollment_k12_{year}Yearlycrdc/codebook_schools_crdc_enrollment
Chronic Absenteeismcrdc/schools_crdc_chronic_absenteeism_{year}Yearlycrdc/codebook_schools_crdc_chronic-absenteeism
Harassment/Bullyingcrdc/schools_crdc_harass_bully_students_{year}Yearlycrdc/codebook_schools_crdc_harrassment-bullying-students
Restraint/Seclusioncrdc/schools_crdc_restraint_seclusion_students_{year}Yearlycrdc/codebook_schools_crdc_restraint-seclusion-students
Algebracrdc/schools_crdc_algebra_{year}Yearlycrdc/codebook_schools_crdc_algebra-1
AP Examscrdc/schools_crdc_ap_exams_{year}Yearlycrdc/codebook_schools_crdc_ap-exams
Retentioncrdc/schools_crdc_retention_{year}Yearlycrdc/codebook_schools_crdc_retention
SAT/ACT Participationcrdc/schools_crdc_sat_and_act_participation_{year}Yearlycrdc/codebook_schools_crdc_sat-act-participation
COVID Indicatorscrdc/schools_crdc_covid_indicatorsSinglecrdc/codebook_schools_crdc_covid_indicators
Credit Recoverycrdc/schools_crdc_credit_recoverySinglecrdc/codebook_schools_crdc_credit-recovery
Directory/Characteristicscrdc/schools_crdc_school_characteristicsSinglecrdc/codebook_schools_crdc_directory
Discipline Instancescrdc/schools_crdc_disciplineinstancesSinglecrdc/codebook_schools_crdc_discipline_instances
Dual Enrollmentcrdc/schools_crdc_dual_enrollmentSinglecrdc/codebook_schools_crdc_dual_enrollment
Harassment/Bullying Allegationscrdc/schools_crdc_harass_bully_allegationsSinglecrdc/codebook_schools_crdc_harrassment-bullying-allegations
Internet Accesscrdc/schools_crdc_internet_accessSinglecrdc/codebook_schools_crdc_internet_access
Math and Sciencecrdc/schools_crdc_mathandscienceSinglecrdc/codebook_schools_crdc_math-and-science
Offensescrdc/schools_crdc_offensesSinglecrdc/codebook_schools_crdc_offenses
Offeringscrdc/schools_crdc_offeringsSinglecrdc/codebook_schools_crdc_offerings
Restraint/Seclusion Instancescrdc/schools_crdc_restraint_seclusion_instancesSinglecrdc/codebook_schools_crdc_restraint-seclusion-instances
School Financecrdc/schools_crdc_financeSinglecrdc/codebook_schools_crdc_finance
Suspensions (Days)crdc/schools_crdc_suspensionsSinglecrdc/codebook_schools_crdc_suspensions_days
Teachers/Staffcrdc/schools_crdc_teacherSinglecrdc/codebook_schools_crdc_teachers_staff

The 24 count is the deduplicated Urban bulk family inventory, not a year, row count, or API endpoint count. The live Portal catalog separately exposed 50 CRDC endpoint templates because topic/disaggregation routes split more finely than bulk files. Family-specific year coverage varies; neither number implies CRDC 2024 data.

CRDC naming note: Some data file paths use concatenated names (e.g., disciplineinstances, mathandscience) while their codebook counterparts use underscored names (e.g., discipline_instances, math_and_science). Always use the exact paths from datasets-reference.md.

Codebooks are .xls files co-located with data in all mirrors. Use get_codebook_url() from fetch-patterns.md to construct download URLs:

from fetch_patterns import get_codebook_url
url = get_codebook_url("crdc/codebook_schools_crdc_discipline")
# get_codebook_url() is a Python helper; in R, construct the codebook URL from the
# mirror root in mirrors.yaml (codebooks are .xls files co-located with the data).
# Mirror failover: see `education-data-query/references/fetch-patterns.md` (R pattern).
config <- yaml::read_yaml("mirrors.yaml")
mirror <- config$mirrors[[1]]
url <- paste0(mirror$root_url, "/", "crdc/codebook_schools_crdc_discipline", ".xls")

Truth Hierarchy: When interpreting variable values, apply this priority:

  1. Actual data file (what you observe in the parquet/CSV) -- this IS the truth
  2. Live codebook (.xls in mirror) -- authoritative documentation, may lag
  3. This skill documentation -- convenient summary, may drift from codebook

If this documentation contradicts the codebook, trust the codebook. If the codebook contradicts observed data, trust the data and investigate.

Filtering

import polars as pl

# Filter to a single state (California) and disaggregated race groups
df = df.filter(
    (pl.col("fips") == 6) &       # California
    (pl.col("race") < 99)          # Exclude totals row
)

# Filter to specific demographic intersection
df = df.filter(
    (pl.col("race") == 2) &        # Black students
    (pl.col("sex") == 99) &         # Both sexes (total)
    (pl.col("disability") == 99)    # All disability statuses
)
library(dplyr)

# Filter to a single state (California) and disaggregated race groups
df <- df |> filter(
    (fips == 6) &       # California
    (race < 99)          # Exclude totals row
)

# Filter to specific demographic intersection
df <- df |> filter(
    (race == 2) &        # Black students
    (sex == 99) &         # Both sexes (total)
    (disability == 99)    # All disability statuses
)

Common Pitfalls

PitfallIssueSolution
Using string codesPortal uses integers, not stringsrace == 2 not race == "BL"
Raw countsDifferent enrollment sizesUse rates per 100/1000 students
Collection cadenceAssuming annual data or applying an odd/even parity ruleCheck topic-specific collection labels; 2020 and 2021 are consecutive
COVID year2020-21 not comparableFlag or exclude from trends
SuppressionSmall cell suppressionCheck suppression rates first
Coverage historyApplying one sampling label to both early collections2013-14 is an official universe collection; verify 2011-12 separately
Definition driftVariables change over timeCheck codebooks for each year
Forgetting code 99Including totals in calculationsFilter race < 99 for disaggregated analysis
CSV type inferencePolars and readr infer ncessch/leaid/crdc_id as integer, destroying leading zerosPython: schema_overrides={"ncessch": pl.Utf8, "leaid": pl.Utf8, "crdc_id": pl.Utf8}; R: readr::read_csv(..., col_types = cols(ncessch = col_character(), leaid = col_character(), crdc_id = col_character()))

Equity Analysis Framework

CRDC data is designed for civil rights analysis. Key analytical approaches:

Disparity Ratios

import polars as pl

# Calculate discipline disparity using Portal integer codes
def discipline_disparity(df, discipline_var, group_a, group_b):
    """
    Calculate risk ratio between two groups.
    Value > 1 indicates group_a has higher rate.

    Args:
        df: DataFrame with CRDC data
        discipline_var: Column with discipline counts
        group_a: Integer race code (e.g., 2 for Black)
        group_b: Integer race code (e.g., 1 for White)

    Example:
        # Black vs White OSS disparity
        disparity = discipline_disparity(df, 'students_susp_out_sch_single', 2, 1)
    """
    # Filter to each group (using integer codes)
    df_a = df.filter(pl.col('race') == group_a)
    df_b = df.filter(pl.col('race') == group_b)

    # Calculate rates
    rate_a = df_a.select(pl.col(discipline_var).sum()).item() / \
             df_a.select(pl.col('enrollment_crdc').sum()).item()
    rate_b = df_b.select(pl.col(discipline_var).sum()).item() / \
             df_b.select(pl.col('enrollment_crdc').sum()).item()

    return rate_a / rate_b

# Example: Black (race=2) vs White (race=1) disparity
# disparity = discipline_disparity(df, 'students_susp_out_sch_single', 2, 1)
library(dplyr)

# Calculate discipline disparity using Portal integer codes.
# Risk ratio between two groups; value > 1 indicates group_a has a higher rate.
# Example: Black (race=2) vs White (race=1) OSS disparity
discipline_var <- "students_susp_out_sch_single"
group_a <- 2  # Black
group_b <- 1  # White

# Filter to each group (using integer codes)
df_a <- df |> filter(race == group_a)
df_b <- df |> filter(race == group_b)

# Calculate rates
rate_a <- sum(df_a[[discipline_var]], na.rm = TRUE) /
  sum(df_a$enrollment_crdc, na.rm = TRUE)
rate_b <- sum(df_b[[discipline_var]], na.rm = TRUE) /
  sum(df_b$enrollment_crdc, na.rm = TRUE)

disparity <- rate_a / rate_b

Composition vs. Representation

  • Composition: What share of suspended students are Black?
  • Representation: Are Black students suspended at higher rates than enrollment share?

Risk Ratios

  • Compare discipline/outcome rates across groups
  • Adjust for school-level factors when appropriate

Related Data Sources

SourceRelationshipWhen to Use
education-data-source-ccdSchool/district characteristicsLinking CRDC to school demographics, locale, Title I status (join on ncessch or leaid)
education-data-source-edfactsAssessment outcomesComparing discipline patterns to academic outcomes
education-data-explorerParent discovery skillRouting questions to mirror CRDC dataset files and variables
education-data-queryData fetchingDownloading CRDC parquet/CSV files from mirrors
education-data-contextGeneral interpretationEducation data interpretation and citation generation

Topic Index

Shortened here. Read the whole file on GitHub.

Signals

GitHub stars
235
Forks
34
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
education-data-source-crdc
Source
github.com/daaf-contribution-community/daaf