API documentation v1
Day-level school calendar data for every US public school district — one row per district per day, every break named and typed, every row scored for confidence.
12,000+ districts, 46M+ students, a rolling three-year window. Flat $99/month — get a key, then read on.
Overview
Responses are read-only JSON (the CSV export returns text/csv), versioned under /v1. Every calendar row carries a source_method and a confidence so you always know whether a date was read from a real calendar or estimated. It's the same archive that powers this site.
Authentication
All data endpoints require a valid API key, passed as a Bearer token in the Authorization header. Keys start with ssd_live_ and are shown once, after purchase and in your account — we store only a SHA-256 hash and can't recover it for you.
Base URL
All endpoints return application/json unless noted (the CSV export returns text/csv).
Rate limits
Each subscription includes 10,000 API calls per month, resetting on the 1st. Exceed it and requests return 429 Too Many Requests until reset. Track usage live in your account dashboard — we alert you at 80%. Need higher volume? Contact us for enterprise pricing.
GET /districts auth
Search and list districts, ordered by enrollment (largest first).
| Param | Type | Description |
|---|---|---|
| state | string | Two-letter code (case-insensitive) |
| search | string | Partial name match, e.g. Houston |
| min_enrollment | int | Enrollment floor |
| limit / offset | int | Pagination (limit default 100, max 1000) |
GET /days auth
The core endpoint — day-level rows showing whether each district is in session on each date, with break names and confidence.
| Param | Type | Description |
|---|---|---|
| district_id | string | A specific district |
| state | string | Two-letter code |
| date | string | YYYY-MM-DD — all districts for that date |
| date_from / date_to | string | Date range |
| school_year | string | e.g. 2026-2027 |
| limit | int | Default 365, max 5000 |
GET /breaks auth
Just the breaks, holidays, and non-school days (weekends excluded) — for "when is spring break across these districts?"
| Param | Type | Description |
|---|---|---|
| state | string | Two-letter code |
| break_name | string | Partial match, e.g. Spring, Thanksgiving |
| date_from / date_to | string | Date range |
| limit | int | Default 100, max 1000 |
GET /export auth
Bulk CSV, same fields as /days, flattened for a warehouse or spreadsheet.
| Param | Type | Description |
|---|---|---|
| school_year | string | Default current year |
| state | string | Omit for all states |
| limit | int | Default 50000, max 100000 |
Returns text/csv with a suggested filename — pipe with -o or load with pd.read_csv().
GET /sample no auth
Free — no key required. The top 100 districts by enrollment, to preview the data model before subscribing.
Data model
School day object
| Field | Type | Description |
|---|---|---|
| is_in_session | float | 1.0 full day · 0.5 half day · 0.0 no school. A real number, not a boolean. |
| day_type | string | SCHOOL_DAY, WEEKEND, BREAK, HOLIDAY, TEACHER_WORKDAY, HALF_DAY, SUMMER |
| break_name | string | null | e.g. Spring Break, Thanksgiving |
| confidence | float | 0.0–1.0 — see below |
| source_method | string | How we know: markitdown_extraction, pdf_extraction (both observed), imputation (estimated), deterministic (weekends, certain) |
School years
| Year | Period | Status |
|---|---|---|
| 2024-2025 | Aug 2024 – Jun 2025 | Previous (historical) |
| 2025-2026 | Aug 2025 – Jun 2026 | Most complete |
| 2026-2027 | Aug 2026 – Jun 2027 | As published / estimated |
The oldest year drops off each September. Requests outside the window return 403.
Confidence scores
| Range | Meaning |
|---|---|
| 0.90–1.00 | High — extracted directly from an official district calendar |
| 0.70–0.89 | Good — from a PDF or secondary source |
| 0.50–0.69 | Moderate — inferred from surrounding data or state patterns |
| 1.00 | Deterministic — weekends and summer, classified by rule |
Errors
| Status | Meaning |
|---|---|
| 200 | Success |
| 400 | Bad request — check your parameters |
| 401 | Missing or invalid API key |
| 403 | Subscription inactive, or year outside the window |
| 429 | Monthly rate limit exceeded |
| 500 | Server error — let us know |
Support
Something not working? Email us — you'll get a real human, usually within a few hours. Include your API key prefix (first 16 characters) so we can find your account. Most first-request issues are a missing Bearer prefix in the header.