1. Overview

The SchoolScan API is a RESTful JSON API. All requests and responses use JSON. All endpoints require authentication. The API is designed for integration with:

  • District business intelligence tools (Power BI, Tableau, Looker)
  • Compliance management systems and dashboards
  • SIS and data-warehouse pipelines
  • Ticketing and remediation workflows (ServiceNow, Jira)
  • Custom internal tools

API access is included in the standard SchoolScan subscription. Request credentials by emailing hello@schoolscan.ai.

2. Authentication

Authentication is via bearer tokens provisioned per district. Include the token in the Authorization header of every request.

# Example request curl -H "Authorization: Bearer sk_live_4x9..." \ -H "Content-Type: application/json" \ https://api.schoolscan.ai/v1/scans
Security

Tokens grant full API access for the issuing district and should be treated as secrets. Rotate tokens immediately if one is exposed. Tokens can be scoped to specific permissions (read-only, scan-trigger, admin) via the settings page.

3. Rate Limits

API requests are rate-limited per district:

  • Read endpoints (GET): 300 requests per minute
  • Write endpoints (POST, PATCH, DELETE): 60 requests per minute
  • Scan triggers: 5 concurrent scans per district

Rate-limit state is returned in response headers: X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset (Unix timestamp). A 429 Too Many Requests response indicates you should back off and retry after the reset time.

4. Scans

List scans

GET /v1/scans

Returns a paginated list of scans. Supports ?status=, ?domain=, and ?created_after= filters.

Retrieve a scan

GET /v1/scans/{scan_id}
{ "id": "scan_2k9x4f", "status": "completed", "domain": "example-district.edu", "started_at": "2026-04-15T14:02:11Z", "completed_at": "2026-04-15T16:47:03Z", "pages_scanned": 247, "findings_count": 12, "overall_grade": "B", "domain_scores": { "direct_pii": 92, "reidentification": 78, "directory_info": 85, "education_records": 95, "metadata": 70, "vendor_exposure": 88 } }

Start a scan

POST /v1/scans

Triggers a new scan of a configured domain. The domain must be registered under your district account. Returns a scan_id you can poll or subscribe to via webhook.

{ "domain": "example-district.edu", "scan_type": "incremental", "notify_on_complete": "https://your-tool.example.com/webhooks/scan" }

Cancel a scan

DELETE /v1/scans/{scan_id}

5. Findings

List findings

GET /v1/findings

Filters: ?scan_id=, ?severity=critical|high|medium|low, ?status=open|reviewing|resolved, ?domain_type=direct_pii|reidentification|directory_info|education_records|metadata|vendor_exposure.

Retrieve a finding

GET /v1/findings/{finding_id}
{ "id": "fnd_8kq2p7", "scan_id": "scan_2k9x4f", "severity": "critical", "domain_type": "direct_pii", "status": "open", "url": "https://example-district.edu/board/minutes/2024-03.pdf", "location": "Page 4, paragraph 2", "pii_type": "student_name_with_discipline_record", "confidence": 0.94, "expert_reviewed": true, "policy_context": "Outside directory information designation", "recommended_action": "Redact student name and discipline reference; re-publish." }

Update finding status

PATCH /v1/findings/{finding_id}

Change status to reviewing, resolved, or accepted_risk. Include a note explaining the remediation or decision for the audit trail.

6. Reports and Exports

Generate a report

POST /v1/reports

Generates a compliance report from a completed scan. Supported formats: pdf, csv, json, markdown.

Download an export

GET /v1/reports/{report_id}/download

Returns a time-limited signed URL for the report. URLs expire after 15 minutes.

7. Webhooks

Webhooks push events to your endpoint rather than requiring polling. Supported events:

  • scan.started — a scan has begun
  • scan.completed — a scan has finished and findings are available
  • finding.critical — a new critical finding was identified
  • finding.expert_reviewed — a finding has been reviewed by privacy staff

Configure webhook endpoints in the settings page. Webhook payloads are signed with HMAC-SHA256; verify the signature using the X-SchoolScan-Signature header and your webhook secret.

8. Errors

Standard HTTP status codes are used:

  • 200 — Success
  • 201 — Created (scan triggered, finding updated)
  • 400 — Bad Request (malformed payload, invalid parameters)
  • 401 — Unauthorized (missing or invalid token)
  • 403 — Forbidden (token lacks permission for the resource)
  • 404 — Not Found
  • 429 — Rate limit exceeded
  • 500 — Server error (retry with backoff)

Error responses include a structured body:

{ "error": { "code": "domain_not_registered", "message": "Domain 'example.edu' is not registered under this account.", "doc_url": "https://schoolscan.ai/api-docs.html#errors" } }

9. Versioning

The API is versioned in the URL path (/v1/). Breaking changes are introduced only in new versions. Minor additions (new fields, new endpoints) may be added to the current version without notice. SchoolScan will provide at least 12 months of advance notice before deprecating a version.

10. SDKs and Tools

We maintain lightweight client libraries:

  • Pythonpip install schoolscan
  • Node.jsnpm install @schoolscan/client
  • Postman Collection — available on request
  • OpenAPI Specificationhttps://api.schoolscan.ai/v1/openapi.json

Need API access?

API access is included with every SchoolScan subscription. Our team can also help you build integrations with your existing compliance or BI tools.

Request API Access

Related: