Skip to main content
Glama

Query Census Data

census_query_data
Read-only

Query a Census dataset for one or more variables at one geography, a list of geographies at the same level, or every geography at a level. Accepts FIPS codes for the target geography — use census_resolve_geography to convert place names to FIPS when needed. On ACS datasets, labeled estimates and margin-of-error values are returned together (the comparison profiles publish no margins), and the negative sentinel values the Census writes for an estimate or margin of error it cannot publish are decoded into the meanings the Census gives them rather than passed through as raw numbers. A value cbp, ecnbasic, or nonemp withheld is stored as 0 beside a flag, and is reported as withheld, with the meaning of its flag, rather than as a zero. Pass geography_fips as "*" for every geography at the level within the parent, or as a comma-separated list of codes ("06,53") for several: rows come back in GEOID order, up to limit per call (default 50, max 500), with totalCount giving how many matched and offset reaching the rest — the order is not a ranking, so use census_compare_geographies to rank. The notice names any listed code that no row came back for. On the business datasets (cbp, ecnbasic, nonemp), pep/charv, dec/ddhca, dec/ddhcb, and acs/acs1/spp, use predicates to filter by industry, size class, or population group — a query that omits one is answered with a default the Census API picks, which is an all-categories total on some dimensions and a single category on others. Each row names the defaults that were applied in applied_filters, and census_list_predicate_values enumerates the codes a dimension accepts. Some dec/ddhca and dec/ddhcb tables split the population groups between them, publishing each group at a geography in only one table of the family, so where a result can be missing a group, a geography, or a value, the notice names the sibling tables to look in. One geography can also come back on more than one row: pep/charv publishes an April estimates base alongside its July estimate, and each row carries a record field saying which it is.

Input Schema

NameRequiredDescriptionDefault
yearNoVintage year (default: latest available for the dataset).
limitNoMost rows to return (default: 50, max: 500). Rows come in GEOID order, whether geography_fips is "*" or a comma-separated list, 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.
offsetNoRows 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.
datasetNoDataset 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.
variablesYesVariable codes to retrieve (e.g., ["B19013_001E", "B19013_001M"]). Codes are matched regardless of case and sent in the dataset's own spelling, which keys the response: "b19013_001e" reads as B19013_001E, and "cp03_2024to2019_062ss" as the comparison profiles' mixed-case significance column CP03_2024to2019_062SS. A code the dataset does not list is sent uppercased. 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, dec/ddhcb, 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.
predicatesNoFilter 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, dec/ddhcb, 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 and dec/ddhcb 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).
tract_fipsNoCensus 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.
county_fipsNoCounty 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; "*" works on the levels whose hierarchy lets it stand in for the county, such as tract and block group, and never under a tract_fips. Blank is treated as omitted.
parent_fipsNoState 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 on the levels whose hierarchy lets "*" stand in for the state, such as county and place; tract, block group, and county subdivision need one state. Blank is treated as omitted.
geography_fipsYesFIPS 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. Several codes at the same level can be joined with commas — "06,53" for two states, or "033,061" with parent_fips "53" for two counties — each at the level's width, none of them "*", and with the parents a single code needs. Spaces around a code are ignored and a repeated code returns one row. Rows come back in GEOID order, not list order, paged by limit and offset with totalCount, and the notice names each code no row came back for. On dec/ddhca and dec/ddhcb tables that split the population groups between them, a code whose group is published in a sibling table there has no row, and the notice names the tables to look in.
geography_levelYesLevel of the target geography (e.g., "county", "tract", "state", "zip code tabulation area"). Use census_list_geographies to see valid values for the dataset.

Output Schema

NameRequiredDescriptionDefault
rowsNoOne row per geography, or per record or category where a geography has several. When geography_fips is "*", the rows from offset up to limit of every geography at the level within the parent, in GEOID order; when it is a comma-separated list, the rows of the listed geographies the Census returned, in the same order and paging.
yearNoVintage year queried.
errorNoPresent when the call failed. Absent on success.
noticeNoWarning that the dataset declares filter dimensions the query left unset, naming each one alongside the label of the default the Census API applied to it. That default is an all-categories total on some dimensions and one ordinary category on others, so the label is what says which. Also carries the warning that a geography came back on more than one row, naming the column that separates the records and the values it took; the codes of a comma-separated geography_fips that no row came back for; the range of rows returned when offset or limit left some out, with the offset of the next page; the sibling tables a missing group, geography, or value may sit in, on dec/ddhca and dec/ddhcb tables that split the population groups between them; and any variable codes whose flags could not be checked because the request had no room left under the Census 50-column limit — a withheld value there reads as 0.
datasetNoDataset queried.
totalRowsNoNumber of rows returned.
truncatedNoTrue when rows were left out by offset or limit — totalCount exceeds the rows returned.
totalCountNoNumber of rows the query matched, before offset and limit were applied.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed7 schema fields changed
    • changedInput schema / properties / county_fips / description
      Previous value: -"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."New value: +"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; \"*\" works on the levels whose hierarchy lets it stand in for the county, such as tract and block group, and never under a tract_fips. Blank is treated as omitted."
    • changedInput schema / properties / geography_fips / description
      Previous value: -"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."New value: +"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. Several codes at the same level can be joined with commas — \"06,53\" for two states, or \"033,061\" with parent_fips \"53\" for two counties — each at the level's width, none of them \"*\", and with the parents a single code needs. Spaces around a code are ignored and a repeated code returns one row. Rows come back in GEOID order, not list order, paged by limit and offset with totalCount, and the notice names each code no row came back for. On dec/ddhca and dec/ddhcb tables that split the population groups between them, a code whose group is published in a sibling table there has no row, and the notice names the tables to look in."
    • changedInput schema / properties / limit / description
      Previous value: -"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."New value: +"Most rows to return (default: 50, max: 500). Rows come in GEOID order, whether geography_fips is \"*\" or a comma-separated list, 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."
    • changedInput schema / properties / parent_fips / description
      Previous value: -"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."New value: +"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 on the levels whose hierarchy lets \"*\" stand in for the state, such as county and place; tract, block group, and county subdivision need one state. Blank is treated as omitted."
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `dataset_not_found`: Dataset code is not recognized, even after case and shorthand resolution. `missing_api_key`: CENSUS_API_KEY is not configured or the key is invalid. `year_not_available`: The dataset does not serve the requested vintage year. `variable_not_found`: The Census API rejected a variable code as unknown for the requested dataset and year. It names only the first unknown code in a request. `variables_unavailable`: The variable metadata endpoint returned an unparseable response for this dataset and year. `geography_not_supported`: The requested geography level does not exist in this dataset and year. `parent_required`: The geography level requires a parent FIPS code but parent_fips was not provided, a tract/block-group level requires county_fips but it was omitted, a single block group requires tract_fips, or tract_fips was set without a concrete county_fips. `parent_not_accepted`: parent_fips, county_fips, or tract_fips names a parent the geography level does not sit within. `no_data`: The query returned no rows. `too_many_variables`: The variable codes plus NAME and the label and record columns added for the dataset exceed the 50 columns the Census API accepts per request. `predicate_not_supported`: A key in predicates is not a variable in this dataset and year. `upstream_error`: Census API returned an error or was unreachable. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `dataset_not_found`: Dataset code is not recognized, even after case and shorthand resolution. `missing_api_key`: CENSUS_API_KEY is not configured or the key is invalid. `year_not_available`: The dataset does not serve the requested vintage year. `variable_not_found`: The Census API rejected a variable code as unknown for the requested dataset and year. It names only the first unknown code in a request. `variables_unavailable`: The variable metadata endpoint returned an unparseable response for this dataset and year. `geography_not_supported`: The requested geography level does not exist in this dataset and year. `parent_required`: The geography level requires a parent FIPS code but parent_fips was not provided, a tract/block-group level requires county_fips but it was omitted, a single block group requires tract_fips, tract_fips was set without a concrete county_fips, or parent_fips or county_fips is \"*\" where the level's hierarchy does not let \"*\" stand in for that parent. For a level the dataset lists under several hierarchies, no hierarchy accepts the call and the error describes the one closest to accepting it, which can need a \"*\" geography_fips or a parent this tool has no input for. When that hierarchy also does not take a parent the call supplied, the error names that parent to drop as well. `parent_not_accepted`: parent_fips, county_fips, or tract_fips names a parent the geography level does not sit within — for a level listed under several hierarchies, one that dropping the parent reaches. `no_data`: The query returned no rows. `too_many_variables`: The variable codes plus NAME and the label and record columns added for the dataset exceed the 50 columns the Census API accepts per request. `predicate_not_supported`: A key in predicates is not a variable in this dataset and year. `upstream_error`: Census API returned an error, was unreachable, or did not finish answering the data request within its 40-second limit across retries. Other values are possible when a failure originates below the handler."
    • changedOutput schema / properties / notice / description
      Previous value: -"Warning that the dataset declares filter dimensions the query left unset, naming each one alongside the label of the default the Census API applied to it. That default is an all-categories total on some dimensions and one ordinary category on others, so the label is what says which. Also carries the warning that a geography came back on more than one row, naming the column that separates the records and the values it took; the range of rows returned when offset or limit left some out, with the offset of the next page; the sibling tables a missing group, geography, or value may sit in, on dec/ddhca and dec/ddhcb tables that split the population groups between them; and any variable codes whose flags could not be checked because the request had no room left under the Census 50-column limit — a withheld value there reads as 0."New value: +"Warning that the dataset declares filter dimensions the query left unset, naming each one alongside the label of the default the Census API applied to it. That default is an all-categories total on some dimensions and one ordinary category on others, so the label is what says which. Also carries the warning that a geography came back on more than one row, naming the column that separates the records and the values it took; the codes of a comma-separated geography_fips that no row came back for; the range of rows returned when offset or limit left some out, with the offset of the next page; the sibling tables a missing group, geography, or value may sit in, on dec/ddhca and dec/ddhcb tables that split the population groups between them; and any variable codes whose flags could not be checked because the request had no room left under the Census 50-column limit — a withheld value there reads as 0."
    • changedOutput schema / properties / rows / description
      Previous value: -"One row per geography, or per record or category where a geography has several. When geography_fips is \"*\", the rows from offset up to limit of every geography at the level within the parent, in GEOID order."New value: +"One row per geography, or per record or category where a geography has several. When geography_fips is \"*\", the rows from offset up to limit of every geography at the level within the parent, in GEOID order; when it is a comma-separated list, the rows of the listed geographies the Census returned, in the same order and paging."
  2. Changed5 schema fields changed
    • changedInput schema / properties / predicates / description
      Previous value: -"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)."New value: +"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, dec/ddhcb, 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 and dec/ddhcb 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)."
    • changedInput schema / properties / variables / description
      Previous value: -"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."New value: +"Variable codes to retrieve (e.g., [\"B19013_001E\", \"B19013_001M\"]). Codes are matched regardless of case and sent in the dataset's own spelling, which keys the response: \"b19013_001e\" reads as B19013_001E, and \"cp03_2024to2019_062ss\" as the comparison profiles' mixed-case significance column CP03_2024to2019_062SS. A code the dataset does not list is sent uppercased. 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, dec/ddhcb, 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."
    • changedOutput schema / properties / notice / description
      Previous value: -"Warning that the dataset declares filter dimensions the query left unset, naming each one alongside the label of the default the Census API applied to it. That default is an all-categories total on some dimensions and one ordinary category on others, so the label is what says which. Also carries the warning that a geography came back on more than one row, naming the column that separates the records and the values it took; the range of rows returned when offset or limit left some out, with the offset of the next page; and any variable codes whose flags could not be checked because the request had no room left under the Census 50-column limit — a withheld value there reads as 0."New value: +"Warning that the dataset declares filter dimensions the query left unset, naming each one alongside the label of the default the Census API applied to it. That default is an all-categories total on some dimensions and one ordinary category on others, so the label is what says which. Also carries the warning that a geography came back on more than one row, naming the column that separates the records and the values it took; the range of rows returned when offset or limit left some out, with the offset of the next page; the sibling tables a missing group, geography, or value may sit in, on dec/ddhca and dec/ddhcb tables that split the population groups between them; and any variable codes whose flags could not be checked because the request had no room left under the Census 50-column limit — a withheld value there reads as 0."
    • changedOutput schema / properties / rows / items / properties / applied_filters / description
      Previous value: -"Filter dimensions the query left unset, mapped to the label of the default the Census API applied (e.g. {\"POPGROUP\": \"European alone\"}). Present only on datasets that declare filter dimensions. The label is what tells an all-categories total apart from one ordinary category — dec/ddhca defaults POPGROUP to a single population group, so a value carrying \"European alone\" is that group's count and not the geography's population. Set the dimension in predicates to choose it yourself."New value: +"Filter dimensions the query left unset, mapped to the label of the default the Census API applied (e.g. {\"POPGROUP\": \"European alone\"}). Present only on datasets that declare filter dimensions. The label is what tells an all-categories total apart from one ordinary category — dec/ddhca and dec/ddhcb default POPGROUP to a single population group, so a value carrying \"European alone\" is that group's count and not the geography's population. Set the dimension in predicates to choose it yourself."
    • changedOutput schema / properties / rows / items / properties / variables / description
      Previous value: -"Map of variable code to value entry. Each key is a variable code from the variables input, uppercased; each value has: estimate (number|null), moe (number|null, optional), label (string), suppressed (boolean), suppression_reason (string, optional), open_ended (true, optional), flag ({code, meaning}, optional), value (string, optional). An estimate of null means one of three things and the other fields say which: suppressed true is a number the Census withheld, a value field is a cell holding text rather than a number (GEO_ID returns \"0500000US53033\"; the older ACS profile vintages write not-applicable as \"(X)\" in a column that is a number elsewhere), and neither is a cell with nothing in it. suppression_reason carries the meaning the Census publishes for the sentinel or flag. On ACS, a margin of error the Census treats as zero (a controlled estimate) is moe 0, not a suppression. open_ended true marks an ACS median that falls in the lowest or highest interval of an open-ended distribution, so the estimate is that interval's boundary (250001 for \"250,000+\", 9999 for \"10,000-\") rather than the median itself — it appears only when the matching M code was requested, since that margin of error is the only signal, and it does not say which end. flag is the symbol a business dataset (cbp, ecnbasic, nonemp) published beside the value: a withholding flag (D, S, an employment or sales range letter) comes with suppressed true, and so does a noise or data-quality band (G/H/J, 0-9) beside a 0, which is the range a range column such as EMP_N or RCPTOT_IMP publishes in place of a number; a quality note (r revised, s high relative standard error) keeps the estimate."New value: +"Map of variable code to value entry. Each key is a variable code from the variables input, in the dataset's spelling — uppercase except the comparison profiles' significance columns (CP03_2024to2019_062SS); each value has: estimate (number|null), moe (number|null, optional), label (string), suppressed (boolean), suppression_reason (string, optional), open_ended (true, optional), flag ({code, meaning}, optional), value (string, optional). An estimate of null means one of three things and the other fields say which: suppressed true is a number the Census withheld, a value field is a cell holding text rather than a number (GEO_ID returns \"0500000US53033\"; the older ACS profile vintages write not-applicable as \"(X)\" in a column that is a number elsewhere), and neither is a cell with nothing in it. suppression_reason carries the meaning the Census publishes for the sentinel or flag. On ACS, a margin of error the Census treats as zero (a controlled estimate) is moe 0, not a suppression. open_ended true marks an ACS median that falls in the lowest or highest interval of an open-ended distribution, so the estimate is that interval's boundary (250001 for \"250,000+\", 9999 for \"10,000-\") rather than the median itself — it appears only when the matching M code was requested, since that margin of error is the only signal, and it does not say which end. flag is the symbol a business dataset (cbp, ecnbasic, nonemp) published beside the value: a withholding flag (D, S, an employment or sales range letter) comes with suppressed true, and so does a noise or data-quality band (G/H/J, 0-9) beside a 0, which is the range a range column such as EMP_N or RCPTOT_IMP publishes in place of a number; a quality note (r revised, s high relative standard error) keeps the estimate."
  3. Changed4 schema fields changed
    • changedInput schema / properties / dataset / description
      Previous value: -"Dataset to query (default: \"acs/acs5\"). Use census_list_datasets to discover valid values."New value: +"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."
    • changedInput schema / properties / predicates / description
      Previous value: -"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, and dec/ddhca 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)."New value: +"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)."
    • changedInput schema / properties / variables / description
      Previous value: -"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), 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, 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."New value: +"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."
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `dataset_not_found`: Dataset code is not recognized. `missing_api_key`: CENSUS_API_KEY is not configured or the key is invalid. `year_not_available`: The dataset does not serve the requested vintage year. `variable_not_found`: The Census API rejected a variable code as unknown for the requested dataset and year. It names only the first unknown code in a request. `variables_unavailable`: The variable metadata endpoint returned an unparseable response for this dataset and year. `geography_not_supported`: The requested geography level does not exist in this dataset and year. `parent_required`: The geography level requires a parent FIPS code but parent_fips was not provided, a tract/block-group level requires county_fips but it was omitted, a single block group requires tract_fips, or tract_fips was set without a concrete county_fips. `parent_not_accepted`: parent_fips, county_fips, or tract_fips names a parent the geography level does not sit within. `no_data`: The query returned no rows. `too_many_variables`: The variable codes plus NAME and the label and record columns added for the dataset exceed the 50 columns the Census API accepts per request. `predicate_not_supported`: A key in predicates is not a variable in this dataset and year. `upstream_error`: Census API returned an error or was unreachable. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `dataset_not_found`: Dataset code is not recognized, even after case and shorthand resolution. `missing_api_key`: CENSUS_API_KEY is not configured or the key is invalid. `year_not_available`: The dataset does not serve the requested vintage year. `variable_not_found`: The Census API rejected a variable code as unknown for the requested dataset and year. It names only the first unknown code in a request. `variables_unavailable`: The variable metadata endpoint returned an unparseable response for this dataset and year. `geography_not_supported`: The requested geography level does not exist in this dataset and year. `parent_required`: The geography level requires a parent FIPS code but parent_fips was not provided, a tract/block-group level requires county_fips but it was omitted, a single block group requires tract_fips, or tract_fips was set without a concrete county_fips. `parent_not_accepted`: parent_fips, county_fips, or tract_fips names a parent the geography level does not sit within. `no_data`: The query returned no rows. `too_many_variables`: The variable codes plus NAME and the label and record columns added for the dataset exceed the 50 columns the Census API accepts per request. `predicate_not_supported`: A key in predicates is not a variable in this dataset and year. `upstream_error`: Census API returned an error or was unreachable. Other values are possible when a failure originates below the handler."
  4. Changed2 schema fields changed
    • addedInput schema / properties / tract_fips
      Added value: +{
      +  "anyOf": [
      +    {
      +      "const": "",
      +      "type": "string"
      +    },
      +    {
      +      "description": "Exactly 6 digits — never padded here, and never \"*\".",
      +      "pattern": "^\\d{6}$",
      +      "type": "string"
      +    }
      +  ],
      +  "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."
      +}
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `dataset_not_found`: Dataset code is not recognized. `missing_api_key`: CENSUS_API_KEY is not configured or the key is invalid. `year_not_available`: The dataset does not serve the requested vintage year. `variable_not_found`: The Census API rejected a variable code as unknown for the requested dataset and year. It names only the first unknown code in a request. `variables_unavailable`: The variable metadata endpoint returned an unparseable response for this dataset and year. `geography_not_supported`: The requested geography level does not exist in this dataset and year. `parent_required`: The geography level requires a parent FIPS code but parent_fips was not provided, or a tract/block-group level requires county_fips but it was omitted. `parent_not_accepted`: parent_fips or county_fips names a parent the geography level does not sit within. `no_data`: The query returned no rows. `too_many_variables`: The variable codes plus NAME and the label and record columns added for the dataset exceed the 50 columns the Census API accepts per request. `predicate_not_supported`: A key in predicates is not a variable in this dataset and year. `upstream_error`: Census API returned an error or was unreachable. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `dataset_not_found`: Dataset code is not recognized. `missing_api_key`: CENSUS_API_KEY is not configured or the key is invalid. `year_not_available`: The dataset does not serve the requested vintage year. `variable_not_found`: The Census API rejected a variable code as unknown for the requested dataset and year. It names only the first unknown code in a request. `variables_unavailable`: The variable metadata endpoint returned an unparseable response for this dataset and year. `geography_not_supported`: The requested geography level does not exist in this dataset and year. `parent_required`: The geography level requires a parent FIPS code but parent_fips was not provided, a tract/block-group level requires county_fips but it was omitted, a single block group requires tract_fips, or tract_fips was set without a concrete county_fips. `parent_not_accepted`: parent_fips, county_fips, or tract_fips names a parent the geography level does not sit within. `no_data`: The query returned no rows. `too_many_variables`: The variable codes plus NAME and the label and record columns added for the dataset exceed the 50 columns the Census API accepts per request. `predicate_not_supported`: A key in predicates is not a variable in this dataset and year. `upstream_error`: Census API returned an error or was unreachable. Other values are possible when a failure originates below the handler."
  5. Changed14 schema fields changed
    • changedInput schema / properties / geography_fips / description
      Previous value: -"FIPS code for the target geography (e.g., \"033\" for a county, \"*\" for all geographies at the level within the parent). 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."New value: +"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."
    • addedInput schema / properties / limit
      Added value: +{
      +  "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.",
      +  "maximum": 500,
      +  "minimum": 1,
      +  "type": "integer"
      +}
    • addedInput schema / properties / offset
      Added value: +{
      +  "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.",
      +  "maximum": 9007199254740991,
      +  "minimum": 0,
      +  "type": "integer"
      +}
    • changedInput schema / properties / predicates / description
      Previous value: -"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, and dec/ddhca 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. 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)."New value: +"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, and dec/ddhca 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)."
    • changedInput schema / properties / variables / description
      Previous value: -"Variable codes to retrieve (e.g., [\"B19013_001E\", \"B19013_001M\"]). Max 50 per request. Use census_search_variables to find codes. On ACS datasets only, 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."New value: +"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), 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, 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."
    • changedOutput schema / anyOf
      Previous value: -[
      -  {
      -    "not": {
      -      "required": [
      -        "error"
      -      ]
      -    },
      -    "required": [
      -      "rows",
      -      "totalRows",
      -      "dataset",
      -      "year"
      -    ]
      -  },
      -  {
      -    "required": [
      -      "error"
      -    ]
      -  }
      -]New value: +[
      +  {
      +    "not": {
      +      "required": [
      +        "error"
      +      ]
      +    },
      +    "required": [
      +      "rows",
      +      "totalRows",
      +      "totalCount",
      +      "truncated",
      +      "dataset",
      +      "year"
      +    ]
      +  },
      +  {
      +    "required": [
      +      "error"
      +    ]
      +  }
      +]
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `dataset_not_found`: Dataset code is not recognized. `missing_api_key`: CENSUS_API_KEY is not configured or the key is invalid. `year_not_available`: The dataset does not serve the requested vintage year. `variable_not_found`: One or more variable codes do not exist in the requested dataset and year. `variables_unavailable`: The variable metadata endpoint returned an unparseable response for this dataset and year. `geography_not_supported`: The requested geography level does not exist in this dataset and year. `parent_required`: The geography level requires a parent FIPS code but parent_fips was not provided, or a tract/block-group level requires county_fips but it was omitted. `parent_not_accepted`: parent_fips or county_fips names a parent the geography level does not sit within. `no_data`: The query returned no rows. `too_many_variables`: More than 50 variable codes were requested. `predicate_not_supported`: A key in predicates is not a variable in this dataset and year. `upstream_error`: Census API returned an error or was unreachable. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `dataset_not_found`: Dataset code is not recognized. `missing_api_key`: CENSUS_API_KEY is not configured or the key is invalid. `year_not_available`: The dataset does not serve the requested vintage year. `variable_not_found`: The Census API rejected a variable code as unknown for the requested dataset and year. It names only the first unknown code in a request. `variables_unavailable`: The variable metadata endpoint returned an unparseable response for this dataset and year. `geography_not_supported`: The requested geography level does not exist in this dataset and year. `parent_required`: The geography level requires a parent FIPS code but parent_fips was not provided, or a tract/block-group level requires county_fips but it was omitted. `parent_not_accepted`: parent_fips or county_fips names a parent the geography level does not sit within. `no_data`: The query returned no rows. `too_many_variables`: The variable codes plus NAME and the label and record columns added for the dataset exceed the 50 columns the Census API accepts per request. `predicate_not_supported`: A key in predicates is not a variable in this dataset and year. `upstream_error`: Census API returned an error or was unreachable. Other values are possible when a failure originates below the handler."
    • changedOutput schema / properties / notice / description
      Previous value: -"Warning that the dataset declares filter dimensions the query left unset, naming each one alongside the label of the default the Census API applied to it. That default is an all-categories total on some dimensions and one ordinary category on others, so the label is what says which. Also carries the warning that a geography came back on more than one row, naming the column that separates the records and the values it took."New value: +"Warning that the dataset declares filter dimensions the query left unset, naming each one alongside the label of the default the Census API applied to it. That default is an all-categories total on some dimensions and one ordinary category on others, so the label is what says which. Also carries the warning that a geography came back on more than one row, naming the column that separates the records and the values it took; the range of rows returned when offset or limit left some out, with the offset of the next page; and any variable codes whose flags could not be checked because the request had no room left under the Census 50-column limit — a withheld value there reads as 0."
    • changedOutput schema / properties / rows / description
      Previous value: -"One row per geography. When geography_fips is \"*\", includes all geographies at the level within the parent."New value: +"One row per geography, or per record or category where a geography has several. When geography_fips is \"*\", the rows from offset up to limit of every geography at the level within the parent, in GEOID order."
    • changedOutput schema / properties / rows / items / properties / record / description
      Previous value: -"Which record this row is, for a dataset that publishes more than one per geography — keyed by the column that separates them, each value carrying a code and a label (e.g. {\"MONTH\": {\"code\": \"7\", \"label\": \"July\"}}). pep/charv publishes an April estimates base and a July estimate, so one geography comes back on two rows whose numbers differ; this field is what says which is which. Pass the code back in predicates (e.g. {\"MONTH\": \"7\"}) to return that record alone. Absent on the datasets that return one row per geography."New value: +"Which record this row is, when one geography comes back on more than one row — keyed by the column that separates them, each value carrying a code and a label (e.g. {\"MONTH\": {\"code\": \"7\", \"label\": \"July\"}}). pep/charv publishes an April estimates base and a July estimate, so one geography comes back on two rows whose numbers differ; this field is what says which is which. A dimension set to \"*\" in predicates lands here too, one row per category (e.g. {\"NAICS2017\": {\"code\": \"11\", \"label\": \"Agriculture, forestry, fishing and hunting\"}}), with the code as its label when the dimension publishes no label column. Pass the code back in predicates (e.g. {\"MONTH\": \"7\"}) to return that record alone. Absent on the datasets that return one row per geography."
    • changedOutput schema / properties / rows / items / properties / variables / description
      Previous value: -"Map of variable code to value entry. Each key is a variable code from the variables input; each value has: estimate (number|null), moe (number|null, optional), label (string), suppressed (boolean), suppression_reason (string, optional), value (string, optional). An estimate of null means one of three things and the other fields say which: suppressed true is a number the Census withheld, a value field is a cell holding text rather than a number (GEO_ID returns \"0500000US53033\"; the older ACS profile vintages write not-applicable as \"(X)\" in a column that is a number elsewhere), and neither is a cell with nothing in it."New value: +"Map of variable code to value entry. Each key is a variable code from the variables input, uppercased; each value has: estimate (number|null), moe (number|null, optional), label (string), suppressed (boolean), suppression_reason (string, optional), open_ended (true, optional), flag ({code, meaning}, optional), value (string, optional). An estimate of null means one of three things and the other fields say which: suppressed true is a number the Census withheld, a value field is a cell holding text rather than a number (GEO_ID returns \"0500000US53033\"; the older ACS profile vintages write not-applicable as \"(X)\" in a column that is a number elsewhere), and neither is a cell with nothing in it. suppression_reason carries the meaning the Census publishes for the sentinel or flag. On ACS, a margin of error the Census treats as zero (a controlled estimate) is moe 0, not a suppression. open_ended true marks an ACS median that falls in the lowest or highest interval of an open-ended distribution, so the estimate is that interval's boundary (250001 for \"250,000+\", 9999 for \"10,000-\") rather than the median itself — it appears only when the matching M code was requested, since that margin of error is the only signal, and it does not say which end. flag is the symbol a business dataset (cbp, ecnbasic, nonemp) published beside the value: a withholding flag (D, S, an employment or sales range letter) comes with suppressed true, and so does a noise or data-quality band (G/H/J, 0-9) beside a 0, which is the range a range column such as EMP_N or RCPTOT_IMP publishes in place of a number; a quality note (r revised, s high relative standard error) keeps the estimate."
    • addedOutput schema / properties / totalCount
      Added value: +{
      +  "description": "Number of rows the query matched, before offset and limit were applied.",
      +  "type": "number"
      +}
    • changedOutput schema / properties / totalRows / description
      Previous value: -"Number of geography rows returned."New value: +"Number of rows returned."
    • addedOutput schema / properties / truncated
      Added value: +{
      +  "description": "True when rows were left out by offset or limit — totalCount exceeds the rows returned.",
      +  "type": "boolean"
      +}
  6. First observed

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, but the description adds substantial context beyond that: sentinel decoding, withheld-value handling, ACS margin-of-error pairing, default predicate substitution, sibling-table notices for missing population groups, multi-row records for pep/charv, and pagination behavior. These are non-obvious data semantics that materially affect how an agent interprets results.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core purpose is front-loaded, and much of the detail is genuinely useful for a complex tool, but the description is a single dense paragraph that is difficult to scan. It also repeats several schema-level details, so while the length is partly justified, the structure and concision are not exemplary.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity, 11 parameters, and rich output schema, the description is complete for correct invocation and interpretation. It covers the non-obvious cases an agent must understand: default predicate behavior, withheld and sentinel values, sibling tables for missing groups, multiple records per geography, and paginated GEOID ordering.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the schema itself already documents every parameter in depth, including limit/offset paging, wildcard behavior, FIPS padding rules, variable limits, and predicate defaults. The description largely restates those same semantics and adds only limited cross-parameter context, so the baseline 3 is appropriate when the schema carries the parameter burden.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a precise verb and resource: querying a Census dataset for variables at a geography, multiple geographies, or all geographies at a level. It clearly distinguishes itself from siblings by naming census_resolve_geography for FIPS conversion and census_compare_geographies for ranking, so an agent can route correctly without opening other schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly routes agents to alternatives: census_resolve_geography for place-name-to-FIPS conversion, census_compare_geographies when ranking is needed, census_list_predicate_values for filter codes, census_search_variables for variable codes, and census_list_geographies for valid geography levels. It also states when wildcards and comma-separated FIPS lists are appropriate, giving clear use conditions rather than implied guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.