{"openapi":"3.1.0","info":{"title":"TeacherSanctions.io API","version":"1.1.0","description":"Search official U.S. state-published educator sanction and disciplinary records.\n\n**Important**: This service provides access to publicly available records. It is **not a consumer report** under the Fair Credit Reporting Act (FCRA). It is intended for research, awareness, public safety, and legitimate business purposes only. Full disclaimers, limitations of liability, acceptable use rules, and user responsibilities are in our Terms of Service (https://www.teachersanctions.io/terms) and Privacy Policy (https://www.teachersanctions.io/privacy). You are solely responsible for compliance with all applicable laws.","contact":{"name":"Support","url":"https://www.teachersanctions.io/contact"}},"servers":[{"url":"https://www.teachersanctions.io","description":"Production"},{"url":"http://localhost:3000","description":"Local development"}],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"ts_live_...","description":"Use `Authorization: Bearer ts_live_...`."},"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key","description":"Use `X-API-Key: ts_live_...`."}},"schemas":{"SearchResult":{"type":"object","required":["recordId","name","firstName","middleName","lastName","suffix","state","sanctionType","effectiveDate","districtOrEmployer","licenseNumber","reason","sourceUrl","provenanceType","provenanceLabel","firstIngestedAt","freshness"],"properties":{"recordId":{"type":"string","format":"uuid","description":"Opaque sanction-record identifier. It is not an educator or person identifier."},"name":{"type":"string"},"firstName":{"type":["string","null"],"description":"Best-effort parsed given name. Use `name` as the preserved display-name fallback."},"middleName":{"type":["string","null"],"description":"Best-effort parsed middle name or initial."},"lastName":{"type":["string","null"],"description":"Best-effort parsed family name."},"suffix":{"type":["string","null"],"description":"Best-effort parsed name suffix."},"state":{"type":"string"},"sanctionType":{"type":"string"},"effectiveDate":{"type":["string","null"],"format":"date","description":"Sanction or action effective date when published by the source."},"districtOrEmployer":{"type":["string","null"]},"licenseNumber":{"type":["string","null"]},"reason":{"type":["string","null"]},"sourceUrl":{"type":"string","description":"Browsable official source when one is available; otherwise an empty string. It is not a unique record identifier."},"provenanceType":{"type":["string","null"],"description":"Source access class, when applicable."},"provenanceLabel":{"type":["string","null"],"description":"Human-readable provenance description."},"firstIngestedAt":{"type":"string","format":"date-time","description":"When this stored record was first ingested. This is not the sanction date, publication date, or last-verification time."},"freshness":{"type":"string","format":"date","deprecated":true,"description":"Deprecated date-only alias of `firstIngestedAt`; retained for backward compatibility."}}},"SearchMeta":{"type":"object","required":["limit","returned","truncated"],"properties":{"limit":{"type":"integer","const":20},"returned":{"type":"integer","minimum":0,"maximum":20},"truncated":{"type":"boolean","description":"True when more matching records exist than were returned. Pagination is not currently supported."}}},"SearchResponse":{"type":"object","required":["results","meta"],"properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/SearchResult"}},"meta":{"$ref":"#/components/schemas/SearchMeta"}}},"StatusState":{"type":"object","required":["abbr","name","recordCount","oldestSanction","lastUpdated"],"properties":{"abbr":{"type":"string"},"name":{"type":"string"},"recordCount":{"type":"integer"},"oldestSanction":{"type":["string","null"],"format":"date"},"lastUpdated":{"type":["string","null"],"format":"date-time"}}},"StatusResponse":{"type":"object","required":["statesCovered","totalSanctions","lastFullRefresh","overallStatus","lastUpdated","states"],"properties":{"statesCovered":{"type":"integer"},"totalSanctions":{"type":"integer"},"lastFullRefresh":{"type":"string"},"overallStatus":{"type":"string"},"lastUpdated":{"type":"string"},"states":{"type":"array","items":{"$ref":"#/components/schemas/StatusState"}}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error code or concise error description."},"message":{"type":"string"},"limit":{"type":"number","description":"Monthly or rate limit (present for free_limit_reached, enterprise_limit_reached, rate_limit_exceeded)"},"reset":{"type":"number","description":"Present for rate-limit errors as Unix epoch milliseconds."},"searches":{"type":"number","description":"Only present for free_limit_reached and enterprise_limit_reached"},"usage":{"type":"object","properties":{"searches_this_month":{"type":"number"},"plan":{"type":"string"}}}}}}},"paths":{"/api/search":{"post":{"summary":"Search educator sanctions","operationId":"searchSanctions","security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["fullName"],"properties":{"fullName":{"type":"string","example":"Jordan Lee Smith"},"state":{"type":["string","null"],"example":"CA","description":"Optional two-letter state code or full state name. Omit for a nationwide search."}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchResponse"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Monthly credit / quota limit reached (free or enterprise)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Invalid request origin for session-authenticated browser requests","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Usage or billing service temporarily unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/status":{"get":{"summary":"Service status","description":"Public endpoint (no authentication) for health checks, data coverage, and last refresh time.","operationId":"getStatus","security":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatusResponse"}}}},"500":{"description":"Degraded fallback status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatusResponse"}}}}}}}}}