Raw schema
{
"type": "object",
"properties": {
"variables": {
"type": "array",
"items": {
"type": "string"
},
"description": "Variable codes to retrieve (e.g., [\"B19013_001E\", \"B19013_001M\"]). Codes are uppercased before the request, so \"b19013_001e\" reads as B19013_001E and the response is keyed by the uppercase code. At most 49 per call: the Census API accepts 50 columns per request and every query also sends NAME. On datasets where a label column is added for each filter dimension left unset, or record columns are added (cbp, ecnbasic, nonemp, pep/charv, dec/ddhca, acs/acs1/spp), the maximum is lower, and too_many_variables states the exact number for the query. Use census_search_variables to find codes. On ACS datasets only, apart from the comparison profiles (acs/acs5/cprofile, acs/acs1/cprofile), which publish none, each estimate has a margin-of-error counterpart at the same code with the E suffix swapped for M โ request both to get the margin alongside the estimate. Other dataset families (pep, dec, cbp, ecnbasic, nonemp) publish no margins of error, and an E-final code there is an ordinary code with no M sibling. A code can also name a text column rather than a measure โ GEO_ID, on every dataset, is the nationally unique geography identifier and comes back under value with estimate null, which is the code to request when a stable join key is what is wanted."
},
"geography_level": {
"type": "string",
"description": "Level of the target geography (e.g., \"county\", \"tract\", \"state\", \"zip code tabulation area\"). Use census_list_geographies to see valid values for the dataset."
},
"geography_fips": {
"type": "string",
"description": "FIPS code for the target geography (e.g., \"033\" for a county, \"*\" for every geography at the level within the parent, returned up to limit rows per call and paged with offset). Use census_resolve_geography to obtain this value โ it is returned as fips_summary. The Census API matches this literally and its width follows geography_level, so it is passed through unpadded: a county is 3 digits (\"051\", not \"51\") and a tract is 6. parent_fips and county_fips are zero-padded for you; this one is not."
},
"parent_fips": {
"description": "State FIPS code when querying sub-state levels (e.g., \"53\" for Washington). Required for county, tract, and block-group queries. census_resolve_geography returns this as state_fips. Pass \"*\" to span every state. Blank is treated as omitted.",
"anyOf": [
{
"type": "string",
"const": ""
},
{
"type": "string",
"pattern": "^(\\*|\\d{1,2})$",
"description": "1 to 2 digits, zero-padded here to the 2 the Census stores, or \"*\"."
}
]
},
"county_fips": {
"description": "County FIPS code when querying tracts or block groups within a specific county (e.g., \"033\" for King County within WA). Required for tract and block-group queries scoped to a county โ use alongside parent_fips (state). census_resolve_geography returns this as county_fips. Pass \"*\" to span every county in the state, which is the only way a block-group query reaches a whole state. Blank is treated as omitted.",
"anyOf": [
{
"type": "string",
"const": ""
},
{
"type": "string",
"pattern": "^(\\*|\\d{1,3})$",
"description": "1 to 3 digits, zero-padded here to the 3 the Census stores, or \"*\"."
}
]
},
"tract_fips": {
"description": "Census tract code scoping the query to one tract (e.g., \"007101\" for Census Tract 71.01), for the levels that sit within a tract โ block group on acs/acs5, block group and block on dec/pl. census_resolve_geography returns it as tract_fips, and for a street address also returns the block_group_fips to pass as geography_fips. A tract code is unique only within its county, so it needs parent_fips and a concrete county_fips (not \"*\"). It is exactly 6 digits and is not padded, since \"7101\" and \"71\" do not name one tract. A level that does not sit within a tract rejects it. Blank is treated as omitted.",
"anyOf": [
{
"type": "string",
"const": ""
},
{
"type": "string",
"pattern": "^\\d{6}$",
"description": "Exactly 6 digits โ never padded here, and never \"*\"."
}
]
},
"predicates": {
"description": "Filter values keyed by variable code, sent as extra query parameters โ e.g. {\"NAICS2017\": \"5112\"} to count only software publishers in cbp. The business datasets (cbp, ecnbasic, nonemp), pep/charv, dec/ddhca, and acs/acs1/spp declare filter dimensions such as industry (NAICS2017/NAICS2022), legal form (LFO), size class (EMPSZES/RCPSZES), tax status (TAXSTAT), operation type (TYPOP), sex (SEX), age (AGE), and population group (POPGROUP). Leaving one unset is not an error: the Census API substitutes its own default, which is the all-categories total on cbp NAICS2017 but a single population group on dec/ddhca POPGROUP and a single sector on ecnbasic NAICS2022 โ so an unfiltered value can read like a total without being one. Every unset dimension is named in the response notice and its applied default is echoed per row in applied_filters. Keys are matched case-insensitively, and a blank value is treated as omitted. A value of \"*\" returns one row per category of that dimension for each geography, each row labelled with its category in record (e.g. {\"NAICS2017\": \"*\"} gives King County one row per industry) โ a breakdown that can run to over a thousand rows. Code names vary by dataset and vintage โ cbp 2023 uses NAICS2017 while nonemp 2023 uses NAICS2022 โ so read them from the notice or from census_search_variables. Call census_list_predicate_values for the codes a dimension accepts; NAICS values are standard North American Industry Classification System codes at any depth (51 information, 5112 software publishers).",
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": "string"
}
},
"dataset": {
"description": "Dataset to query (default: \"acs/acs5\"). Use census_list_datasets to discover valid values. Case is ignored, and a two-part code can be given by its last part alone โ \"acs5\" is acs/acs5, \"pl\" is dec/pl. Three-part codes such as acs/acs5/profile must be given in full. The response echoes the resolved code.",
"type": "string"
},
"year": {
"description": "Vintage year (default: latest available for the dataset).",
"type": "number"
},
"limit": {
"description": "Most rows to return (default: 50, max: 500). Rows come in GEOID order, a geography's records or categories in code order, and each one counts, so a geography returned as several records (pep/charv April and July) or as one row per category of a \"*\" predicate takes one row each. totalCount says how many rows matched.",
"type": "integer",
"minimum": 1,
"maximum": 500
},
"offset": {
"description": "Rows to skip before returning up to limit (default: 0). Pages run in GEOID order, so offset 50 with limit 50 returns rows 51โ100, and the notice names the offset of the next page. An offset at or past totalCount returns no rows.",
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
}
},
"required": [
"variables",
"geography_level",
"geography_fips"
],
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false
}