US Geographic & Demographics API
Download OpenAPI (geo-demographics.yaml) · Base URL https://api.olympus.new-odyssey.com
Census demographic profiles for ZIP Code Tabulation Areas (ZCTAs) and counties, nearby public schools, and two-location comparison, served by the Olympus Go gateway (/v1/geo-demographics/* is forwarded to the geographic service as /v1/*).
Geography: ZCTAs are not ZIP codes. A ZCTA is a Census statistical area built from census blocks to approximate a USPS ZIP code delivery area. Many USPS ZIP codes (PO-box-only, single-building, military and other non-residential ZIPs) have no ZCTA, and a ZIP and the ZCTA with the same code rarely cover exactly the same addresses. Location endpoints take a 5-digit code and resolve it only by exact ZCTA code; every response states the geography it describes in geography.type and geography.id. A code with no ZCTA returns 404 ZCTA_NOT_FOUND. No ZIP-to-ZCTA crosswalk is applied.
Vintage: estimates are not current. Every metric is an American Community Survey (ACS) 5-year estimate and carries its vintage (e.g. period 2020-2024): it describes that 5-year period, not today. Dollar values are inflation-adjusted to the final year of the period. Estimates carry a 90% margin of error (moe) where the Census Bureau publishes one.
Suppressed and open-ended values. When the Census Bureau publishes an annotation instead of an estimate (too few sample cases, not applicable), value is null and null_reason says why. Medians in an open-ended interval are returned as the interval edge with a qualifier (or_more: e.g. 250000 means "250,000 or more"; less_than: 2500 means "less than 2,500").
Provenance. Every record carries a provenance block (dataset, source URL and version, source date, when this version was published, schema version, validation status of its publication), every metric names its ACS table and variables, and meta.datasets lists the active publication of each dataset the response read. meta.coverage states what the data covers and excludes.
Coverage. ACS 5-year ZCTAs and counties in the 50 states, DC and Puerto Rico; NCES public and public charter schools that are open in the CCD school year. Not included: crime data or scores, school ratings or rankings, flood or other risk scores, parcel-level decisions, private schools, predictive scores. Not every USPS ZIP code has a ZCTA.
Authenticate with an API key in X-API-Key or Authorization: Bearer. The organization's plan must include geo-demographics; requests count against its monthly quota. Every response carries X-Request-Id. Errors share the Error body.
Locations
ZCTA profile
/v1/geo-demographics/locations/{zcta}Geography of one ZCTA (land area, internal point, overlapping counties with land-area shares) and headline ACS metrics. Use /demographics for the full metric set.
Authentication: API key (X-API-Key or Bearer)
Parameters
| Name | In | Type | Description |
|---|---|---|---|
| zctarequired | path | string | 5-digit ZCTA code. A USPS ZIP code is accepted as input but resolves only if a ZCTA with the same code exists ( Example: 02139 |
Responses
| 200 | The ZCTA profile. | LocationResponse |
| 400 | The code is not 5 digits ( | Error |
| 401 | Missing or invalid API key ( | Error |
| 403 | Organization suspended ( | Error |
| 404 | No ZCTA has this code in the active publication ( | Error |
| 429 | Per-minute rate limit exceeded ( | Error |
| 503 | A dataset this endpoint reads has no active publication yet ( | Error |
curl -s "https://api.olympus.new-odyssey.com/v1/geo-demographics/locations/02139" \
-H "X-API-Key: $OLYMPUS_API_KEY"ZCTA demographics
/v1/geo-demographics/locations/{zcta}/demographicsThe full metric set for one ZCTA: population, age, households, income, home value, rent, tenure, education, poverty and unemployment. Each metric carries its value, margin of error, ACS table and variables, vintage, and a reason when the value is null.
Authentication: API key (X-API-Key or Bearer)
Parameters
| Name | In | Type | Description |
|---|---|---|---|
| zctarequired | path | string | 5-digit ZCTA code. A USPS ZIP code is accepted as input but resolves only if a ZCTA with the same code exists ( Example: 02139 |
Responses
| 200 | Demographic profile of the ZCTA. | DemographicsResponse |
| 400 | The code is not 5 digits ( | Error |
| 401 | Missing or invalid API key ( | Error |
| 403 | Organization suspended ( | Error |
| 404 | No ZCTA has this code in the active publication ( | Error |
| 429 | Per-minute rate limit exceeded ( | Error |
| 503 | A dataset this endpoint reads has no active publication yet ( | Error |
curl -s "https://api.olympus.new-odyssey.com/v1/geo-demographics/locations/02139/demographics" \
-H "X-API-Key: $OLYMPUS_API_KEY"Public schools near a ZCTA
/v1/geo-demographics/locations/{zcta}/schoolsNCES public and public charter schools within radius_miles of the ZCTA's internal point (Census Gazetteer), nearest first. Distances are great-circle miles from that point, not from an address and not travel distance; the ZCTA's own area may extend beyond the radius. No ratings, test scores or rankings are provided.
Authentication: API key (X-API-Key or Bearer)
Parameters
| Name | In | Type | Description |
|---|---|---|---|
| zctarequired | path | string | 5-digit ZCTA code. A USPS ZIP code is accepted as input but resolves only if a ZCTA with the same code exists ( Example: 02139 |
| radius_miles | query | number | Search radius from the ZCTA internal point. |
| limit | query | integer | |
| level | query | SchoolLevel | Only schools with this NCES school level. |
| charter | query | boolean |
|
Responses
| 200 | Schools within the radius, nearest first. | SchoolListResponse |
| 400 | Invalid parameter or body ( | Error |
| 401 | Missing or invalid API key ( | Error |
| 403 | Organization suspended ( | Error |
| 404 | No ZCTA has this code in the active publication ( | Error |
| 429 | Per-minute rate limit exceeded ( | Error |
| 503 | A dataset this endpoint reads has no active publication yet ( | Error |
curl -s "https://api.olympus.new-odyssey.com/v1/geo-demographics/locations/02139/schools" \
-H "X-API-Key: $OLYMPUS_API_KEY"Compare two ZCTAs
/v1/geo-demographics/locations/compareSide-by-side ACS metrics for exactly two ZCTAs, with the difference and, where both margins of error are published, whether the difference is statistically significant at the 90% level (Census method: |a - b| > 1.645 * sqrt(se_a^2 + se_b^2), se = moe / 1.645). Both locations are served from the same active publication, so they always share a vintage. If either code has no ZCTA the request fails with 404 ZCTA_NOT_FOUND naming the missing codes.
Authentication: API key (X-API-Key or Bearer)
Request body
application/json — CompareRequest
{
"locations": [
"02139",
"60614"
],
"metrics": [
"median_household_income",
"median_gross_rent"
]
}Responses
| 200 | The comparison. | CompareResponse |
| 400 | Invalid parameter or body ( | Error |
| 401 | Missing or invalid API key ( | Error |
| 403 | Organization suspended ( | Error |
| 404 | No ZCTA has this code in the active publication ( | Error |
| 429 | Per-minute rate limit exceeded ( | Error |
| 503 | A dataset this endpoint reads has no active publication yet ( | Error |
Counties
County profile
/v1/geo-demographics/counties/{fips}ACS metrics for one county or county equivalent (5-digit FIPS, e.g. 25017), with its Gazetteer geography and the ZCTAs that overlap it. ZCTA overlaps come from the Census 2020 ZCTA-to-county relationship file and use 2020 counties: for Connecticut, whose ACS 2022+ county equivalents are planning regions (09110-09190), zctas is empty and zctas_note says why.
Authentication: API key (X-API-Key or Bearer)
Parameters
| Name | In | Type | Description |
|---|---|---|---|
| fipsrequired | path | string | 5-digit county FIPS code (state + county). Example: 25017 |
Responses
| 200 | The county profile. | CountyResponse |
| 400 | Invalid parameter or body ( | Error |
| 401 | Missing or invalid API key ( | Error |
| 403 | Organization suspended ( | Error |
| 404 | No county or county equivalent has this FIPS code in the active publication ( | Error |
| 429 | Per-minute rate limit exceeded ( | Error |
| 503 | A dataset this endpoint reads has no active publication yet ( | Error |
curl -s "https://api.olympus.new-odyssey.com/v1/geo-demographics/counties/25017" \
-H "X-API-Key: $OLYMPUS_API_KEY"Coverage
Datasets, vintages and coverage
/v1/geo-demographics/coverageWhat this API currently serves: each dataset's active publication, freshness, vintage, record counts, coverage statement and the exclusions that apply to every endpoint.
Authentication: API key (X-API-Key or Bearer)
Responses
| 200 | Coverage of every dataset this API serves. | CoverageResponse |
| 401 | Missing or invalid API key ( | Error |
| 403 | Organization suspended ( | Error |
| 429 | Per-minute rate limit exceeded ( | Error |
curl -s "https://api.olympus.new-odyssey.com/v1/geo-demographics/coverage" \
-H "X-API-Key: $OLYMPUS_API_KEY"Schemas
Error object
The error body shared by every Olympus service.
| Field | Type | Description |
|---|---|---|
| error * | string | Human-readable message. |
| code * | string | Stable machine-readable code. |
| product | string | Product that produced the error, when applicable. |
| details | object |
DatasetId enum: atlas.zcta_demographics | atlas.county_demographics | atlas.zcta_counties | atlas.schools
atlas.zcta_demographicsatlas.county_demographicsatlas.zcta_countiesatlas.schools
SourceId enum: census.acs5 | census.zcta_county_rel2020 | nces.ccd_directory
Registered upstream source of the record.
census.acs5census.zcta_county_rel2020nces.ccd_directory
Provenance object
Where this record came from and which publication introduced this version of it.
| Field | Type | Description |
|---|---|---|
| dataset_id * | DatasetId | |
| source_id * | SourceId | |
| source_url * | string (uri) | The record's upstream data: for ACS records the Census Data API query for this geography and variable set (add your own |
| source_version * | string | Publisher release of the source snapshot. |
| source_date * | string (date) | null | Publisher as-of date of that snapshot (Census API dataset |
| published_at * | string (date-time) | When this version of the record was first published by Olympus. Unchanged records keep their original time. |
| schema_version * | string | |
| validation_status * | enum: passed | passed_with_warnings | Outcome of the validation checks that gated the publication. |
| record_id * | string | Stable record key within the dataset. |
DatasetPublication object
| Field | Type | Description |
|---|---|---|
| dataset_id * | DatasetId | |
| publication_id | integer (int64) | |
| published_at * | string (date-time) | |
| validation_status | enum: passed | passed_with_warnings | |
| freshness * | enum: fresh | stale |
|
Coverage object
What the data behind this response covers and excludes.
| Field | Type | Description |
|---|---|---|
| geography_type * | enum: zcta | county | school | |
| scope * | string | |
| vintage | Vintage | |
| school_year | string | null | NCES school year of the school directory, for school responses. |
| excluded * | array of string | |
| notes | array of string |
Notice object
| Field | Type | Description |
|---|---|---|
| code * | enum: ZCTA_NOT_USPS_ZIP | ESTIMATE_PERIOD | SUPPRESSED_VALUES | RELATIONSHIP_VINTAGE | ZCTA_ASSIGNMENT_APPROXIMATE | |
| message * | string |
Meta object
| Field | Type | Description |
|---|---|---|
| request_id | string | |
| datasets * | DatasetPublication [] | Active publication of each dataset this response read. |
| coverage * | Coverage | |
| notices | Notice [] | Caveats that apply to this response (always includes |
Vintage object
The ACS release a value comes from. Values describe this period, not the present.
| Field | Type | Description |
|---|---|---|
| survey * | enum: ACS 5-year | |
| period * | string | |
| year * | integer | Final year of the period; dollar values are in this year's dollars. |
MetricKey enum: total_population | median_age | households | median_household_income | median_home_value | median_gross_rent | owner_occupied_pct | renter_occupied_pct | high_school_or_higher_pct | bachelors_or_higher_pct | poverty_rate | unemployment_rate
total_populationmedian_agehouseholdsmedian_household_incomemedian_home_valuemedian_gross_rentowner_occupied_pctrenter_occupied_pcthigh_school_or_higher_pctbachelors_or_higher_pctpoverty_rateunemployment_rate
MetricSource object
| Field | Type | Description |
|---|---|---|
| dataset_id * | DatasetId | |
| source_id * | enum: census.acs5 | |
| table_id * | string | |
| variables * | array of string | ACS estimate variables used. |
| moe_variable | string | null | |
| derived * | boolean | True when Olympus computed the value from the variables (percentages); derived values have no published MOE. |
| formula | string | null |
Metric object
| Field | Type | Description |
|---|---|---|
| key * | MetricKey | |
| label * | string | |
| unit * | enum: count | usd | percent | years | |
| value * | number | null | The estimate; null when the Census Bureau published an annotation instead (see |
| moe * | number | null | 90% margin of error as published. Null for derived metrics and when not published (see |
| moe_note | enum: controlled_estimate | open_ended_distribution | insufficient_sample | null |
|
| qualifier * | enum: or_more | less_than | null | Set for medians in an open-ended interval; |
| null_reason * | enum: insufficient_sample | not_applicable | not_available | zero_universe | unknown_annotation | null | |
| census_value | number | null | The raw published value when it is an annotation code or an open-ended code (e.g. -666666666, 250001). |
| universe * | string | |
| vintage * | Vintage | |
| source * | MetricSource | |
| geography * | GeographyRef |
Metrics object
Every metric for the geography, keyed by metric.
| Field | Type | Description |
|---|---|---|
| total_population * | Metric | |
| median_age * | Metric | |
| households * | Metric | |
| median_household_income * | Metric | |
| median_home_value * | Metric | |
| median_gross_rent * | Metric | |
| owner_occupied_pct * | Metric | |
| renter_occupied_pct * | Metric | |
| high_school_or_higher_pct * | Metric | |
| bachelors_or_higher_pct * | Metric | |
| poverty_rate * | Metric | |
| unemployment_rate * | Metric |
UniverseCounts object
Universe and component counts behind the derived percentages (ACS estimates, same vintage).
| Field | Type | Description |
|---|---|---|
| occupied_housing_units | integer | null | |
| owner_occupied_units | integer | null | |
| renter_occupied_units | integer | null | |
| population_25_plus | integer | null | |
| poverty_universe | integer | null | |
| below_poverty | integer | null | |
| civilian_labor_force | integer | null | |
| unemployed | integer | null |
GeographyRef object
The geography a value describes.
| Field | Type | Description |
|---|---|---|
| type * | enum: zcta | county | |
| id * | string | 5-digit ZCTA code or 5-digit county FIPS. |
Point object
| Field | Type | Description |
|---|---|---|
| latitude * | number | |
| longitude * | number |
ZctaCounty object
One part of a ZCTA that lies in a county (Census 2020 relationship file, 2020 counties).
| Field | Type | Description |
|---|---|---|
| county_fips * | string | |
| county_name | string | null | |
| state_fips * | string | |
| state_code | string | null | |
| zcta_land_share * | number | null | Share of the ZCTA's land area in this county. |
| county_land_share * | number | null | Share of the county's land area in this ZCTA. |
| population_share * | number | null | Always null in 1.0 - the 2020 relationship file publishes no population. |
| is_primary * | boolean | The county holding the largest land share of the ZCTA. |
| relationship_vintage * | string | |
| provenance * | Provenance |
ZctaGeography object
| Field | Type | Description |
|---|---|---|
| type * | enum: zcta | |
| id * | string | |
| zcta5 * | string | |
| name * | string | |
| input_code * | string | The code as requested. |
| matched_by * | enum: exact_zcta_code | How the input resolved to this ZCTA. No ZIP-to-ZCTA crosswalk is applied. |
| land_area_sqmi * | number | null | |
| water_area_sqmi * | number | null | |
| population_density_sqmi | number | null | ACS total population / Gazetteer land area. |
| internal_point * | Point | Census internal point (not a centroid of addresses); the origin for school distances. |
| primary_county_fips | string | null | |
| primary_state_code | string | null | |
| geography_vintage * | string | |
| counties * | ZctaCounty [] |
CountyGeography object
| Field | Type | Description |
|---|---|---|
| type * | enum: county | |
| id * | string | |
| county_fips * | string | |
| name * | string | |
| county_name | string | null | |
| state_fips * | string | |
| state_code | string | null | |
| land_area_sqmi * | number | null | |
| water_area_sqmi | number | null | |
| population_density_sqmi | number | null | |
| internal_point * | Point | |
| geography_vintage * | string |
LocationProfile object
| Field | Type | Description |
|---|---|---|
| geography * | ZctaGeography | |
| vintage * | Vintage | |
| summary * | object | Headline metrics; see |
| links * | object | |
| provenance * | Provenance |
Demographics object
| Field | Type | Description |
|---|---|---|
| geography * | GeographyRef | |
| name | string | |
| vintage * | Vintage | |
| metrics * | Metrics | |
| counts * | UniverseCounts | |
| provenance * | Provenance |
CountyProfile object
| Field | Type | Description |
|---|---|---|
| geography * | CountyGeography | |
| vintage * | Vintage | |
| metrics * | Metrics | |
| counts * | UniverseCounts | |
| zctas * | array of object | ZCTAs overlapping the county (2020 relationship file), by descending county land share. |
| zctas_note | string | null | |
| provenance * | Provenance |
SchoolLevel enum: elementary | middle | high | secondary | prekindergarten | adult_education | ungraded | other | not_reported | not_applicable
elementarymiddlehighsecondaryprekindergartenadult_educationungradedothernot_reportednot_applicable
School object
One NCES public school. No ratings, scores or rankings.
| Field | Type | Description |
|---|---|---|
| ncessch * | string | 12-digit NCES school ID. |
| name * | string | |
| district | object | |
| level * | SchoolLevel | |
| type * | enum: regular | special_education | career_technical | alternative | null | |
| is_charter * | boolean | null | Null when NCES reports charter status as not applicable (e.g. BIE schools). |
| grades * | object | |
| operational_status * | enum: open | new | added | changed_boundary | reopened | |
| address * | object | |
| phone | string | null | |
| website | string | null | |
| enrollment | integer | null | CCD membership (October 1 count) when loaded and reported; null otherwise. |
| location * | Point | |
| distance_miles * | number | Great-circle distance from the ZCTA internal point. |
| county * | object | |
| zcta * | object | |
| locale_code | string | null | NCES urban-centric locale code (e.g. 11 = City, Large). |
| school_year * | string | |
| provenance * | Provenance |
LocationResponse object
| Field | Type | Description |
|---|---|---|
| data * | LocationProfile | |
| meta * | Meta |
DemographicsResponse object
| Field | Type | Description |
|---|---|---|
| data * | Demographics | |
| meta * | Meta |
CountyResponse object
| Field | Type | Description |
|---|---|---|
| data * | CountyProfile | |
| meta * | Meta |
SchoolListResponse object
| Field | Type | Description |
|---|---|---|
| data * | object | |
| meta * | Meta |
CompareRequest object
| Field | Type | Description |
|---|---|---|
| locations * | array of string | Exactly two distinct 5-digit ZCTA codes. |
| metrics | MetricKey [] | Metrics to compare; defaults to all. |
Comparison object
| Field | Type | Description |
|---|---|---|
| metric * | MetricKey | |
| unit * | enum: count | usd | percent | years | |
| values * | array of object | |
| difference * | number | null | Second minus first. Null when either value is null or open-ended. |
| comparable * | boolean | False when either value is null or open-ended. |
| significant_at_90 * | boolean | null | Census 90% significance test; null when either MOE is unavailable (always null for derived metrics). |
CompareResponse object
| Field | Type | Description |
|---|---|---|
| data * | object | |
| meta * | Meta |
DatasetCoverage object
| Field | Type | Description |
|---|---|---|
| dataset_id * | DatasetId | |
| status * | enum: fresh | stale | unpublished | |
| publication_id | integer (int64) | null | |
| published_at | string (date-time) | null | |
| validation_status | enum: passed | passed_with_warnings | null | |
| schema_version | string | |
| record_count | integer | null | |
| coverage_description * | string | |
| coverage | object | Publication coverage, e.g. |
| sources | array of object |
CoverageResponse object
| Field | Type | Description |
|---|---|---|
| data * | object | |
| meta * | object |
* required field