How to Consume Our Data

The published public/data/ contract behind this site — everything a script, agent, or integration needs to reconstruct our opportunity data.

The reconstruction contract

Given partners.json plus each partner's referenced events.json and past-events.json files, no other data source — no API key, no database, no source code — is needed to fully reproduce this site's opportunity data. Every file below is a plain, publicly-served JSON file with no authentication.

These files are generated at build/publish time by the scraper pipeline (export/publish.py::project()) and served as static assets. This page never fetches them live — everything shown below is a hand-authored, static example of the real shape, kept accurate by an automated field-name check.

A note on naming

The pipeline's own curated partner roster (the input it reads) also happens to be named partners.json, but lives at a different path and has a different shape. This page documents only the published output, public/data/partners.json — not the curated input file. Don't confuse the two.

File 1: the partner roster — partners.json

Served at /data/partners.json. A single JSON object: an envelope of generated_at (an ISO 8601 UTC timestamp) and partner_count, wrapping a partners array. Every element is a partner organization record — its directory fields (name, description, location, website, contact info, logo, etc.) plus three fields added specifically for this contract:

FieldDescription
slug Stable, URL-safe identifier for this partner. Used as the directory name in File 2's path.
events_url Path to this partner's current/upcoming events file, resolved relative to public/data/ (e.g. partners/example-stem-center/events.json).
past_events_url Path to this partner's past-events file, resolved the same way as events_url.

File 2: per-partner events — events.json / past-events.json

Served at /data/partners/<slug>/events.json and /data/partners/<slug>/past-events.json, one pair per partner listed in partners.json. Each file is a JSON object with the same envelope shape:

FieldDescription
generated_at ISO 8601 UTC timestamp of when this file was written.
partner_slug The same slug as this partner's partners.json entry.
kind Either "current" (in events.json) or "past" (in past-events.json).
event_count Number of records in the events array below.
events Array of event records — see the full field reference below.

current and past are a true partition, not an independent filter: every event this pipeline has ever recorded for a partner lands in exactly one of the two files (undated records included, in past-events.json) — nothing is silently dropped.

Event field reference

Every event record in events carries exactly these fields (the site's canonical schema, export.writer.SITE_SCHEMA_FIELDS):

FieldDescription
slugstring — Stable identifier for this event, unique within the partner's event files.
titlestring — Event title, with HTML entities already decoded.
partner_namestring — Display name of the hosting partner organization.
partner_idinteger or null — Numeric id matching this partner's entry in partners.json; null if unmatched.
descriptionstring — Event description as scraped from the partner source. May contain Markdown syntax and/or unescaped HTML entities (e.g. &hellip;) — this site decodes and renders it at build time; a generic client should do the same before display.
linkstring — Canonical URL for the event (its registration link, or its source URL).
availabilitystring — Human-readable note: a recurrence summary (e.g. "Repeats 3 times through 2026-05-01"), an application-deadline/rolling note for Work-based Learning listings, or "" when neither applies.
date_startstring — ISO 8601 start date/time, or "" if unknown.
date_endstring — ISO 8601 end date/time (or, for Work-based Learning records, the application deadline), or "" if unset.
age_grade_levelarray of strings — Controlled-vocabulary age/grade tags.
cost_rangestring — Controlled-vocabulary cost bucket (e.g. "Free").
time_of_dayarray of strings — Controlled-vocabulary time-of-day tags derived from the start time.
opportunity_typestring — LLM-classified category (e.g. "Camp", "Work-based Learning", "Out-of-school Programs").
areas_of_interestarray of strings — Controlled-vocabulary STEM subject-area tags.
specific_attentionarray of strings — Reserved for population-targeting tags; always [] in the current pipeline.
financial_supportstring — Reserved financial-aid flag; always "No" in the current pipeline.
ngss_alignedstring — Reserved NGSS-alignment flag; always "No" in the current pipeline.
locationstring — Event location, falling back to the partner's own address when the event doesn't specify one.
latitudestring — Latitude (falling back to the partner's), or "" if neither is known.
longitudestring — Longitude (falling back to the partner's), or "" if neither is known.
contact_namestring — Reserved; always "" in the current pipeline.
contact_emailstring — Reserved; always "" in the current pipeline.
contact_phonestring — Reserved; always "" in the current pipeline.
logo_srcstring — Partner logo filename, self-hosted and already downloaded (never a remote URL), or "" if absent.
eligibilitystring — Free-text restriction note (e.g. "Open only to partner high schools") for programs with a closed enrollment pipeline, sourced from the registry, or "" when the program is open/unrestricted.
image_srcstring — Event image filename, self-hosted and already downloaded (never a remote URL), or "" if absent.

File 3: the robot teams directory — teams.json

Served at /data/teams.json (sprint 017). A single JSON object, independent of Files 1–2 above: a self-describing meta envelope wrapping a teams array — the FIRST/VEX robotics teams directory for San Diego County. No other data source is needed to interpret it.

FieldDescription
meta.generatedISO 8601 UTC timestamp of when this file was written.
meta.totalNumber of records in the teams array below.
meta.by_leagueObject mapping each league code ("FTC", "FRC", "FLL", "VEX") present this run to its team count.
meta.by_location_precisionObject mapping each location_precision value present this run to its team count.
meta.out_of_regionNumber of teams with in_region: false — outside San Diego County, but never dropped.

Every element of teams carries exactly these fields (the site's canonical team schema, teams.export.TEAMS_SCHEMA_FIELDS):

FieldDescription
team_idstring — Stable identifier, {league}-{number} (e.g. "ftc-1622"); league-prefixed so teams from different leagues sharing a number stay distinct.
leaguestring — Program code: "FTC", "FRC", "FLL", or "VEX".
programstring — Human-readable program name (e.g. "FIRST Tech Challenge").
numberstring — Team number/designation as issued by the league; alphanumeric for VEX (e.g. "90210A").
namestring — Team's display name.
organizationstring — Sponsoring school or organization name.
org_typestring — What organization names: "school", "family_community", or "unknown".
citystring — City name, from acquisition-time source data.
postal_codestring — Postal/ZIP code, from acquisition-time source data.
latitudenumber or null — Geocoded latitude, or null if not yet geocoded.
longitudenumber or null — Geocoded longitude, or null if not yet geocoded.
location_precisionstring — Which geocoding rung produced the coordinates: "school", "zip", "city", or "none" if ungeocoded.
in_regionboolean — false for a team located outside San Diego County (still included, never dropped).
matched_namestring — The real-world place name the geocoder actually matched (e.g. "St. Pius X School"); empty when location_precision is "none".
needs_reviewboolean — true when a fuzzy school-name match scored below the confidence threshold and should be human-verified.
websitestring — Team's own website, when known, or "" if unknown.
website_statusstring — Liveness-check result for website, or "" if not checked.
organization_websitestring — The matched school's own website (school-precision matches only); distinct from website, never presented as the team's own site.
socialarray of strings — Team-declared social media URLs (Instagram, YouTube, etc.), raw with no platform label.
rookie_yearinteger or null — First season the team competed.
activeboolean — Whether the team is currently active.
last_seasoninteger or null — Most recent season the team competed.
sponsorsarray of strings — Sponsor organization names.
sponsor_provenanceobject — Maps each sponsors entry to how it was found: "structured" (a source's own API) or "scraped" (extracted from a fetched page).
org_keystring — Cross-league identity key linking sibling teams fielded by the same organization.
sibling_team_idsarray of strings — team_ids of other teams sharing this team's org_key.

A trimmed teams.json entry:

{
  "team_id": "ftc-1622",
  "league": "FTC",
  "program": "FIRST Tech Challenge",
  "number": "1622",
  "name": "Example Robotics",
  "organization": "Example High School",
  "org_type": "school",
  "city": "San Diego",
  "postal_code": "92101",
  "latitude": 32.7157,
  "longitude": -117.1611,
  "location_precision": "school",
  "in_region": true,
  "matched_name": "Example High School",
  "needs_review": false,
  "website": "",
  "website_status": "",
  "organization_website": "",
  "social": [],
  "rookie_year": 2015,
  "active": true,
  "last_season": 2025,
  "sponsors": ["Example Robotics Boosters"],
  "sponsor_provenance": {"Example Robotics Boosters": "structured"},
  "org_key": "",
  "sibling_team_ids": []
}

Worked example

A trimmed partners.json entry for a hypothetical partner, and its matching events.json — hand-authored, not fetched, to illustrate the shape (Design Rationale D3: these files may not exist yet in every checkout).

Trimmed entry from partners.json

{
  "generated_at": "2026-08-27T12:00:00Z",
  "partner_count": 1,
  "partners": [
    {
      "id": 42,
      "name": "Example STEM Center",
      "organization_type": "Museum",
      "location": "1234 Discovery Way, San Diego, CA 92101",
      "latitude": 32.7157,
      "longitude": -117.1611,
      "website": "https://example-stem-center.org/",
      "logo_src": "example-stem-center.png",
      "slug": "example-stem-center",
      "events_url": "partners/example-stem-center/events.json",
      "past_events_url": "partners/example-stem-center/past-events.json"
    }
  ]
}

Matching partners/example-stem-center/events.json

{
  "generated_at": "2026-08-27T12:00:00Z",
  "partner_slug": "example-stem-center",
  "kind": "current",
  "event_count": 1,
  "events": [
    {
      "slug": "family-robotics-night_20260915",
      "title": "Family Robotics Night",
      "partner_name": "Example STEM Center",
      "partner_id": 42,
      "description": "Build and race simple robots together as a family.",
      "link": "https://example-stem-center.org/events/robotics-night",
      "availability": "",
      "date_start": "2026-09-15T18:00:00-07:00",
      "date_end": "2026-09-15T20:00:00-07:00",
      "age_grade_level": ["Elementary", "Middle School"],
      "cost_range": "Free",
      "time_of_day": ["Evening"],
      "opportunity_type": "Out-of-school Programs",
      "areas_of_interest": ["Technology", "Engineering"],
      "specific_attention": [],
      "financial_support": "No",
      "ngss_aligned": "No",
      "location": "1234 Discovery Way, San Diego, CA 92101",
      "latitude": "32.7157",
      "longitude": "-117.1611",
      "contact_name": "",
      "contact_email": "",
      "contact_phone": "",
      "logo_src": "example-stem-center.png",
      "eligibility": "",
      "image_src": ""
    }
  ]
}

This same contract is what powers the site you're already looking at — browse the Partner Directory to see it rendered.