The core compliance data: one record per U.S. jurisdiction (50 states + DC).
GET /api/v1/compliance/states
Returns a summary record for every jurisdiction. The summary deliberately omits the long-form prose fields (special_notes, withdrawal_process, etc.) to keep the payload small for list views.
curl -H "Authorization: Bearer $TOKEN" https://homeschoolfox.com/api/v1/compliance/states
Response (truncated):
{
"data": [
{
"abbreviation": "AK",
"name": "Alaska",
"compulsory_age_range": "7-16",
"notice": { "required": false, "type": "none", "recipient_label": null, "frequency": "none", "approval_required": false },
"requirements": { "hours_per_year": null, ... }
},
...
],
"meta": { "api_version": "v1", "count": 51 }
}
GET /api/v1/compliance/states/:abbreviation
The full record for one jurisdiction. The :abbreviation is the standard two-letter postal code, case-insensitive.
curl -H "Authorization: Bearer $TOKEN" https://homeschoolfox.com/api/v1/compliance/states/MO
Response (excerpted):
{
"data": {
"abbreviation": "MO",
"name": "Missouri",
"compulsory_age_range": "7-17",
"notice": { "required": false, "type": "none", "recipient_label": null, "frequency": "none", "approval_required": false },
"requirements": {
"hours_per_year": 1000,
"core_hours_per_year": 600,
"secondary_hours_per_year": null,
"secondary_hours_start_grade": null,
"days_per_year": null,
"hours_or_days": null,
"hours_per_day": null,
"subjects": ["reading", "math", "social studies", "language arts", "science"]
},
"assessment": { "type": "none", "frequency": "none", "description": "...", "allows_portfolio": null },
"portfolio": { "required": true, "records_required": true, "description": "..." },
"reporting": { "frequency": "none" },
"esa": { "program_name": "MOScholars (...)", "amount_cents": 637500, "homeschool_access": "status_change", ... },
"tax_credit_summary": null,
"umbrella_summary": null,
"filing_deadlines": {},
"required_documents": [],
"special_notes": "...",
"withdrawal_process": null,
"source_urls": [
{ "name": "HSLDA", "url": "https://hslda.org/legal/missouri" },
{ "name": "Families for Home Education (FHE-MO)", "url": "https://fhe-mo.org/" }
],
"editorial": {
"schema_version": "1",
"last_verified_at": "2026-05-12",
"needs_review": false,
"verification_notes": null
}
},
"meta": {
"api_version": "v1",
"version": 1,
"released_at": "2026-05-12",
"git_sha": "ec3bc5a2"
}
}
States that raise the hour requirement by grade
Four states set a higher annual hour floor for older students, and they do not agree on where the line falls. requirements.secondary_hours_start_grade is the first grade at which secondary_hours_per_year replaces hours_per_year:
| State | hours_per_year |
secondary_hours_per_year |
secondary_hours_start_grade |
Authority |
|---|---|---|---|---|
| MT | 720 | 1080 | 4 | MCA 20-1-301(2) |
| NE | 1032 | 1080 | 9 | 92 NAC 13 § 004.01, with Neb. Rev. Stat. 79-101 |
| NY | 900 | 990 | 7 | 8 NYCRR 100.10(f)(2) |
| PA | 900 | 990 | 7 | 24 P.S. § 13-1327.1(c) |
Do not assume grade 7. Both fields are null for the 47 states with no split.
Reading esa
esa.homeschool_access says whether a homeschooling family can reach the program's money (open, status_change, closed, unclear). Do not infer it from amount_cents: an amount may be absent because no figure is verified, and present on a program that pays out only to families who first leave the homeschool track. The esa_programs endpoint carries the full field notes.
esa.reporting.deadline_keys names the entries in this state's filing_deadlines that belong to the ESA program rather than to homeschooling. A client rendering a homeschool compliance calendar should exclude them — Arizona's four quarterly dates bind ESA contract holders, and an Arizona homeschooler files an affidavit once and reports nothing after.
Reading reporting
reporting.frequency is none, annual, quarterly, as_needed, or at_specified_grades. It covers a report of progress or results. The notice of intent lives in notice and never counts here. at_specified_grades means results are filed only in the grades listed in reporting.grades (CO, ND, WV), and nothing is filed in other years. reporting.due carries a statewide due date where the statute sets one. Both keys are absent for other states.
Reading notice
notice.required alone does not tell you what a family owes.
notice.frequency—annual,once,on_withdrawal,none, orunknown. Eleven states file once and never again (AL, AZ, FL, HI, KS, NC, NV, OR, SD, UT, WV). Do not assume annual.notice.type— now alsocounty,regionalandschool. Four states file somewhere other than a district or the state: AZ and MT with the county school superintendent, OR with a regional education service district, HI with the child's own school principal.notice.recipient_label— a written phrase that overrides the office implied bytype, for a recipient the enum cannot name. Mississippi's county school attendance officer is the case it exists for.notice.form_labelandnotice.form_note: set when the filing is a form an office supplies, not a letter the parent writes. Alabama is the case they exist for: the parent files the church school enrollment form the superintendent provides, countersigned by the church school's administrator (Ala. Code 16-28-7). North Carolina also carries them, because DNPE takes the notice only through its online system. A client that offers a letter template should skip it whenform_labelis present.notice.approval_required—truein MA and RI, where the program must be approved before instruction begins. Filing is not permission, and a family that starts on filing day can be found truant.
Two states carry required: false with a type set and frequency: "on_withdrawal": NH and WY ask for nothing to begin homeschooling, but require notice when a child is withdrawn from public school: a declaration of home education in NH (RSA 193-A:3), and in WY a notice to the district or, failing that, an in-person meeting to sign written consent (W.S. 21-4-102(c)). A client that renders required: false as "no paperwork" is wrong for exactly those two.
Reading portfolio and assessment
portfolio.required means a portfolio of student work specifically, and is deliberately narrow: it gates the portfolio guide on the site. Seventeen more states mandate records without mandating a portfolio (attendance registers, academic records, retained test results), and those carry portfolio.records_required: true with required: false. A client that reads required: false as "no recordkeeping duty" is wrong in CA, CO, GA, HI, IN, KY, ME, MN, MT, NC, ND, NY, OR, RI, VT, WA and WV. records_required is always true where required is true.
assessment.allows_portfolio matters only where type is "choice", and says whether a portfolio is among the methods the statute accepts. It is false in CO, VA and WA, where a portfolio satisfies nothing on its own: Colorado takes a test or an evaluation by a qualified person, Virginia a test composite or an evaluation, Washington an approved standardized test or a written assessment by a certificated person. Do not render a generic "testing, portfolio, or evaluation" for every choice state.
States that set both hours and days
Seven states carry a value in both hours_per_year and days_per_year, and they do not all mean the same thing. requirements.hours_or_days says which:
true— either figure satisfies the statute on its own. PA (24 P.S. § 13-1327.1(c); PDE: "Either 180 days or 900 hours of instruction are required") and WA (RCW 28A.195.010(1): "no less than one hundred eighty school days or the equivalent in annual minimum instructional hour offerings").false— both bind. NY puts the 180 days and the 900/990 hours under one stem in 8 NYCRR 100.10(f) with no "or" and no election. CO, GA, ND and RI express one rule as a daily rate across a day count, so their annual hours are derived rather than an alternative.
Do not render the two figures as a joint requirement without checking this flag. It is null for the 44 states that set only one figure or neither.
States with more than one legal track
Some states give families a choice of legal tracks. South Carolina, for example, has three accountability options. The structured fields (notice, requirements, assessment, portfolio, reporting) describe the track most families use, and editorial.track_basis names that track. A rule that binds only another track, such as South Carolina's 4.5-hour day under Option 1, appears in the description fields and special_notes, not in the structured fields. track_basis is absent or null for a single-track state.
Optional query params
?as_of=YYYY-MM-DD— return the snapshot active on that date?version=N— pin to a specific monotonic version number
You can only pass one at a time. Both 404 if the requested date predates the first snapshot or the version doesn't exist.
GET /api/v1/compliance/states/:abbreviation/versions
Returns the version history for one state, newest-first. Each version row carries the version number, release date, short SHA, commit author, commit message (change_summary), and a diff block listing top-level keys added / removed / changed vs the previous version.
curl -H "Authorization: Bearer $TOKEN" https://homeschoolfox.com/api/v1/compliance/states/MO/versions
Optional ?limit=N (default 50, max 200).
GET /api/v1/compliance/states/:abbreviation/versions/:version_number
Returns the historical payload at a specific version — byte-identical to what GET /states/MO?version=N returns. Useful for explicit pinning where you want the version number visible in the URL.