Skip to main content
Glama

Download Eurostat Dataset

eurostat_download_dataset
Read-onlyIdempotent

Download a Eurostat dataset in bulk through the SDMX 2.1 TSV endpoint and stage it as a SQL table on the dataframe canvas — the route to a whole dataset, where eurostat_query_dataset is the route to a slice of one. The TSV wire format is roughly half the bytes of the JSON-stat body eurostat_query_dataset reads, so it reaches datasets that would otherwise time out, and it is expanded here into one row per non-blank TSV cell, including the unflagged ":" cells that mark a period a series lacks or a period of a frequency it has no observation of. Filters take the same dimension-code map eurostat_query_dataset uses and are applied server-side by Eurostat; call eurostat_get_dataset_info first for the dimension codes and eurostat_get_dimension_values for their values. Narrow with since_period/until_period rather than asking for the most recent N periods — the TSV layout keeps a column for every period whichever is requested, so a period range is what actually shrinks the response. Transfers are bounded by a decoded-byte budget enforced while streaming: complete rows within the allowed prefix are retained with budgetExceeded set; a budget too small for a usable row fails as byte_budget_exceeded with narrowing guidance. Only preview_limit rows come back inline. When a table is staged, call eurostat_dataframe_describe first to confirm its columns, then eurostat_dataframe_query; without a canvas, rows past the preview are not retained.

Input Schema

NameRequiredDescriptionDefault
filtersNoDimension filters as a map of dimension code → array of accepted values, applied by Eurostat before the body is sent. Example: {"unit": ["CP_MEUR"], "na_item": ["B1G"], "geo": ["DE", "FR"]}. Omit a dimension or pass an empty array to accept every value for it; a blank or whitespace-only value is likewise unset and dropped ([""] accepts every value, ["", "DE"] is ["DE"]). Dimension codes match in any case ("GEO" is geo). Do not put "time" here — use since_period/until_period. Naming a dimension the dataset does not have is rejected with the dataset's dimension list rather than silently ignored.
canvas_idNoReuse an existing dataframe canvas so this download lands beside earlier results and can be joined against them. Pass the canvasId a previous eurostat_download_dataset or eurostat_query_dataset response returned; omit to start a fresh canvas. Ignored on deployments without a dataframe canvas. A download that yields no row (a header-only table) fails as no_results and leaves the canvas untouched.
dataset_codeYesDataset code (e.g., "nama_10_gdp"). Required. A DS-* code — Comext detailed trade or PRODCOM, in any case — is served by the Comext host, which refuses an unfiltered download of its large collections as extraction_too_big: filter it, including freq on the trade flows, which mix annual and monthly series.
since_periodNoStart of the period range, inclusive, sent as startPeriod. Accepted forms: YYYY, YYYY-MM, YYYY-MM-DD, YYYY-Qn (1–4), YYYY-Sn (1–2), YYYY-Tn (1–3), YYYY-Mnn (01–12), YYYY-Wnn (a week the year has, up to 53) or YYYY-Dnnn (a day the year has, up to 366) (e.g., "2020", "2023-Q1", "2024-01"). Extra leading zeros after the letter are dropped ("2020-W001" is sent as "2020-W01"), a day of the year is sent as three digits ("2026-D1" as "2026-D001"), and YYYY-A1 is sent as YYYY. Any form works on any dataset, read as a span of days, but Eurostat keeps only periods wholly inside the range, per frequency: "2022-06" on annual data excludes 2022, which starts before the bound, and a notice names that period when the TSV header shows its frequency. A range whose first and last day are the same day is requested as that day and the next, and the next day is dropped before anything is counted or staged. A malformed or non-existent period (e.g., "2020-13") is rejected as invalid_period. The most effective way to shrink a bulk response: it removes period columns from the TSV rather than blanking their cells.
until_periodNoEnd of the period range, inclusive (e.g., "2024"), sent as endPeriod, in the same forms as since_period. Omit for data through the latest available period. A bound that falls inside a period excludes it here too: "2023-06" on annual data excludes 2023, which ends after the bound. The range must hold at least one day: a since_period that starts after until_period ends is rejected as invalid_period, and bounds of different frequencies are compared by day.
preview_limitNoHow many rows to echo inline, from the start of the download. Default 25; positive integers above 500 are clamped to 500 with a notice. The full download is on the canvas table when one was staged; this is orientation, not the result set.

Output Schema

NameRequiredDescriptionDefault
errorNoPresent when the call failed. Absent on success.
noticeNoGuidance on every download: the staged table with the required eurostat_dataframe_describe then eurostat_dataframe_query sequence (or, without a canvas, what was returned inline and what was discarded), preceded by a period a bound falls inside when the TSV header shows that frequency, by byte-budget disclosure when the budget stopped the transfer, by what the unflagged ":" rows are when a series lacks periods or the slice mixes frequencies, and by the inline-preview length when preview_limit returns fewer rows than were downloaded.
canvasIdNoDataframe canvas holding the staged download. Pass to eurostat_dataframe_describe, eurostat_dataframe_query, or a later staging call. Omitted when nothing was staged.
rowCountNoRows expanded from the download, one per non-blank cell. A row carrying a value, a flag, a status or a text value is an observation, a flagged ":" (a value Eurostat reports as unavailable) included. A row holding an unflagged ":" — obs_value null with no flag, status or text — is not: it is a period its series lacks (counted in absentCellCount when the series has an observation of that frequency) or a period of a frequency its series has no observation of.
bytesReadNoDecoded TSV bytes accepted for parsing, after decompression when applicable; never more than EUROSTAT_BULK_MAX_BYTES, including an incomplete trailing line that is discarded.
tableNameNoCanvas table holding every downloaded row. Call eurostat_dataframe_describe with canvasId first to confirm the table and columns, then eurostat_dataframe_query. Omitted when this deployment runs without a dataframe canvas, in which case only the inline preview survives the call.
compressedNoTrue when Eurostat sent the body gzip-compressed. It does so without a Content-Encoding header on large responses, so this reports what the stream actually carried.
totalCountNoRows the download produced — equal to rowCount, unflagged ":" rows included: a period their series lacks (absentCellCount) or a period of a frequency their series has no observation of. The inline observations array holds only the first preview_limit of them; budgetExceeded, not this count, says whether the download is the whole dataset.
datasetCodeNoDataset code as provided.
periodRangeNoPeriod coverage of the observations actually downloaded. Narrower than the dataset when budgetExceeded is true or a period range was applied.
appliedQueryNoThe bulk request as the server built it.
missingCountNoRows carrying no numeric value (obs_value is null): observations published without a number — a flagged ":" or a text value — and every unflagged ":" row, a period its series lacks or a period of a frequency its series has no observation of.
observationsNoThe first preview_limit rows of the download, in the order Eurostat streamed them. A prefix of the staged table, not a sample.
budgetExceededNoTrue when the byte budget stopped the transfer before the dataset ended, making the rows a prefix rather than the whole thing. Narrow with filters or a period range, or raise EUROSTAT_BULK_MAX_BYTES.
dimensionsUsedNoDimension codes carried by the downloaded rows, in the order Eurostat keys them (e.g., ["freq", "unit", "na_item", "geo"]). Read from the TSV header, so it reflects the response rather than metadata. The period lives in the separate "time" column.
stagedRowCountNoRows written to the canvas table. Matches rowCount. Omitted alongside tableName.
absentCellCountNoUnflagged ":" rows — obs_value null with no flag, status or text — at a period of a frequency the same series carries in another downloaded row: periods that series lacks, where Eurostat publishes no observation. Unflagged rows at the periods of a frequency the series has no observation of (the padding of a mixed-frequency slice, or a series that is ":" throughout) are left out, and a flagged ":" or a text value is an observation, never counted. Part of rowCount and missingCount, and counted over the rows downloaded, so a budget-cut download counts its prefix.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed15 schema fields changed
    • changedInput schema / properties / canvas_id / description
      Previous value: -"Reuse an existing dataframe canvas so this download lands beside earlier results and can be joined against them. Pass the canvasId a previous eurostat_download_dataset or eurostat_query_dataset response returned; omit to start a fresh canvas. Ignored on deployments without a dataframe canvas. A download that carries no observations fails as no_results and leaves the canvas untouched."New value: +"Reuse an existing dataframe canvas so this download lands beside earlier results and can be joined against them. Pass the canvasId a previous eurostat_download_dataset or eurostat_query_dataset response returned; omit to start a fresh canvas. Ignored on deployments without a dataframe canvas. A download that yields no row (a header-only table) fails as no_results and leaves the canvas untouched."
    • changedInput schema / properties / preview_limit / description
      Previous value: -"How many observations to echo inline, from the start of the download. Default 25; positive integers above 500 are clamped to 500 with a notice. The full download is on the canvas table when one was staged; this is orientation, not the result set."New value: +"How many rows to echo inline, from the start of the download. Default 25; positive integers above 500 are clamped to 500 with a notice. The full download is on the canvas table when one was staged; this is orientation, not the result set."
    • changedOutput schema / anyOf
      Previous value: -[
      -  {
      -    "not": {
      -      "required": [
      -        "error"
      -      ]
      -    },
      -    "required": [
      -      "datasetCode",
      -      "dimensionsUsed",
      -      "rowCount",
      -      "missingCount",
      -      "periodRange",
      -      "bytesRead",
      -      "compressed",
      -      "budgetExceeded",
      -      "observations",
      -      "totalCount",
      -      "appliedQuery"
      -    ]
      -  },
      -  {
      -    "required": [
      -      "error"
      -    ]
      -  }
      -]New value: +[
      +  {
      +    "not": {
      +      "required": [
      +        "error"
      +      ]
      +    },
      +    "required": [
      +      "datasetCode",
      +      "dimensionsUsed",
      +      "rowCount",
      +      "missingCount",
      +      "absentCellCount",
      +      "periodRange",
      +      "bytesRead",
      +      "compressed",
      +      "budgetExceeded",
      +      "observations",
      +      "totalCount",
      +      "appliedQuery"
      +    ]
      +  },
      +  {
      +    "required": [
      +      "error"
      +    ]
      +  }
      +]
    • addedOutput schema / properties / absentCellCount
      Added value: +{
      +  "description": "Unflagged \":\" rows — obs_value null with no flag, status or text — at a period of a frequency the same series carries in another downloaded row: periods that series lacks, where Eurostat publishes no observation. Unflagged rows at the periods of a frequency the series has no observation of (the padding of a mixed-frequency slice, or a series that is \":\" throughout) are left out, and a flagged \":\" or a text value is an observation, never counted. Part of rowCount and missingCount, and counted over the rows downloaded, so a budget-cut download counts its prefix.",
      +  "type": "number"
      +}
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `byte_budget_exceeded`: The decoded TSV byte budget was exhausted before a complete header and usable observation could be read. `not_found`: The dataset code is not available for dissemination (HTTP 404, SDMX faultcode 100). `invalid_dimension`: A filter names a dimension the dataset does not have, or a value Eurostat rejects, or the period range selects no period of the dataset (SDMX faultcode 150): it misses the coverage, or holds no whole period. The fault covers all of these; its TIME_PERIOD clause tells the period range apart. `filter_arity`: Eurostat rejected the positional dimension key because it carried the wrong number of positions (SDMX faultcode 140, INVALID_QUERY_NB_FILTERS), meaning the dataset structure has changed since the metadata call. `invalid_period`: since_period or until_period is not a period literal, or names a month, quarter, semester, trimester, week or day that does not exist, or since_period starts after until_period ends. Checked before any request — the bulk endpoint would otherwise roll an out-of-range period into a neighbouring one, and answer an inverted range with the whole series — and SDMX faultcode 140 TIME_PERIOD_FILTER_SPEC_INVALID maps here too. `async_queued`: Eurostat answered HTTP 200 with a SOAP syncResponse queue ticket (status SUBMITTED) instead of data, because the extraction was too costly to serve synchronously. `no_results`: The download completed but carried no populated observation cells. Nothing is staged, and no canvas is created or touched. `extraction_too_big`: Eurostat refused the extraction as too large (SDMX faultcode 413, HTTP 413): past its 5,000,000-row extraction limit, or an unfiltered download of a large DS-* Comext collection, which Eurostat serves only filtered. Covers every dataset, on either host. `upstream_fault`: The SDMX data endpoint returned a fault this server does not model, or a body that is not a TSV table; or the data endpoint — or, for a filtered download, the structure endpoint — answered HTTP 5xx or could not be reached on every retry, which the error marks retryable. `canvas_not_found`: A canvas_id was supplied for staging but is unknown or its lifetime has elapsed. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `byte_budget_exceeded`: The decoded TSV byte budget was exhausted before a complete header and usable row could be read. `not_found`: The dataset code is not available for dissemination (HTTP 404, SDMX faultcode 100). `invalid_dimension`: A filter names a dimension the dataset does not have, or a value Eurostat rejects, or the period range selects no period of the dataset (SDMX faultcode 150): it misses the coverage, or holds no whole period. The fault covers all of these; its TIME_PERIOD clause tells the period range apart. `filter_arity`: Eurostat rejected the positional dimension key because it carried the wrong number of positions (SDMX faultcode 140, INVALID_QUERY_NB_FILTERS), meaning the dataset structure has changed since the metadata call. `invalid_period`: since_period or until_period is not a period literal, or names a month, quarter, semester, trimester, week or day that does not exist, or since_period starts after until_period ends. Checked before any request — the bulk endpoint would otherwise roll an out-of-range period into a neighbouring one, and answer an inverted range with the whole series — and SDMX faultcode 140 TIME_PERIOD_FILTER_SPEC_INVALID maps here too. `async_queued`: Eurostat answered HTTP 200 with a SOAP syncResponse queue ticket (status SUBMITTED) instead of data, because the extraction was too costly to serve synchronously. `no_results`: The download completed but yielded no row: a header-only table, or a one-day reply whose only cells fall on the next day. Nothing is staged, and no canvas is created or touched. A table whose only rows are unflagged \":\" cells succeeds with those rows, with periodRange omitted. `extraction_too_big`: Eurostat refused the extraction as too large (SDMX faultcode 413, HTTP 413): past its 5,000,000-row extraction limit, or an unfiltered download of a large DS-* Comext collection, which Eurostat serves only filtered. Covers every dataset, on either host. `upstream_fault`: The SDMX data endpoint returned a fault this server does not model, or a body that is not a TSV table; for a filtered download, the structure endpoint returned a structure this server cannot build a filter key from; the data endpoint — or, for a filtered download, the structure endpoint — answered HTTP 501, which is not retried; or it answered another HTTP 5xx or could not be reached on every retry, which the error marks retryable. `canvas_not_found`: A canvas_id was supplied for staging but is unknown or its lifetime has elapsed. Other values are possible when a failure originates below the handler."
    • changedOutput schema / properties / missingCount / description
      Previous value: -"Downloaded observations carrying no numeric value (obs_value is null)."New value: +"Rows carrying no numeric value (obs_value is null): observations published without a number — a flagged \":\" or a text value — and every unflagged \":\" row, a period its series lacks or a period of a frequency its series has no observation of."
    • changedOutput schema / properties / notice / description
      Previous value: -"Guidance on every download: the staged table with the required eurostat_dataframe_describe then eurostat_dataframe_query sequence (or, without a canvas, what was returned inline and what was discarded), preceded by a period a bound falls inside when the TSV header shows that frequency, by byte-budget disclosure when the budget stopped the transfer, and by the inline-preview length when preview_limit returns fewer rows than were downloaded."New value: +"Guidance on every download: the staged table with the required eurostat_dataframe_describe then eurostat_dataframe_query sequence (or, without a canvas, what was returned inline and what was discarded), preceded by a period a bound falls inside when the TSV header shows that frequency, by byte-budget disclosure when the budget stopped the transfer, by what the unflagged \":\" rows are when a series lacks periods or the slice mixes frequencies, and by the inline-preview length when preview_limit returns fewer rows than were downloaded."
    • changedOutput schema / properties / observations / description
      Previous value: -"The first preview_limit observations of the download, in the order Eurostat streamed them. A prefix of the staged table, not a sample."New value: +"The first preview_limit rows of the download, in the order Eurostat streamed them. A prefix of the staged table, not a sample."
    • changedOutput schema / properties / observations / items / description
      Previous value: -"One observation as a flat row: one column per dimension holding its code, \"time\" for the period, then obs_value, obs_flag, obs_flag_label, conf_status, conf_status_label. A label column is null when Eurostat publishes no label for that code. Rows of a DS-* dataset also carry obs_value_text after obs_value: a value Eurostat published as text, such as a PRODCOM quantity unit (\"KG\"), kept verbatim with obs_value null; a PRODCOM \":C\" arrives as conf_status \"C\" instead."New value: +"One downloaded row: one column per dimension holding its code, \"time\" for the period, then obs_value, obs_flag, obs_flag_label, conf_status, conf_status_label. A label column is null when Eurostat publishes no label for that code. Rows of a DS-* dataset also carry obs_value_text after obs_value: a value Eurostat published as text, such as a PRODCOM quantity unit (\"KG\"), kept verbatim with obs_value null; a PRODCOM \":C\" arrives as conf_status \"C\" instead."
    • changedOutput schema / properties / periodRange / description
      Previous value: -"Period coverage of the rows actually downloaded. Narrower than the dataset when budgetExceeded is true or a period range was applied."New value: +"Period coverage of the observations actually downloaded. Narrower than the dataset when budgetExceeded is true or a period range was applied."
    • changedOutput schema / properties / periodRange / properties / end / description
      Previous value: -"Latest period carrying an observation. Omitted when nothing was downloaded."New value: +"Latest period of a row carrying an observation, read the same way as start. Omitted, with the other bound, when no row carries an observation."
    • changedOutput schema / properties / periodRange / properties / start / description
      Previous value: -"Earliest period carrying an observation. Omitted when nothing was downloaded."New value: +"Earliest period of a row carrying an observation — a value, a flag, a status or a text value; an unflagged \":\" row sets no bound. Omitted, with the other bound, when no row carries an observation."
    • changedOutput schema / properties / rowCount / description
      Previous value: -"Observations expanded from the download — one per populated cell, counting those Eurostat reports as unavailable."New value: +"Rows expanded from the download, one per non-blank cell. A row carrying a value, a flag, a status or a text value is an observation, a flagged \":\" (a value Eurostat reports as unavailable) included. A row holding an unflagged \":\" — obs_value null with no flag, status or text — is not: it is a period its series lacks (counted in absentCellCount when the series has an observation of that frequency) or a period of a frequency its series has no observation of."
    • changedOutput schema / properties / tableName / description
      Previous value: -"Canvas table holding every downloaded observation. Call eurostat_dataframe_describe with canvasId first to confirm the table and columns, then eurostat_dataframe_query. Omitted when this deployment runs without a dataframe canvas, in which case only the inline preview survives the call."New value: +"Canvas table holding every downloaded row. Call eurostat_dataframe_describe with canvasId first to confirm the table and columns, then eurostat_dataframe_query. Omitted when this deployment runs without a dataframe canvas, in which case only the inline preview survives the call."
    • changedOutput schema / properties / totalCount / description
      Previous value: -"Observations the download produced — equal to rowCount. The inline observations array holds only the first preview_limit of them; budgetExceeded, not this count, says whether the download is the whole dataset."New value: +"Rows the download produced — equal to rowCount, unflagged \":\" rows included: a period their series lacks (absentCellCount) or a period of a frequency their series has no observation of. The inline observations array holds only the first preview_limit of them; budgetExceeded, not this count, says whether the download is the whole dataset."
  2. Changed7 schema fields changed
    • changedInput schema / properties / since_period / description
      Previous value: -"Start of the period range, inclusive, sent as startPeriod. Accepted forms: YYYY, YYYY-MM, YYYY-MM-DD, YYYY-Qn (1–4), YYYY-Sn (1–2), YYYY-Tn (1–3), YYYY-Mnn (01–12), YYYY-Wnn (a week the year has, up to 53) or YYYY-Dnnn (a day the year has, up to 366) (e.g., \"2020\", \"2023-Q1\", \"2024-01\"). Extra leading zeros after the letter are dropped (\"2020-W001\" is sent as \"2020-W01\"), a day of the year is sent as three digits (\"2026-D1\" as \"2026-D001\"), YYYY-A1 is sent as YYYY, and a period of another frequency is mapped onto the dataset's own. A malformed or non-existent period (e.g., \"2020-13\") is rejected as invalid_period. The most effective way to shrink a bulk response: it removes period columns from the TSV rather than blanking their cells."New value: +"Start of the period range, inclusive, sent as startPeriod. Accepted forms: YYYY, YYYY-MM, YYYY-MM-DD, YYYY-Qn (1–4), YYYY-Sn (1–2), YYYY-Tn (1–3), YYYY-Mnn (01–12), YYYY-Wnn (a week the year has, up to 53) or YYYY-Dnnn (a day the year has, up to 366) (e.g., \"2020\", \"2023-Q1\", \"2024-01\"). Extra leading zeros after the letter are dropped (\"2020-W001\" is sent as \"2020-W01\"), a day of the year is sent as three digits (\"2026-D1\" as \"2026-D001\"), and YYYY-A1 is sent as YYYY. Any form works on any dataset, read as a span of days, but Eurostat keeps only periods wholly inside the range, per frequency: \"2022-06\" on annual data excludes 2022, which starts before the bound, and a notice names that period when the TSV header shows its frequency. A range whose first and last day are the same day is requested as that day and the next, and the next day is dropped before anything is counted or staged. A malformed or non-existent period (e.g., \"2020-13\") is rejected as invalid_period. The most effective way to shrink a bulk response: it removes period columns from the TSV rather than blanking their cells."
    • changedInput schema / properties / until_period / description
      Previous value: -"End of the period range, inclusive (e.g., \"2024\"), sent as endPeriod, in the same forms as since_period. Omit for data through the latest available period. The range must hold at least one day: a since_period that starts after until_period ends is rejected as invalid_period, while pairs of different frequencies are fine (\"2020-06\" to \"2020\")."New value: +"End of the period range, inclusive (e.g., \"2024\"), sent as endPeriod, in the same forms as since_period. Omit for data through the latest available period. A bound that falls inside a period excludes it here too: \"2023-06\" on annual data excludes 2023, which ends after the bound. The range must hold at least one day: a since_period that starts after until_period ends is rejected as invalid_period, and bounds of different frequencies are compared by day."
    • changedOutput schema / properties / appliedQuery / properties / sincePeriod / description
      Previous value: -"startPeriod applied, if any."New value: +"since_period applied, if any."
    • changedOutput schema / properties / appliedQuery / properties / untilPeriod / description
      Previous value: -"endPeriod applied, if any."New value: +"until_period applied, if any."
    • changedOutput schema / properties / appliedQuery / properties / url / description
      Previous value: -"The SDMX request URL, so the download can be reproduced."New value: +"The SDMX request URL, so the download can be reproduced. A one-day range goes out as that day and the next, so its endPeriod is a day past untilPeriod."
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `byte_budget_exceeded`: The decoded TSV byte budget was exhausted before a complete header and usable observation could be read. `not_found`: The dataset code is not available for dissemination (HTTP 404, SDMX faultcode 100). `invalid_dimension`: A filter names a dimension the dataset does not have, or a value or period range Eurostat rejects (SDMX faultcode 150). `filter_arity`: Eurostat rejected the positional dimension key because it carried the wrong number of positions (SDMX faultcode 140, INVALID_QUERY_NB_FILTERS), meaning the dataset structure has changed since the metadata call. `invalid_period`: since_period or until_period is not a period literal, or names a month, quarter, semester, trimester, week or day that does not exist, or since_period starts after until_period ends. Checked before any request — the bulk endpoint would otherwise roll an out-of-range period into a neighbouring one, and answer an inverted range with the whole series — and SDMX faultcode 140 TIME_PERIOD_FILTER_SPEC_INVALID maps here too. `async_queued`: Eurostat answered HTTP 200 with a SOAP syncResponse queue ticket (status SUBMITTED) instead of data, because the extraction was too costly to serve synchronously. `no_results`: The download completed but carried no populated observation cells. Nothing is staged, and no canvas is created or touched. `extraction_too_big`: Eurostat refused the extraction as too large (SDMX faultcode 413, HTTP 413): past its 5,000,000-row extraction limit, or an unfiltered download of a large DS-* Comext collection, which Eurostat serves only filtered. Covers every dataset, on either host. `upstream_fault`: The SDMX data endpoint returned a fault this server does not model, or a body that is not a TSV table; or the data endpoint — or, for a filtered download, the structure endpoint — answered HTTP 5xx or could not be reached on every retry, which the error marks retryable. `canvas_not_found`: A canvas_id was supplied for staging but is unknown or its lifetime has elapsed. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `byte_budget_exceeded`: The decoded TSV byte budget was exhausted before a complete header and usable observation could be read. `not_found`: The dataset code is not available for dissemination (HTTP 404, SDMX faultcode 100). `invalid_dimension`: A filter names a dimension the dataset does not have, or a value Eurostat rejects, or the period range selects no period of the dataset (SDMX faultcode 150): it misses the coverage, or holds no whole period. The fault covers all of these; its TIME_PERIOD clause tells the period range apart. `filter_arity`: Eurostat rejected the positional dimension key because it carried the wrong number of positions (SDMX faultcode 140, INVALID_QUERY_NB_FILTERS), meaning the dataset structure has changed since the metadata call. `invalid_period`: since_period or until_period is not a period literal, or names a month, quarter, semester, trimester, week or day that does not exist, or since_period starts after until_period ends. Checked before any request — the bulk endpoint would otherwise roll an out-of-range period into a neighbouring one, and answer an inverted range with the whole series — and SDMX faultcode 140 TIME_PERIOD_FILTER_SPEC_INVALID maps here too. `async_queued`: Eurostat answered HTTP 200 with a SOAP syncResponse queue ticket (status SUBMITTED) instead of data, because the extraction was too costly to serve synchronously. `no_results`: The download completed but carried no populated observation cells. Nothing is staged, and no canvas is created or touched. `extraction_too_big`: Eurostat refused the extraction as too large (SDMX faultcode 413, HTTP 413): past its 5,000,000-row extraction limit, or an unfiltered download of a large DS-* Comext collection, which Eurostat serves only filtered. Covers every dataset, on either host. `upstream_fault`: The SDMX data endpoint returned a fault this server does not model, or a body that is not a TSV table; or the data endpoint — or, for a filtered download, the structure endpoint — answered HTTP 5xx or could not be reached on every retry, which the error marks retryable. `canvas_not_found`: A canvas_id was supplied for staging but is unknown or its lifetime has elapsed. Other values are possible when a failure originates below the handler."
    • changedOutput schema / properties / notice / description
      Previous value: -"Guidance on every download: the staged table with the required eurostat_dataframe_describe then eurostat_dataframe_query sequence (or, without a canvas, what was returned inline and what was discarded), preceded by byte-budget disclosure when the budget stopped the transfer and by the inline-preview length when preview_limit returns fewer rows than were downloaded."New value: +"Guidance on every download: the staged table with the required eurostat_dataframe_describe then eurostat_dataframe_query sequence (or, without a canvas, what was returned inline and what was discarded), preceded by a period a bound falls inside when the TSV header shows that frequency, by byte-budget disclosure when the budget stopped the transfer, and by the inline-preview length when preview_limit returns fewer rows than were downloaded."
  3. Changed2 schema fields changed
    • changedInput schema / properties / preview_limit / default
      Previous value: -50New value: +25
    • changedInput schema / properties / preview_limit / description
      Previous value: -"How many observations to echo inline, from the start of the download. Default 50; positive integers above 500 are clamped to 500 with a notice. The full download is on the canvas table when one was staged; this is orientation, not the result set."New value: +"How many observations to echo inline, from the start of the download. Default 25; positive integers above 500 are clamped to 500 with a notice. The full download is on the canvas table when one was staged; this is orientation, not the result set."
  4. Changed7 schema fields changed
    • changedInput schema / properties / preview_limit / description
      Previous value: -"How many observations to echo inline, from the start of the download. Caps at 500. The full download is on the canvas table when one was staged; this is orientation, not the result set."New value: +"How many observations to echo inline, from the start of the download. Default 50; positive integers above 500 are clamped to 500 with a notice. The full download is on the canvas table when one was staged; this is orientation, not the result set."
    • removedInput schema / properties / preview_limit / maximum
      Removed value: -500
    • addedInput schema / properties / preview_limit / multipleOf
      Added value: +1
    • changedInput schema / properties / preview_limit / type
      Previous value: -"integer"New value: +"number"
    • changedOutput schema / properties / bytesRead / description
      Previous value: -"Decoded TSV bytes read from Eurostat — after gzip decompression when the body arrived compressed, so it measures the payload rather than the wire."New value: +"Decoded TSV bytes accepted for parsing, after decompression when applicable; never more than EUROSTAT_BULK_MAX_BYTES, including an incomplete trailing line that is discarded."
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `not_found`: The dataset code is not available for dissemination (HTTP 404, SDMX faultcode 100). `invalid_dimension`: A filter names a dimension the dataset does not have, or a value or period range Eurostat rejects (SDMX faultcode 150). `filter_arity`: Eurostat rejected the positional dimension key because it carried the wrong number of positions (SDMX faultcode 140, INVALID_QUERY_NB_FILTERS), meaning the dataset structure has changed since the metadata call. `invalid_period`: since_period or until_period is not a period literal, or names a month, quarter, semester, trimester, week or day that does not exist, or since_period starts after until_period ends. Checked before any request — the bulk endpoint would otherwise roll an out-of-range period into a neighbouring one, and answer an inverted range with the whole series — and SDMX faultcode 140 TIME_PERIOD_FILTER_SPEC_INVALID maps here too. `async_queued`: Eurostat answered HTTP 200 with a SOAP syncResponse queue ticket (status SUBMITTED) instead of data, because the extraction was too costly to serve synchronously. `no_results`: The download completed but carried no populated observation cells. Nothing is staged, and no canvas is created or touched. `extraction_too_big`: Eurostat refused the extraction as too large (SDMX faultcode 413, HTTP 413): past its 5,000,000-row extraction limit, or an unfiltered download of a large DS-* Comext collection, which Eurostat serves only filtered. Covers every dataset, on either host. `upstream_fault`: The SDMX data endpoint returned a fault this server does not model, or a body that is not a TSV table; or the data endpoint — or, for a filtered download, the structure endpoint — answered HTTP 5xx or could not be reached on every retry, which the error marks retryable. `canvas_not_found`: A canvas_id was supplied for staging but is unknown or its lifetime has elapsed. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `byte_budget_exceeded`: The decoded TSV byte budget was exhausted before a complete header and usable observation could be read. `not_found`: The dataset code is not available for dissemination (HTTP 404, SDMX faultcode 100). `invalid_dimension`: A filter names a dimension the dataset does not have, or a value or period range Eurostat rejects (SDMX faultcode 150). `filter_arity`: Eurostat rejected the positional dimension key because it carried the wrong number of positions (SDMX faultcode 140, INVALID_QUERY_NB_FILTERS), meaning the dataset structure has changed since the metadata call. `invalid_period`: since_period or until_period is not a period literal, or names a month, quarter, semester, trimester, week or day that does not exist, or since_period starts after until_period ends. Checked before any request — the bulk endpoint would otherwise roll an out-of-range period into a neighbouring one, and answer an inverted range with the whole series — and SDMX faultcode 140 TIME_PERIOD_FILTER_SPEC_INVALID maps here too. `async_queued`: Eurostat answered HTTP 200 with a SOAP syncResponse queue ticket (status SUBMITTED) instead of data, because the extraction was too costly to serve synchronously. `no_results`: The download completed but carried no populated observation cells. Nothing is staged, and no canvas is created or touched. `extraction_too_big`: Eurostat refused the extraction as too large (SDMX faultcode 413, HTTP 413): past its 5,000,000-row extraction limit, or an unfiltered download of a large DS-* Comext collection, which Eurostat serves only filtered. Covers every dataset, on either host. `upstream_fault`: The SDMX data endpoint returned a fault this server does not model, or a body that is not a TSV table; or the data endpoint — or, for a filtered download, the structure endpoint — answered HTTP 5xx or could not be reached on every retry, which the error marks retryable. `canvas_not_found`: A canvas_id was supplied for staging but is unknown or its lifetime has elapsed. Other values are possible when a failure originates below the handler."
    • changedOutput schema / properties / error / properties / data / properties / reason / examples
      Previous value: -[
      -  "not_found",
      -  "invalid_dimension",
      -  "filter_arity",
      -  "invalid_period",
      -  "async_queued",
      -  "no_results",
      -  "extraction_too_big",
      -  "upstream_fault",
      -  "canvas_not_found"
      -]New value: +[
      +  "byte_budget_exceeded",
      +  "not_found",
      +  "invalid_dimension",
      +  "filter_arity",
      +  "invalid_period",
      +  "async_queued",
      +  "no_results",
      +  "extraction_too_big",
      +  "upstream_fault",
      +  "canvas_not_found"
      +]
  5. Changed3 schema fields changed
    • changedInput schema / properties / filters / description
      Previous value: -"Dimension filters as a map of dimension code → array of accepted values, applied by Eurostat before the body is sent. Example: {\"unit\": [\"CP_MEUR\"], \"na_item\": [\"B1G\"], \"geo\": [\"DE\", \"FR\"]}. Omit a dimension or pass an empty array to accept every value for it. Dimension codes match in any case (\"GEO\" is geo). Do not put \"time\" here — use since_period/until_period. Naming a dimension the dataset does not have is rejected with the dataset's dimension list rather than silently ignored."New value: +"Dimension filters as a map of dimension code → array of accepted values, applied by Eurostat before the body is sent. Example: {\"unit\": [\"CP_MEUR\"], \"na_item\": [\"B1G\"], \"geo\": [\"DE\", \"FR\"]}. Omit a dimension or pass an empty array to accept every value for it; a blank or whitespace-only value is likewise unset and dropped ([\"\"] accepts every value, [\"\", \"DE\"] is [\"DE\"]). Dimension codes match in any case (\"GEO\" is geo). Do not put \"time\" here — use since_period/until_period. Naming a dimension the dataset does not have is rejected with the dataset's dimension list rather than silently ignored."
    • changedOutput schema / properties / appliedQuery / properties / filters / description
      Previous value: -"Dimension filters sent to Eurostat. Empty arrays are dropped."New value: +"Dimension filters sent to Eurostat. Blank values and dimensions left with no value are dropped."
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `not_found`: The dataset code is not available for dissemination (HTTP 404, SDMX faultcode 100). `invalid_dimension`: A filter names a dimension the dataset does not have, or a value or period range Eurostat rejects (SDMX faultcode 150). `filter_arity`: Eurostat rejected the positional dimension key because it carried the wrong number of positions (SDMX faultcode 140, INVALID_QUERY_NB_FILTERS), meaning the dataset structure has changed since the metadata call. `invalid_period`: since_period or until_period is not a period literal, or names a month, quarter, semester, trimester, week or day that does not exist, or since_period starts after until_period ends. Checked before any request — the bulk endpoint would otherwise roll an out-of-range period into a neighbouring one, and answer an inverted range with the whole series — and SDMX faultcode 140 TIME_PERIOD_FILTER_SPEC_INVALID maps here too. `async_queued`: Eurostat answered HTTP 200 with a SOAP syncResponse queue ticket (status SUBMITTED) instead of data, because the extraction was too costly to serve synchronously. `no_results`: The download completed but carried no populated observation cells. Nothing is staged, and no canvas is created or touched. `extraction_too_big`: Eurostat refused the extraction as too large (SDMX faultcode 413, HTTP 413): past its 5,000,000-row extraction limit, or an unfiltered download of a large DS-* Comext collection, which Eurostat serves only filtered. Covers every dataset, on either host. `upstream_fault`: The SDMX endpoint returned a fault this server does not model, or a body that is not a TSV table. `canvas_not_found`: A canvas_id was supplied for staging but is unknown or its lifetime has elapsed. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `not_found`: The dataset code is not available for dissemination (HTTP 404, SDMX faultcode 100). `invalid_dimension`: A filter names a dimension the dataset does not have, or a value or period range Eurostat rejects (SDMX faultcode 150). `filter_arity`: Eurostat rejected the positional dimension key because it carried the wrong number of positions (SDMX faultcode 140, INVALID_QUERY_NB_FILTERS), meaning the dataset structure has changed since the metadata call. `invalid_period`: since_period or until_period is not a period literal, or names a month, quarter, semester, trimester, week or day that does not exist, or since_period starts after until_period ends. Checked before any request — the bulk endpoint would otherwise roll an out-of-range period into a neighbouring one, and answer an inverted range with the whole series — and SDMX faultcode 140 TIME_PERIOD_FILTER_SPEC_INVALID maps here too. `async_queued`: Eurostat answered HTTP 200 with a SOAP syncResponse queue ticket (status SUBMITTED) instead of data, because the extraction was too costly to serve synchronously. `no_results`: The download completed but carried no populated observation cells. Nothing is staged, and no canvas is created or touched. `extraction_too_big`: Eurostat refused the extraction as too large (SDMX faultcode 413, HTTP 413): past its 5,000,000-row extraction limit, or an unfiltered download of a large DS-* Comext collection, which Eurostat serves only filtered. Covers every dataset, on either host. `upstream_fault`: The SDMX data endpoint returned a fault this server does not model, or a body that is not a TSV table; or the data endpoint — or, for a filtered download, the structure endpoint — answered HTTP 5xx or could not be reached on every retry, which the error marks retryable. `canvas_not_found`: A canvas_id was supplied for staging but is unknown or its lifetime has elapsed. Other values are possible when a failure originates below the handler."
  6. Changed5 schema fields changed
    • changedInput schema / properties / canvas_id / description
      Previous value: -"Reuse an existing dataframe canvas so this download lands beside earlier results and can be joined against them. Pass the canvasId a previous eurostat_download_dataset or eurostat_query_dataset response returned; omit to start a fresh canvas. Ignored on deployments without a dataframe canvas."New value: +"Reuse an existing dataframe canvas so this download lands beside earlier results and can be joined against them. Pass the canvasId a previous eurostat_download_dataset or eurostat_query_dataset response returned; omit to start a fresh canvas. Ignored on deployments without a dataframe canvas. A download that carries no observations fails as no_results and leaves the canvas untouched."
    • changedInput schema / properties / dataset_code / description
      Previous value: -"Dataset code (e.g., \"nama_10_gdp\"). Required."New value: +"Dataset code (e.g., \"nama_10_gdp\"). Required. A DS-* code — Comext detailed trade or PRODCOM, in any case — is served by the Comext host, which refuses an unfiltered download of its large collections as extraction_too_big: filter it, including freq on the trade flows, which mix annual and monthly series."
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `not_found`: The dataset code is not available for dissemination (HTTP 404, SDMX faultcode 100). `invalid_dimension`: A filter names a dimension the dataset does not have, or a value or period range Eurostat rejects (SDMX faultcode 150). `filter_arity`: Eurostat rejected the positional dimension key because it carried the wrong number of positions (SDMX faultcode 140, INVALID_QUERY_NB_FILTERS), meaning the dataset structure has changed since the metadata call. `invalid_period`: since_period or until_period is not a period literal, or names a month, quarter, semester, trimester, week or day that does not exist, or since_period starts after until_period ends. Checked before any request — the bulk endpoint would otherwise roll an out-of-range period into a neighbouring one, and answer an inverted range with the whole series — and SDMX faultcode 140 TIME_PERIOD_FILTER_SPEC_INVALID maps here too. `async_queued`: Eurostat answered HTTP 200 with a SOAP syncResponse queue ticket (status SUBMITTED) instead of data, because the extraction was too costly to serve synchronously. `no_results`: The download completed but carried no populated observation cells. `upstream_fault`: The SDMX endpoint returned a fault this server does not model, or a body that is not a TSV table. `canvas_not_found`: A canvas_id was supplied for staging but is unknown or its lifetime has elapsed. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `not_found`: The dataset code is not available for dissemination (HTTP 404, SDMX faultcode 100). `invalid_dimension`: A filter names a dimension the dataset does not have, or a value or period range Eurostat rejects (SDMX faultcode 150). `filter_arity`: Eurostat rejected the positional dimension key because it carried the wrong number of positions (SDMX faultcode 140, INVALID_QUERY_NB_FILTERS), meaning the dataset structure has changed since the metadata call. `invalid_period`: since_period or until_period is not a period literal, or names a month, quarter, semester, trimester, week or day that does not exist, or since_period starts after until_period ends. Checked before any request — the bulk endpoint would otherwise roll an out-of-range period into a neighbouring one, and answer an inverted range with the whole series — and SDMX faultcode 140 TIME_PERIOD_FILTER_SPEC_INVALID maps here too. `async_queued`: Eurostat answered HTTP 200 with a SOAP syncResponse queue ticket (status SUBMITTED) instead of data, because the extraction was too costly to serve synchronously. `no_results`: The download completed but carried no populated observation cells. Nothing is staged, and no canvas is created or touched. `extraction_too_big`: Eurostat refused the extraction as too large (SDMX faultcode 413, HTTP 413): past its 5,000,000-row extraction limit, or an unfiltered download of a large DS-* Comext collection, which Eurostat serves only filtered. Covers every dataset, on either host. `upstream_fault`: The SDMX endpoint returned a fault this server does not model, or a body that is not a TSV table. `canvas_not_found`: A canvas_id was supplied for staging but is unknown or its lifetime has elapsed. Other values are possible when a failure originates below the handler."
    • changedOutput schema / properties / error / properties / data / properties / reason / examples
      Previous value: -[
      -  "not_found",
      -  "invalid_dimension",
      -  "filter_arity",
      -  "invalid_period",
      -  "async_queued",
      -  "no_results",
      -  "upstream_fault",
      -  "canvas_not_found"
      -]New value: +[
      +  "not_found",
      +  "invalid_dimension",
      +  "filter_arity",
      +  "invalid_period",
      +  "async_queued",
      +  "no_results",
      +  "extraction_too_big",
      +  "upstream_fault",
      +  "canvas_not_found"
      +]
    • changedOutput schema / properties / observations / items / description
      Previous value: -"One observation as a flat row: one column per dimension holding its code, \"time\" for the period, then obs_value, obs_flag, obs_flag_label, conf_status, conf_status_label. A label column is null when Eurostat publishes no label for that code."New value: +"One observation as a flat row: one column per dimension holding its code, \"time\" for the period, then obs_value, obs_flag, obs_flag_label, conf_status, conf_status_label. A label column is null when Eurostat publishes no label for that code. Rows of a DS-* dataset also carry obs_value_text after obs_value: a value Eurostat published as text, such as a PRODCOM quantity unit (\"KG\"), kept verbatim with obs_value null; a PRODCOM \":C\" arrives as conf_status \"C\" instead."
  7. Changed11 schema fields changed
    • changedInput schema / properties / filters / description
      Previous value: -"Dimension filters as a map of dimension code → array of accepted values, applied by Eurostat before the body is sent. Example: {\"unit\": [\"CP_MEUR\"], \"na_item\": [\"B1G\"], \"geo\": [\"DE\", \"FR\"]}. Omit a dimension or pass an empty array to accept every value for it. Do not put \"time\" here — use since_period/until_period. Naming a dimension the dataset does not have is rejected with the dataset's dimension list rather than silently ignored."New value: +"Dimension filters as a map of dimension code → array of accepted values, applied by Eurostat before the body is sent. Example: {\"unit\": [\"CP_MEUR\"], \"na_item\": [\"B1G\"], \"geo\": [\"DE\", \"FR\"]}. Omit a dimension or pass an empty array to accept every value for it. Dimension codes match in any case (\"GEO\" is geo). Do not put \"time\" here — use since_period/until_period. Naming a dimension the dataset does not have is rejected with the dataset's dimension list rather than silently ignored."
    • changedInput schema / properties / since_period / description
      Previous value: -"Start of the period range (e.g., \"2020\", \"2023-Q1\", \"2024-01\"), sent as startPeriod. The most effective way to shrink a bulk response: it removes period columns from the TSV rather than blanking their cells."New value: +"Start of the period range, inclusive, sent as startPeriod. Accepted forms: YYYY, YYYY-MM, YYYY-MM-DD, YYYY-Qn (1–4), YYYY-Sn (1–2), YYYY-Tn (1–3), YYYY-Mnn (01–12), YYYY-Wnn (a week the year has, up to 53) or YYYY-Dnnn (a day the year has, up to 366) (e.g., \"2020\", \"2023-Q1\", \"2024-01\"). Extra leading zeros after the letter are dropped (\"2020-W001\" is sent as \"2020-W01\"), a day of the year is sent as three digits (\"2026-D1\" as \"2026-D001\"), YYYY-A1 is sent as YYYY, and a period of another frequency is mapped onto the dataset's own. A malformed or non-existent period (e.g., \"2020-13\") is rejected as invalid_period. The most effective way to shrink a bulk response: it removes period columns from the TSV rather than blanking their cells."
    • changedInput schema / properties / until_period / description
      Previous value: -"End of the period range (e.g., \"2024\"), sent as endPeriod. Omit for data through the latest available period."New value: +"End of the period range, inclusive (e.g., \"2024\"), sent as endPeriod, in the same forms as since_period. Omit for data through the latest available period. The range must hold at least one day: a since_period that starts after until_period ends is rejected as invalid_period, while pairs of different frequencies are fine (\"2020-06\" to \"2020\")."
    • changedOutput schema / anyOf
      Previous value: -[
      -  {
      -    "not": {
      -      "required": [
      -        "error"
      -      ]
      -    },
      -    "required": [
      -      "datasetCode",
      -      "dimensionsUsed",
      -      "rowCount",
      -      "missingCount",
      -      "periodRange",
      -      "bytesRead",
      -      "compressed",
      -      "budgetExceeded",
      -      "observations",
      -      "appliedQuery"
      -    ]
      -  },
      -  {
      -    "required": [
      -      "error"
      -    ]
      -  }
      -]New value: +[
      +  {
      +    "not": {
      +      "required": [
      +        "error"
      +      ]
      +    },
      +    "required": [
      +      "datasetCode",
      +      "dimensionsUsed",
      +      "rowCount",
      +      "missingCount",
      +      "periodRange",
      +      "bytesRead",
      +      "compressed",
      +      "budgetExceeded",
      +      "observations",
      +      "totalCount",
      +      "appliedQuery"
      +    ]
      +  },
      +  {
      +    "required": [
      +      "error"
      +    ]
      +  }
      +]
    • removedOutput schema / properties / cap
      Removed value: -{
      -  "description": "The preview_limit applied to inline observations.",
      -  "type": "number"
      -}
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `not_found`: The dataset code is not available for dissemination (HTTP 404, SDMX faultcode 100). `invalid_dimension`: A filter names a dimension the dataset does not have, or a value or period range Eurostat rejects (SDMX faultcode 150). `filter_arity`: Eurostat rejected the positional dimension key because it carried the wrong number of positions (SDMX faultcode 140), meaning the dataset structure has changed since the metadata call. `async_queued`: Eurostat answered HTTP 200 with a SOAP syncResponse queue ticket (status SUBMITTED) instead of data, because the extraction was too costly to serve synchronously. `no_results`: The download completed but carried no populated observation cells. `upstream_fault`: The SDMX endpoint returned a fault this server does not model, or a body that is not a TSV table. `canvas_not_found`: A canvas_id was supplied for staging but is unknown or its lifetime has elapsed. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `not_found`: The dataset code is not available for dissemination (HTTP 404, SDMX faultcode 100). `invalid_dimension`: A filter names a dimension the dataset does not have, or a value or period range Eurostat rejects (SDMX faultcode 150). `filter_arity`: Eurostat rejected the positional dimension key because it carried the wrong number of positions (SDMX faultcode 140, INVALID_QUERY_NB_FILTERS), meaning the dataset structure has changed since the metadata call. `invalid_period`: since_period or until_period is not a period literal, or names a month, quarter, semester, trimester, week or day that does not exist, or since_period starts after until_period ends. Checked before any request — the bulk endpoint would otherwise roll an out-of-range period into a neighbouring one, and answer an inverted range with the whole series — and SDMX faultcode 140 TIME_PERIOD_FILTER_SPEC_INVALID maps here too. `async_queued`: Eurostat answered HTTP 200 with a SOAP syncResponse queue ticket (status SUBMITTED) instead of data, because the extraction was too costly to serve synchronously. `no_results`: The download completed but carried no populated observation cells. `upstream_fault`: The SDMX endpoint returned a fault this server does not model, or a body that is not a TSV table. `canvas_not_found`: A canvas_id was supplied for staging but is unknown or its lifetime has elapsed. Other values are possible when a failure originates below the handler."
    • changedOutput schema / properties / error / properties / data / properties / reason / examples
      Previous value: -[
      -  "not_found",
      -  "invalid_dimension",
      -  "filter_arity",
      -  "async_queued",
      -  "no_results",
      -  "upstream_fault",
      -  "canvas_not_found"
      -]New value: +[
      +  "not_found",
      +  "invalid_dimension",
      +  "filter_arity",
      +  "invalid_period",
      +  "async_queued",
      +  "no_results",
      +  "upstream_fault",
      +  "canvas_not_found"
      +]
    • changedOutput schema / properties / notice / description
      Previous value: -"Guidance for every staged result, including the required eurostat_dataframe_describe then eurostat_dataframe_query sequence, composed with byte-budget, no-canvas, or empty-result disclosure when applicable."New value: +"Guidance on every download: the staged table with the required eurostat_dataframe_describe then eurostat_dataframe_query sequence (or, without a canvas, what was returned inline and what was discarded), preceded by byte-budget disclosure when the budget stopped the transfer and by the inline-preview length when preview_limit returns fewer rows than were downloaded."
    • removedOutput schema / properties / shown
      Removed value: -{
      -  "description": "Observations returned in the inline preview.",
      -  "type": "number"
      -}
    • addedOutput schema / properties / totalCount
      Added value: +{
      +  "description": "Observations the download produced — equal to rowCount. The inline observations array holds only the first preview_limit of them; budgetExceeded, not this count, says whether the download is the whole dataset.",
      +  "type": "number"
      +}
    • removedOutput schema / properties / truncated
      Removed value: -{
      -  "description": "True when the inline observation preview omits rows.",
      -  "type": "boolean"
      -}
  8. Changed2 schema fields changed
    • changedInput schema / properties / canvas_id / description
      Previous value: -"Reuse an existing dataframe canvas so this download lands beside earlier results and can be joined against them. Pass a canvasId from a previous response; omit to start a fresh canvas. Ignored on deployments without a dataframe canvas."New value: +"Reuse an existing dataframe canvas so this download lands beside earlier results and can be joined against them. Pass the canvasId a previous eurostat_download_dataset or eurostat_query_dataset response returned; omit to start a fresh canvas. Ignored on deployments without a dataframe canvas."
    • addedInput schema / properties / canvas_id / pattern
      Added value: +"^[A-Za-z0-9_-]{10}$"
  9. Changed2 schema fields changed
    • removedOutput schema / properties / observations / items / additionalProperties / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / observations / items / additionalProperties / type
      Added value: +[
      +  "string",
      +  "number",
      +  "null"
      +]
  10. Changed2 schema fields changed
    • changedOutput schema / properties / notice / description
      Previous value: -"Guidance when the download was cut short by the byte budget, when nothing could be staged, or when it returned no observations. Omitted otherwise."New value: +"Guidance for every staged result, including the required eurostat_dataframe_describe then eurostat_dataframe_query sequence, composed with byte-budget, no-canvas, or empty-result disclosure when applicable."
    • changedOutput schema / properties / tableName / description
      Previous value: -"Canvas table holding every downloaded observation. Omitted when this deployment runs without a dataframe canvas, in which case only the inline preview survives the call."New value: +"Canvas table holding every downloaded observation. Call eurostat_dataframe_describe with canvasId first to confirm the table and columns, then eurostat_dataframe_query. Omitted when this deployment runs without a dataframe canvas, in which case only the inline preview survives the call."
  11. Changed9 schema fields changed
    • changedInput schema / $schema
      Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • addedInput schema / additionalProperties
      Added value: +false
    • changedOutput schema / $schema
      Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • addedOutput schema / anyOf
      Added value: +[
      +  {
      +    "not": {
      +      "required": [
      +        "error"
      +      ]
      +    },
      +    "required": [
      +      "datasetCode",
      +      "dimensionsUsed",
      +      "rowCount",
      +      "missingCount",
      +      "periodRange",
      +      "bytesRead",
      +      "compressed",
      +      "budgetExceeded",
      +      "observations",
      +      "appliedQuery"
      +    ]
      +  },
      +  {
      +    "required": [
      +      "error"
      +    ]
      +  }
      +]
    • addedOutput schema / properties / cap
      Added value: +{
      +  "description": "The preview_limit applied to inline observations.",
      +  "type": "number"
      +}
    • addedOutput schema / properties / error
      Added value: +{
      +  "additionalProperties": {},
      +  "description": "Present when the call failed. Absent on success.",
      +  "properties": {
      +    "code": {
      +      "description": "JSON-RPC error code for this failure.",
      +      "maximum": 9007199254740991,
      +      "minimum": -9007199254740991,
      +      "type": "integer"
      +    },
      +    "data": {
      +      "additionalProperties": {},
      +      "properties": {
      +        "reason": {
      +          "description": "Machine-readable failure mode. Declared by this tool: `not_found`: The dataset code is not available for dissemination (HTTP 404, SDMX faultcode 100). `invalid_dimension`: A filter names a dimension the dataset does not have, or a value or period range Eurostat rejects (SDMX faultcode 150). `filter_arity`: Eurostat rejected the positional dimension key because it carried the wrong number of positions (SDMX faultcode 140), meaning the dataset structure has changed since the metadata call. `async_queued`: Eurostat answered HTTP 200 with a SOAP syncResponse queue ticket (status SUBMITTED) instead of data, because the extraction was too costly to serve synchronously. `no_results`: The download completed but carried no populated observation cells. `upstream_fault`: The SDMX endpoint returned a fault this server does not model, or a body that is not a TSV table. `canvas_not_found`: A canvas_id was supplied for staging but is unknown or its lifetime has elapsed. Other values are possible when a failure originates below the handler.",
      +          "examples": [
      +            "not_found",
      +            "invalid_dimension",
      +            "filter_arity",
      +            "async_queued",
      +            "no_results",
      +            "upstream_fault",
      +            "canvas_not_found"
      +          ],
      +          "type": "string"
      +        },
      +        "recovery": {
      +          "additionalProperties": {},
      +          "description": "Actionable next step for the caller.",
      +          "properties": {
      +            "hint": {
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "hint"
      +          ],
      +          "type": "object"
      +        },
      +        "retryable": {
      +          "description": "Whether retrying may succeed.",
      +          "type": "boolean"
      +        }
      +      },
      +      "type": "object"
      +    },
      +    "message": {
      +      "description": "Human-readable description of what went wrong.",
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "code",
      +    "message"
      +  ],
      +  "type": "object"
      +}
    • addedOutput schema / properties / shown
      Added value: +{
      +  "description": "Observations returned in the inline preview.",
      +  "type": "number"
      +}
    • addedOutput schema / properties / truncated
      Added value: +{
      +  "description": "True when the inline observation preview omits rows.",
      +  "type": "boolean"
      +}
    • removedOutput schema / required
      Removed value: -[
      -  "datasetCode",
      -  "dimensionsUsed",
      -  "rowCount",
      -  "missingCount",
      -  "periodRange",
      -  "bytesRead",
      -  "compressed",
      -  "budgetExceeded",
      -  "observations",
      -  "appliedQuery"
      -]
  12. Added

TDQS

A4.6/5.0
Behavior4/5

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

Goes well beyond the readOnly/idempotent annotations: TSV wire format rationale, one-row-per-non-blank-cell expansion including ':' cells, a streaming decoded-byte budget that retains a complete-row prefix with budgetExceeded, byte_budget_exceeded failure with narrowing guidance, and the loss of rows past the preview when no canvas is staged. The only gap is that it never says rows are or are not deduplicated/ordered beyond the preview, but the operationally critical traits are disclosed.

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

Conciseness4/5

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

Front-loaded with purpose and the sibling contrast, and nearly every clause carries new information (budget semantics, canvas lifecycle, staging handoff). It is a single dense paragraph and slightly repetitive around the period-column argument, which keeps it from a 5.

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?

For a bulk-transfer tool with six parameters, nested filters and a byte budget, the description covers the pre-call research path, the failure modes, the retention caveat without a canvas, and the follow-up call sequence. An output schema exists, so omitting return-value detail is appropriate.

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

Parameters4/5

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

Schema coverage is 100%, so the baseline is 3, but the description adds cross-tool meaning the schema cannot: filters use the same dimension-code map as eurostat_query_dataset and are applied server-side, and period bounds beat row-count limits because the TSV keeps a column per period. It also connects preview_limit to the canvas retention behavior rather than leaving it as a bare integer.

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?

States a specific verb and resource (download a Eurostat dataset in bulk via the SDMX 2.1 TSV endpoint, staged as a SQL table) and explicitly contrasts itself with eurostat_query_dataset as 'the route to a whole dataset' versus 'a slice of one'. An agent can separate the two without opening either schema.

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?

Gives explicit alternatives and sequencing: use query_dataset for slices, call eurostat_get_dataset_info first for dimension codes and eurostat_get_dimension_values for values, and after staging call eurostat_dataframe_describe then eurostat_dataframe_query. It also gives a negative rule — narrow with since_period/until_period rather than requesting the most recent N periods.

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.