API reference · v1.0.0

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

GET/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

NameInTypeDescription
zctarequiredpathstring

5-digit ZCTA code. A USPS ZIP code is accepted as input but resolves only if a ZCTA with the same code exists (geography.matched_by: exact_zcta_code); the response always describes the ZCTA.

Example: 02139

Responses

200

The ZCTA profile.

LocationResponse
400

The code is not 5 digits (VALIDATION_ERROR).

Error
401

Missing or invalid API key (UNAUTHORIZED), or a disabled, expired or revoked one (API_KEY_DISABLED, API_KEY_EXPIRED, API_KEY_REVOKED).

Error
403

Organization suspended (ORGANIZATION_SUSPENDED), no live subscription (NO_ACTIVE_SUBSCRIPTION) , geo-demographics not on the plan (PRODUCT_NOT_ENABLED) or a key scoped to another product (API_KEY_PRODUCT_SCOPE).

Error
404

No ZCTA has this code in the active publication (ZCTA_NOT_FOUND). The code may still be a valid USPS ZIP code: PO-box-only, single-building and non-residential ZIPs have no ZCTA. details.codes lists the codes not found.

Error
429

Per-minute rate limit exceeded (RATE_LIMIT_EXCEEDED) or monthly quota exhausted (QUOTA_EXCEEDED).

Error
503

A dataset this endpoint reads has no active publication yet (SERVICE_UNAVAILABLE, details.dataset_id).

Error
curl
curl -s "https://api.olympus.new-odyssey.com/v1/geo-demographics/locations/02139" \
  -H "X-API-Key: $OLYMPUS_API_KEY"

ZCTA demographics

GET/v1/geo-demographics/locations/{zcta}/demographics

The 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

NameInTypeDescription
zctarequiredpathstring

5-digit ZCTA code. A USPS ZIP code is accepted as input but resolves only if a ZCTA with the same code exists (geography.matched_by: exact_zcta_code); the response always describes the ZCTA.

Example: 02139

Responses

200

Demographic profile of the ZCTA.

DemographicsResponse
400

The code is not 5 digits (VALIDATION_ERROR).

Error
401

Missing or invalid API key (UNAUTHORIZED), or a disabled, expired or revoked one (API_KEY_DISABLED, API_KEY_EXPIRED, API_KEY_REVOKED).

Error
403

Organization suspended (ORGANIZATION_SUSPENDED), no live subscription (NO_ACTIVE_SUBSCRIPTION) , geo-demographics not on the plan (PRODUCT_NOT_ENABLED) or a key scoped to another product (API_KEY_PRODUCT_SCOPE).

Error
404

No ZCTA has this code in the active publication (ZCTA_NOT_FOUND). The code may still be a valid USPS ZIP code: PO-box-only, single-building and non-residential ZIPs have no ZCTA. details.codes lists the codes not found.

Error
429

Per-minute rate limit exceeded (RATE_LIMIT_EXCEEDED) or monthly quota exhausted (QUOTA_EXCEEDED).

Error
503

A dataset this endpoint reads has no active publication yet (SERVICE_UNAVAILABLE, details.dataset_id).

Error
curl
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

GET/v1/geo-demographics/locations/{zcta}/schools

NCES 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

NameInTypeDescription
zctarequiredpathstring

5-digit ZCTA code. A USPS ZIP code is accepted as input but resolves only if a ZCTA with the same code exists (geography.matched_by: exact_zcta_code); the response always describes the ZCTA.

Example: 02139
radius_milesquerynumber

Search radius from the ZCTA internal point.

limitqueryinteger
levelquerySchoolLevel

Only schools with this NCES school level.

charterqueryboolean

true for charter schools only, false to exclude them. Omit for both.

Responses

200

Schools within the radius, nearest first.

SchoolListResponse
400

Invalid parameter or body (VALIDATION_ERROR; details.fields maps each field to the reason) or malformed request (BAD_REQUEST).

Error
401

Missing or invalid API key (UNAUTHORIZED), or a disabled, expired or revoked one (API_KEY_DISABLED, API_KEY_EXPIRED, API_KEY_REVOKED).

Error
403

Organization suspended (ORGANIZATION_SUSPENDED), no live subscription (NO_ACTIVE_SUBSCRIPTION) , geo-demographics not on the plan (PRODUCT_NOT_ENABLED) or a key scoped to another product (API_KEY_PRODUCT_SCOPE).

Error
404

No ZCTA has this code in the active publication (ZCTA_NOT_FOUND). The code may still be a valid USPS ZIP code: PO-box-only, single-building and non-residential ZIPs have no ZCTA. details.codes lists the codes not found.

Error
429

Per-minute rate limit exceeded (RATE_LIMIT_EXCEEDED) or monthly quota exhausted (QUOTA_EXCEEDED).

Error
503

A dataset this endpoint reads has no active publication yet (SERVICE_UNAVAILABLE, details.dataset_id).

Error
curl
curl -s "https://api.olympus.new-odyssey.com/v1/geo-demographics/locations/02139/schools" \
  -H "X-API-Key: $OLYMPUS_API_KEY"

Compare two ZCTAs

POST/v1/geo-demographics/locations/compare

Side-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

example
{
  "locations": [
    "02139",
    "60614"
  ],
  "metrics": [
    "median_household_income",
    "median_gross_rent"
  ]
}

Responses

200

The comparison.

CompareResponse
400

Invalid parameter or body (VALIDATION_ERROR; details.fields maps each field to the reason) or malformed request (BAD_REQUEST).

Error
401

Missing or invalid API key (UNAUTHORIZED), or a disabled, expired or revoked one (API_KEY_DISABLED, API_KEY_EXPIRED, API_KEY_REVOKED).

Error
403

Organization suspended (ORGANIZATION_SUSPENDED), no live subscription (NO_ACTIVE_SUBSCRIPTION) , geo-demographics not on the plan (PRODUCT_NOT_ENABLED) or a key scoped to another product (API_KEY_PRODUCT_SCOPE).

Error
404

No ZCTA has this code in the active publication (ZCTA_NOT_FOUND). The code may still be a valid USPS ZIP code: PO-box-only, single-building and non-residential ZIPs have no ZCTA. details.codes lists the codes not found.

Error
429

Per-minute rate limit exceeded (RATE_LIMIT_EXCEEDED) or monthly quota exhausted (QUOTA_EXCEEDED).

Error
503

A dataset this endpoint reads has no active publication yet (SERVICE_UNAVAILABLE, details.dataset_id).

Error

Counties

County profile

GET/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

NameInTypeDescription
fipsrequiredpathstring

5-digit county FIPS code (state + county).

Example: 25017

Responses

200

The county profile.

CountyResponse
400

Invalid parameter or body (VALIDATION_ERROR; details.fields maps each field to the reason) or malformed request (BAD_REQUEST).

Error
401

Missing or invalid API key (UNAUTHORIZED), or a disabled, expired or revoked one (API_KEY_DISABLED, API_KEY_EXPIRED, API_KEY_REVOKED).

Error
403

Organization suspended (ORGANIZATION_SUSPENDED), no live subscription (NO_ACTIVE_SUBSCRIPTION) , geo-demographics not on the plan (PRODUCT_NOT_ENABLED) or a key scoped to another product (API_KEY_PRODUCT_SCOPE).

Error
404

No county or county equivalent has this FIPS code in the active publication (COUNTY_NOT_FOUND).

Error
429

Per-minute rate limit exceeded (RATE_LIMIT_EXCEEDED) or monthly quota exhausted (QUOTA_EXCEEDED).

Error
503

A dataset this endpoint reads has no active publication yet (SERVICE_UNAVAILABLE, details.dataset_id).

Error
curl
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

GET/v1/geo-demographics/coverage

What 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 (UNAUTHORIZED), or a disabled, expired or revoked one (API_KEY_DISABLED, API_KEY_EXPIRED, API_KEY_REVOKED).

Error
403

Organization suspended (ORGANIZATION_SUSPENDED), no live subscription (NO_ACTIVE_SUBSCRIPTION) , geo-demographics not on the plan (PRODUCT_NOT_ENABLED) or a key scoped to another product (API_KEY_PRODUCT_SCOPE).

Error
429

Per-minute rate limit exceeded (RATE_LIMIT_EXCEEDED) or monthly quota exhausted (QUOTA_EXCEEDED).

Error
curl
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.

FieldTypeDescription
error *string

Human-readable message.

code *string

Stable machine-readable code.

productstring

Product that produced the error, when applicable.

detailsobject

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.

FieldTypeDescription
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 key parameter to run it); otherwise the file URL.

source_version *string

Publisher release of the source snapshot.

source_date *string (date) | null

Publisher as-of date of that snapshot (Census API dataset modified date; file Last-Modified for downloaded files).

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

FieldTypeDescription
dataset_id *DatasetId
publication_idinteger (int64)
published_at *string (date-time)
validation_statusenum: passed | passed_with_warnings
freshness *enum: fresh | stale

stale when the active publication is older than the dataset's expected maximum age (400 days for ACS and schools).

Coverage object

What the data behind this response covers and excludes.

FieldTypeDescription
geography_type *enum: zcta | county | school
scope *string
vintageVintage
school_yearstring | null

NCES school year of the school directory, for school responses.

excluded *array of string
notesarray of string

Notice object

FieldTypeDescription
code *enum: ZCTA_NOT_USPS_ZIP | ESTIMATE_PERIOD | SUPPRESSED_VALUES | RELATIONSHIP_VINTAGE | ZCTA_ASSIGNMENT_APPROXIMATE
message *string

Meta object

FieldTypeDescription
request_idstring
datasets *DatasetPublication []

Active publication of each dataset this response read.

coverage *Coverage
noticesNotice []

Caveats that apply to this response (always includes ZCTA_NOT_USPS_ZIP for location responses).

Vintage object

The ACS release a value comes from. Values describe this period, not the present.

FieldTypeDescription
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

FieldTypeDescription
dataset_id *DatasetId
source_id *enum: census.acs5
table_id *string
variables *array of string

ACS estimate variables used.

moe_variablestring | null
derived *boolean

True when Olympus computed the value from the variables (percentages); derived values have no published MOE.

formulastring | null

Metric object

FieldTypeDescription
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 null_reason).

moe *number | null

90% margin of error as published. Null for derived metrics and when not published (see moe_note).

moe_noteenum: controlled_estimate | open_ended_distribution | insufficient_sample | null

controlled_estimate: the estimate is controlled to an independent count and has no sampling error to show.

qualifier *enum: or_more | less_than | null

Set for medians in an open-ended interval; value is then the interval edge.

null_reason *enum: insufficient_sample | not_applicable | not_available | zero_universe | unknown_annotation | null
census_valuenumber | 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.

FieldTypeDescription
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).

FieldTypeDescription
occupied_housing_unitsinteger | null
owner_occupied_unitsinteger | null
renter_occupied_unitsinteger | null
population_25_plusinteger | null
poverty_universeinteger | null
below_povertyinteger | null
civilian_labor_forceinteger | null
unemployedinteger | null

GeographyRef object

The geography a value describes.

FieldTypeDescription
type *enum: zcta | county
id *string

5-digit ZCTA code or 5-digit county FIPS.

Point object

FieldTypeDescription
latitude *number
longitude *number

ZctaCounty object

One part of a ZCTA that lies in a county (Census 2020 relationship file, 2020 counties).

FieldTypeDescription
county_fips *string
county_namestring | null
state_fips *string
state_codestring | 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

FieldTypeDescription
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_sqminumber | 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_fipsstring | null
primary_state_codestring | null
geography_vintage *string
counties *ZctaCounty []

CountyGeography object

FieldTypeDescription
type *enum: county
id *string
county_fips *string
name *string
county_namestring | null
state_fips *string
state_codestring | null
land_area_sqmi *number | null
water_area_sqminumber | null
population_density_sqminumber | null
internal_point *Point
geography_vintage *string

LocationProfile object

FieldTypeDescription
geography *ZctaGeography
vintage *Vintage
summary *object

Headline metrics; see /demographics for all of them.

links *object
provenance *Provenance

Demographics object

FieldTypeDescription
geography *GeographyRef
namestring
vintage *Vintage
metrics *Metrics
counts *UniverseCounts
provenance *Provenance

CountyProfile object

FieldTypeDescription
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_notestring | 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.

FieldTypeDescription
ncessch *string

12-digit NCES school ID.

name *string
districtobject
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
phonestring | null
websitestring | null
enrollmentinteger | 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_codestring | null

NCES urban-centric locale code (e.g. 11 = City, Large).

school_year *string
provenance *Provenance

LocationResponse object

FieldTypeDescription
data *LocationProfile
meta *Meta

DemographicsResponse object

FieldTypeDescription
data *Demographics
meta *Meta

CountyResponse object

FieldTypeDescription
data *CountyProfile
meta *Meta

SchoolListResponse object

FieldTypeDescription
data *object
meta *Meta

CompareRequest object

FieldTypeDescription
locations *array of string

Exactly two distinct 5-digit ZCTA codes.

metricsMetricKey []

Metrics to compare; defaults to all.

Comparison object

FieldTypeDescription
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

FieldTypeDescription
data *object
meta *Meta

DatasetCoverage object

FieldTypeDescription
dataset_id *DatasetId
status *enum: fresh | stale | unpublished
publication_idinteger (int64) | null
published_atstring (date-time) | null
validation_statusenum: passed | passed_with_warnings | null
schema_versionstring
record_countinteger | null
coverage_description *string
coverageobject

Publication coverage, e.g. {"records": 33772, "acs_period": "2020-2024", "nulls_by_reason": {...}}.

sourcesarray of object

CoverageResponse object

FieldTypeDescription
data *object
meta *object

* required field