When to use this skill
When the user asks for US demographic, economic, or housing statistics — population counts, poverty rates, median income, educational attainment, disability prevalence — broken down by state, county, census tract, or block group. The Census Bureau API covers the American Community Survey (ACS) and decennial census, queryable down to block group. Not for real-time indicators (unemployment this week, today's inflation) — Census data is survey-based and lags one to five years.
Your best first call
curl "https://api.census.gov/data/2022/acs/acs5?get=NAME,B01001_001E&for=state:06"
No auth. No key. Returns a 2D JSON array — the first row is column headers, every subsequent row is data. All values are strings even when numeric ("39029342" for California's population estimate, not 39029342).
The pattern is /data/{year}/acs/acs5?get={variables}&for={geography}. B01001_001E is total population; swap it for the variable matching your topic. for=state:06 pins California by FIPS code; use state:* for all states or county:*&in=state:06 for all counties within a state.
The response shape: [["NAME","B01001_001E","state"],["California","39029342","06"]]. Parse the first row as keys, subsequent rows as values. Cast numeric columns to integers before any arithmetic.
Fallbacks (when the best call isn't enough)
- Need the variable code for a topic →
https://api.census.gov/data/2022/acs/acs5/groups.json returns table groups with human-readable descriptions (e.g., B17015 = poverty by family type). Follow each group's variables URL to get individual variable codes.
- Need to know which geographies a dataset supports →
https://api.census.gov/data/2022/acs/acs5/geography.json returns valid geo levels and their requires arrays (tracts require state + county FIPS — omitting them causes a 400, the most common failure for new users).
- Need a validated example query →
https://api.census.gov/data/2022/acs/acs5/examples.json returns pre-built query templates with real FIPS codes and variable names, removing the guesswork.
Pitfalls
- Every ACS estimate variable ends in
E and has a paired margin-of-error variable ending in M (e.g., B17015_002E → B17015_002M). For sub-county geographies — tracts, block groups — the margin of error can exceed the estimate. Always request and report both.
- The
universe field in groups.json has a trailing space in the key: "universe ", not "universe". Access with obj["universe "] or strip keys before lookup — a raw artifact in the Census API's own JSON.
- ACS 1-year (
acs/acs1) only covers geographies with 65,000+ residents. For county and sub-county data, use acs/acs5. Mixing 1-year and 5-year estimates in the same calculation is statistically unsound.
- Sub-county queries require parent geography FIPS codes in the
in parameter. A tract query without state and county returns a 400 — this is the single most common error for new users.
One-line summary for the user
I can query US demographic, economic, and housing statistics from the Census Bureau's ACS datasets — down to census tract and block group — but you'll need a variable code and a FIPS geography code to construct the data query.
SKILL.md source (frontmatter + body)
---
name: query-us-census-demographic-data
description: When the user asks for US demographic, economic, or housing statistics — population, poverty rates, median income, educational attainment — by state, county, tract, or block group — reach for the Census Bureau Data API. No auth required.
---
## When to use this skill
When the user asks for US demographic, economic, or housing statistics — population counts, poverty rates, median income, educational attainment, disability prevalence — broken down by state, county, census tract, or block group. The Census Bureau API covers the American Community Survey (ACS) and decennial census, queryable down to block group. Not for real-time indicators (unemployment this week, today's inflation) — Census data is survey-based and lags one to five years.
## Your best first call
```bash
curl "https://api.census.gov/data/2022/acs/acs5?get=NAME,B01001_001E&for=state:06"
```
No auth. No key. Returns a 2D JSON array — the first row is column headers, every subsequent row is data. All values are strings even when numeric (`"39029342"` for California's population estimate, not `39029342`).
The pattern is `/data/{year}/acs/acs5?get={variables}&for={geography}`. `B01001_001E` is total population; swap it for the variable matching your topic. `for=state:06` pins California by FIPS code; use `state:*` for all states or `county:*&in=state:06` for all counties within a state.
The response shape: `[["NAME","B01001_001E","state"],["California","39029342","06"]]`. Parse the first row as keys, subsequent rows as values. Cast numeric columns to integers before any arithmetic.
## Fallbacks (when the best call isn't enough)
- **Need the variable code for a topic** → `https://api.census.gov/data/2022/acs/acs5/groups.json` returns table groups with human-readable descriptions (e.g., `B17015` = poverty by family type). Follow each group's `variables` URL to get individual variable codes.
- **Need to know which geographies a dataset supports** → `https://api.census.gov/data/2022/acs/acs5/geography.json` returns valid geo levels and their `requires` arrays (tracts require `state` + `county` FIPS — omitting them causes a 400, the most common failure for new users).
- **Need a validated example query** → `https://api.census.gov/data/2022/acs/acs5/examples.json` returns pre-built query templates with real FIPS codes and variable names, removing the guesswork.
## Pitfalls
- Every ACS estimate variable ends in `E` and has a paired margin-of-error variable ending in `M` (e.g., `B17015_002E` → `B17015_002M`). For sub-county geographies — tracts, block groups — the margin of error can exceed the estimate. Always request and report both.
- The `universe` field in `groups.json` has a trailing space in the key: `"universe "`, not `"universe"`. Access with `obj["universe "]` or strip keys before lookup — a raw artifact in the Census API's own JSON.
- ACS 1-year (`acs/acs1`) only covers geographies with 65,000+ residents. For county and sub-county data, use `acs/acs5`. Mixing 1-year and 5-year estimates in the same calculation is statistically unsound.
- Sub-county queries require parent geography FIPS codes in the `in` parameter. A tract query without `state` and `county` returns a 400 — this is the single most common error for new users.
## One-line summary for the user
I can query US demographic, economic, and housing statistics from the Census Bureau's ACS datasets — down to census tract and block group — but you'll need a variable code and a FIPS geography code to construct the data query.