Guides

Accessing Macro Data Vintages with FinzData

FinzData provides access to every vintage of US macroeconomic series from FRED/ALFRED, showing each value as first published and all subsequent revisions. This allows analysts to study data revisions in real time or historically, using the same data structure as the Federal Reserve's ALFRED system. You can retrieve first releases, latest values, or the full history of revisions for any series, and filter by a specific date to see what was known at that time.

Updated 2026-10-11. Code on this page was run against live FinzData data before publishing.

Understanding Macro Data Vintages

Macroeconomic data series like CPI or nonfarm payrolls are subject to revisions after their initial release. Each time a value is updated, FinzData stores both the new value and preserves the original. This creates a vintage structure where each observation has a 'realtime_start' (when it was first published) and 'realtime_end' (when it was last revised).

The 'first' vintage returns values as they were first released, without any later revisions. The 'latest' vintage (default) returns the most recent available value for each date. The 'all' vintage returns every published version of each value, showing the full revision history. These correspond directly to ALFRED's vintage options.

Using vintages helps avoid look-ahead bias in backtesting and allows measurement of how much initial estimates were revised over time. This is critical for evaluating the reliability of early economic signals.

Setting Up the FinzData Client

Begin by installing the FinzData Python client and setting your API key as an environment variable. The client automatically reads FINZDATA_API_KEY, so no hardcoding is needed in your scripts.

Import the library and create a client instance. The free plan provides access to the latest values of 158 macro series, but accessing vintages requires a look-back bundle or Institutional plan due to the historical nature of revision data.

Once the client is initialized, you can query macro series using standard identifiers like 'CPIAUCSL' for Consumer Price Index or 'PAYEMS' for nonfarm payrolls.

import finzdata as yf
import os

# API key is read from environment variable FINZDATA_API_KEY
c = yf.Client()

Retrieving First Releases with vintage='first'

To get values as they were first published, use vintage='first'. This shows the initial estimate for each date, without any later revisions. It is useful for simulating real-time decision making or analyzing the original market impact of data releases.

For example, retrieving CPIAUCSL with vintage='first' returns the CPI value as first reported each month. The 'realtime_start' column indicates when that value was published, and 'realtime_end' shows when that value was replaced by a revision (9999-12-31 while it is still current).

This vintage is available only with a look-back bundle or Institutional plan, as it requires access to historical revision data.

import finzdata as yf
# Needs a look-back bundle or the Institutional plan (free keys get HTTP 403)
c = yf.Client()

# First release values of CPI
cpi_first = c.macro("CPIAUCSL", vintage="first", start="2020-01-01")
print(cpi_first[["date", "value", "realtime_start"]].head())

Getting Latest Values with vintage='latest'

The default behavior when calling c.macro() is to return the latest vintage, equivalent to specifying vintage='latest'. This gives the most current value available for each date, incorporating all known revisions up to now.

This is what most economic dashboards and APIs display by default. For example, the latest CPI value for a past date may differ from its first release due to corrections, seasonal factor updates, or annual benchmark revisions.

The free plan allows access to latest values for 158 macro series, making this accessible without a paid bundle for current analysis.

import finzdata as yf
# Needs a look-back bundle or the Institutional plan (free keys get HTTP 403)
c = yf.Client()

# Latest values of CPI (default)
cpi_latest = c.macro("CPIAUCSL", start="2020-01-01")
print(cpi_latest[["date", "value"]].head())

Accessing Full Revision History with vintage='all'

To see every published version of each data point, use vintage='all'. This returns multiple rows per date, each representing a different vintage of the same observation. It reveals how estimates evolved over time through successive revisions.

For example, a single month's payrolls figure might appear several times in the output, each with a different 'value' and progressively later 'realtime_start' dates, showing when each revision was published.

This level of detail requires a look-back bundle or Institutional plan, as it involves accessing the complete history of data revisions.

import finzdata as yf
# Needs a look-back bundle or the Institutional plan (free keys get HTTP 403)
c = yf.Client()

# All vintages of nonfarm payrolls
payrolls_all = c.macro("PAYEMS", vintage="all", start="2020-01-01")
print(payrolls_all[["date", "value", "realtime_start"]].head(10))

Using as_of to See What Was Known on a Date

The as_of parameter lets you reconstruct the real-time data available on a specific historical date. It returns only the data that had been published by that date, mimicking the information set available to policymakers or traders at the time.

For example, setting as_of='2022-06-30' and vintage='all' on CPIAUCSL shows what the CPI values were believed to be as of June 2022, before any later revisions were published. This is essential for avoiding look-ahead bias in backtesting economic models.

as_of works on its own (no vintage argument needed) and is only available with a look-back bundle or Institutional plan.

import finzdata as yf
# Needs a look-back bundle or the Institutional plan (free keys get HTTP 403)
c = yf.Client()

# CPI as known on June 30, 2022
cpi_as_of = c.macro("CPIAUCSL", vintage="all", as_of="2022-06-30")
print(cpi_as_of[["date", "value", "realtime_start"]].tail())

Measuring the Size of Revisions

To quantify how much initial estimates were revised, compare the 'first' and 'latest' values for the same date. The difference reveals the cumulative revision over time, which can be analyzed for bias, volatility, or correlation with economic conditions.

For example, merging first and latest CPI values by date allows you to compute revision size as (latest - first). Tracking the average and standard deviation of these differences helps assess data reliability.

Such analysis is only possible with access to both vintages, which requires a look-back bundle or Institutional plan.

import finzdata as yf
import pandas as pd
# Needs a look-back bundle or the Institutional plan (free keys get HTTP 403)

c = yf.Client()

# Get first and latest CPI values
cpi_first = c.macro("CPIAUCSL", vintage="first", start="2000-01-01")
cpi_latest = c.macro("CPIAUCSL", vintage="latest", start="2000-01-01")

# Merge on date and calculate revision
cpi_merged = pd.merge(
    cpi_first[['date', 'value']].rename(columns={'value': 'first_value'}),
    cpi_latest[['date', 'value']].rename(columns={'value': 'latest_value'}),
    on='date'
)
cpi_merged['revision'] = cpi_merged['latest_value'] - cpi_merged['first_value']
print(cpi_merged[['date', 'first_value', 'latest_value', 'revision']].tail())

Questions

Do I need a paid plan to access macro data vintages in FinzData?

Accessing the latest values of 158 macro series is free. However, retrieving vintages such as 'first', 'all', or using the 'as_of' parameter requires a look-back bundle or Institutional plan, as it involves historical revision data.

How does FinzData's macro vintage feature compare to ALFRED?

FinzData provides the same vintage structure as the Federal Reserve's ALFRED system: each observation includes 'realtime_start' and 'realtime_end' timestamps, and supports 'first', 'latest', 'all', and 'as_of' queries. The Python client mirrors ALFRED's functionality for programmatic access.

Can I use macro vintages to avoid look-ahead bias in backtesting?

Yes. By passing an as_of date, you can retrieve only the data that was publicly available on that historical date. This ensures your model or strategy does not use information that would not have been known at the time.