# Forecasting Macro Releases: How to Use the FXMacroData Predictions API

Canonical: https://fxmacrodata.com/articles/forecasting-macro-releases-with-predictions-api
Author: FXMacroData
Published: 2026-05-04T14:00:00Z

Market moves before the number drops. The FXMacroData predictions API surfaces market consensus, central-bank projections, IMF WEO forecasts, and survey data where the publisher provides them — all linked to realised observations via a stable announcement_id so you can measure forecast accuracy and build lookahead-free backtests.

## Why forecasts matter as much as the number itself

FX markets do not move on data releases — they move on surprises. When the[Federal Reserve](/dashboard/press-releases/usd) or the[European Central Bank](/dashboard/press-releases/eur) publishes new data, the market has already formed an expectation. If the print matches the consensus, the pair barely twitches. If it deviates, you get the spike.

That gap — the distance between what was expected and what arrived — is where a large share of FX volatility lives. To work with it systematically, you need access to the forecast alongside the actual observation, linked together in a way that lets you compute the surprise without contaminating your data with lookahead.

The FXMacroData predictions API is built for exactly this workflow. It surfaces forecasts from multiple source categories and links every prediction to its target announcement via a stable`announcement_id`, so you can join predictions with realised values, measure forecast accuracy over time, and build surprise indices for any indicator and currency combination you care about.

**One thing to settle first:**not every forecast is a market consensus, and many releases have no consensus from any official publisher. Which forecast classes exist for a given release, and which of them genuinely represent a consensus of forecasters, is covered in[Consensus, Nowcast or Projection?](/articles/prediction-classes-consensus-vs-nowcast) . Read that before you use any of the numbers below as an expectation term.

## What the predictions endpoint returns

One route exposes prediction data for a specific currency and indicator:

- `/v1/predictions/{currency}/{indicator}`— all forecasts for a specific currency and indicator pair, with optional filters for prediction type and source.

Forecast data requires an active plan on every currency,[USD](/united-states) included. Every paid plan returns the same forecast sources: a paid key widens the date window you can query, it does not add forecast sources.

The response groups entries by announcement. Each group carries the`announcement_id`— a stable, deterministic key in the form`{currency}_{indicator}_{date}`— followed by a`predictions`list where each entry records the forecast value, its source, and a human-readable label. Here is a minimal example for[USD inflation](/api-data-docs/usd/inflation) :

```
{
  "currency": "USD",
  "indicator": "inflation",
  "count": 2,
  "prediction_count": 3,
  "data": [
    {
      "announcement_id": "usd_inflation_2026-02-28",
      "currency": "usd",
      "indicator": "inflation",
      "date": "2026-02-28",
      "announcement_datetime": 1773232200,
      "predictions": [
        {
          "predicted_value": 2.9,
          "prediction_type": "market_consensus",
          "prediction_source": "philly_fed_spf",
          "prediction_source_label": "Philadelphia Fed Survey of Professional Forecasters"
        }
      ]
    },
    {
      "announcement_id": "usd_inflation_2026-03-31",
      "currency": "usd",
      "indicator": "inflation",
      "date": "2026-03-31",
      "predictions": [
        {
          "predicted_value": 2.6,
          "prediction_type": "market_consensus",
          "prediction_source": "philly_fed_spf",
          "prediction_source_label": "Philadelphia Fed Survey of Professional Forecasters"
        },
        {
          "predicted_value": 2.5,
          "prediction_type": "imf_weo",
          "prediction_source": "imf_weo",
          "prediction_source_label": "IMF World Economic Outlook"
        }
      ]
    }
  ]
}
```

The`announcement_id`on every prediction row is identical to the one returned by`/v1/announcements/{currency}/{indicator}`, so a simple dictionary join is all you need to pair each forecast with its realised observation.

## Prediction source categories

Nine`prediction_type`values are currently recognised. Understanding the difference matters for how you weight and interpret each forecast:

prediction_type What it is Example sources`market_consensus`Compiled market poll of professional forecasters Philadelphia Fed SPF, Reuters poll`market_prediction`Individual professional-forecaster point prediction Forecaster-level disaggregated survey data`survey`Central-bank survey of professional forecasters[ECB Survey of Professional Forecasters](/api-data-docs/eur/inflation)`model_nowcast`Institutional model nowcast for a current-period release Atlanta Fed GDPNow, New York Fed Staff Nowcast`central_bank_forecast`Official central-bank projection published in monetary policy statements[RBNZ Monetary Policy Statement](/api-data-docs/nzd/inflation) ,[BoC Monetary Policy Report](/api-data-docs/cad/inflation)`central_bank_projection`Official central-bank staff or committee projection (e.g.[FOMC](/articles/federal-reserve) SEP medians,[ECB](/articles/european-central-bank) staff projections) FOMC Summary of Economic Projections, Riksbank Monetary Policy Report`imf_weo`IMF World Economic Outlook projection Published twice yearly, all supported currencies`oecd_eo`OECD Economic Outlook projection Published twice yearly for OECD member currencies`fxmacrodata`FXMacroData blended forecast derived from stored macro history and available external forecasts FXMacroData Blended Forecast

Each source serves a different analytical purpose. Market consensus is the short-horizon market expectation that drives immediate FX reaction on release day. Central-bank forecasts reflect the institution's own outlook and are useful for tracking how much the bank's projections evolve between meetings. IMF WEO forecasts provide a neutral multi-year baseline and are consistent across all 22 covered currencies, making them useful for cross-currency comparisons.

## Building a surprise index in Python

The most direct application of the predictions API is computing a release surprise index — the deviation of the actual print from the market expectation, expressed in standard deviations of historical surprises. Here is a complete example for[US Non-Farm Payrolls](/api-data-docs/usd/non_farm_payrolls) . The[NFP](/articles/labor-statistics-fx-trading) endpoint serves the payroll employment level in persons (BLS publishes it in thousands), so the Philadelphia Fed SPF consensus used here is the quarterly-average payroll-employment level rather than the headline one-month payroll-change poll.

```
import requests
import statistics

BASE = "https://api.fxmacrodata.com"

# Fetch predictions — forecast values require an API key, USD included
preds_resp = requests.get(
    f"{BASE}/v1/predictions/usd/non_farm_payrolls",
    params={
        "prediction_type": "market_consensus",
        "prediction_source": "philly_fed_spf",
    },
    headers={"X-API-Key": "YOUR_API_KEY"},
    timeout=30,
).json()

# Fetch actuals
actuals_resp = requests.get(
    f"{BASE}/v1/announcements/usd/non_farm_payrolls",
    params={"start_date": "2020-01-01"},
    timeout=30,
).json()

# Index actuals by announcement_id
actuals = {row["announcement_id"]: row["val"] for row in actuals_resp["data"]}

# Compute surprises (actual - consensus)
surprises = []
for group in preds_resp["data"]:
    aid = group["announcement_id"]
    actual = actuals.get(aid)
    if actual is None:
        continue
    # Use the first (or only) prediction in the group
    forecast = group["predictions"][0]["predicted_value"]
    surprises.append({
        "date": group["date"],
        "actual": actual,
        "forecast": forecast,
        "surprise": actual - forecast,
    })

# Normalise to z-scores
values = [s["surprise"] for s in surprises]
mean = statistics.mean(values)
stdev = statistics.stdev(values)
for s in surprises:
    s["z_score"] = (s["surprise"] - mean) / stdev

# Print recent surprises
for s in surprises[-6:]:
    direction = "↑ beat" if s["z_score"] > 0 else "↓ miss"
    print(f"{s['date']}: actual={s['actual']:,.0f}  forecast={s['forecast']:,.0f}  "
          f"surprise={s['surprise']:+,.0f}  z={s['z_score']:+.2f}  {direction}")

```

The output gives you a time series of normalised surprises that can be directly correlated with USD spot moves on release days to quantify the surprise-to-FX transmission coefficient for any given indicator.

## Comparing central-bank forecasts to market consensus

A useful signal in rate-sensitive currency pairs is the divergence between what the central bank projects and what the market expects. When the two converge, it often signals that the market has fully digested the bank's guidance. When they diverge, it can indicate either a credibility gap or a genuine information asymmetry between the bank and the buy side.

You can retrieve both forecast types in a single request and compute the divergence directly:

```
import requests

# Fetch all prediction types for EUR inflation together
resp = requests.get(
    "https://api.fxmacrodata.com/v1/predictions/eur/inflation",
    headers={"X-API-Key": "YOUR_API_KEY"},
    timeout=30,
).json()

# For each announcement group, compare central_bank_forecast vs market_consensus
for group in resp["data"]:
    preds_by_type = {p["prediction_type"]: p for p in group["predictions"]}
    cb = preds_by_type.get("central_bank_forecast")
    mkt = preds_by_type.get("market_consensus")
    if cb and mkt:
        divergence = cb["predicted_value"] - mkt["predicted_value"]
        print(f"{group['date']}: CB={cb['predicted_value']:.2f}%  "
              f"Market={mkt['predicted_value']:.2f}%  "
              f"Divergence={divergence:+.2f}pp  "
              f"({cb['prediction_source_label']})")

```

Positive divergence (the central bank projects higher inflation than the market) is typically a hawkish signal. The bank either has non-public information or is deliberately signalling concern about above-target inflation. Sustained positive divergence has historically preceded surprise hikes in several currency pairs tracked on the[release calendar](/dashboard/release-calendar) .

## Cross-currency forecast comparison with IMF WEO

Because IMF WEO projections exist for every covered currency and use a consistent methodology, they are well-suited to cross-currency comparisons. The following snippet pulls[GDP](/api-data-docs/aud/gdp) forecasts for the four major commodity-linked currencies and ranks them by expected growth:

```
import requests

API_KEY = "YOUR_API_KEY"
CURRENCIES = ["aud", "cad", "nzd", "brl"]

forecasts = {}
for ccy in CURRENCIES:
    resp = requests.get(
        f"https://api.fxmacrodata.com/v1/predictions/{ccy}/gdp",
        params={"prediction_type": "imf_weo"},
        headers={"X-API-Key": API_KEY},
        timeout=30,
    ).json()
    if resp.get("data"):
        # Take the most recent forecast
        latest = resp["data"][-1]
        forecasts[ccy.upper()] = latest["predictions"][0]["predicted_value"]

# Rank by projected growth
ranked = sorted(forecasts.items(), key=lambda x: x[1], reverse=True)
print("IMF WEO GDP forecast ranking:")
for rank, (ccy, val) in enumerate(ranked, 1):
    print(f"  {rank}. {ccy}: {val:.1f}% YoY")

```

This kind of ranking feeds naturally into relative-value frameworks for commodity-currency pairs like AUD/CAD or NZD/AUD, where growth differentials are a primary driver of medium-term carry positioning.

## Filtering by prediction source

When a single announcement has multiple predictions from different sources, you may want to isolate a specific one. Use the`prediction_source`query parameter with the stable source slug:

```
# Philadelphia Fed Survey of Professional Forecasters only
curl -H "X-API-Key: YOUR_API_KEY" "https://api.fxmacrodata.com/v1/predictions/usd/inflation?prediction_source=philly_fed_spf"

# ECB Survey of Professional Forecasters
curl -H "X-API-Key: YOUR_API_KEY" "https://api.fxmacrodata.com/v1/predictions/eur/inflation?prediction_source=ecb_spf"

# RBNZ Monetary Policy Statement
curl -H "X-API-Key: YOUR_API_KEY" "https://api.fxmacrodata.com/v1/predictions/nzd/inflation?prediction_source=rbnz_mps"

# IMF World Economic Outlook
curl -H "X-API-Key: YOUR_API_KEY" "https://api.fxmacrodata.com/v1/predictions/usd/inflation?prediction_source=imf_weo"

```

The`prediction_source_label`field in the response gives the full human-readable name of the source, suitable for chart labels and report footnotes. Use the stable`prediction_source`slug for filtering and programmatic joins.

## Using the release calendar for upcoming forecasts

The[release calendar](/dashboard/release-calendar) surfaces upcoming announcement dates for all covered currencies. When you combine calendar data with the predictions endpoint, you can build a forward-looking dashboard that shows the current consensus for each upcoming release.

```
import requests
from datetime import date

API_KEY = "YOUR_API_KEY"
BASE = "https://api.fxmacrodata.com"

# Get upcoming USD releases
calendar = requests.get(f"{BASE}/v1/calendar/usd").json()
upcoming = [row for row in calendar["data"] if row.get("release")]

# For each upcoming release, fetch the current consensus prediction
for release in upcoming[:5]:
    indicator = release["release"]
    preds = requests.get(
        f"{BASE}/v1/predictions/usd/{indicator}",
        params={"prediction_type": "market_consensus"},
        headers={"X-API-Key": API_KEY},
        timeout=30,
    ).json()
    if preds.get("data"):
        latest_pred = preds["data"][-1]
        if latest_pred.get("predictions"):
            val = latest_pred["predictions"][0]["predicted_value"]
            print(f"{indicator}: consensus={val}")

```

## Point-in-time discipline: only use what was knowable

A forecast is valid for a backtest only if it existed*before*the release it predicts. Every prediction row carries a`generated_at`timestamp, and the acceptance rule is strict: keep the row only when`generated_at`is earlier than the announcement's`announcement_datetime`. FXMacroData enforces this structurally — the prediction store refuses to persist any forecast generated at or after the release, so the API cannot hand you a look-ahead row even by accident. Keep`pre_release_only=true`(the default) and you can re-verify the rule independently on every row.

**Coverage depth is a property of the publisher, not your plan.**Pre-release history exists where an official source has been publishing forecasts for years — and it honestly does not exist where no source did. No plan, parameter, or export route unlocks additional historical consensus rows.

USD pre-release forecast depth by event family (2013 → today)

CPI / Core CPI Unemployment FOMC decision NFP · PPI · Retail 2013 Aug 2013 today every monthly release no historical event-specific consensus, on any plan

The verified USD picture for point-in-time research:[CPI](/articles/inflation-indicators-fx-guide) and Core CPI carry Cleveland Fed nowcasts for every monthly release from the August 2013 reference period onward, on both the year-over-year and month-over-month series. The[unemployment rate](/united-states/unemployment#api-docs) carries FOMC SEP median projection vintages for every year-end release from 2015 (with the NY Fed's market-expectations survey adding vintages from 2023), FOMC rate decisions have sparser source-labelled coverage starting in 2023, and historical event-specific market consensus is not available for Non-Farm Payrolls, PPI, or[retail sales](/indicators/retail-sales) . The full picture — every currency, every source, and verified history depth — lives on the[forecast coverage matrix](/documentation/predictions#coverage) , and the step-by-step research workflow is in the[point-in-time backtesting guide](/documentation/point-in-time-backtesting) .

When you pull history, always pass explicit`start_date`and`end_date`: the endpoint's default window is only about the last six months, so an unfiltered query over an old study period returns a near-empty result that is easy to misread as missing data.

## Endpoint reference summary

Full parameter documentation is available on the[API reference page](/documentation/) . The table below gives a quick reference for the two predictions routes:

Parameter Type Description`currency`path 3-letter currency code. An API key is required on every currency, USD included.`indicator`path or query Indicator slug (e.g.`inflation`,`policy_rate`,`gdp`). Path in the`/{currency}/{indicator}`route; optional query on`/{currency}`.`prediction_type`query Legacy category:`market_consensus`,`market_prediction`,`model_nowcast`,`survey`,`central_bank_forecast`,`central_bank_projection`,`imf_weo`,`oecd_eo`,`fxmacrodata`. Prefer`prediction_class`, which merges the values naming the same instrument. See[the class reference](/articles/prediction-classes-consensus-vs-nowcast) .`prediction_source`query Stable source slug (e.g.`philly_fed_spf`,`ecb_spf`,`imf_weo`).`start_date`/`end_date`query Period date range (YYYY-MM-DD). Defaults to roughly the last 6 months through the next quarter — pass explicit dates for historical research.`X-API-Key`header API key from any active plan. Required for all currencies.

The predictions API is designed to sit alongside the[inflation](/indicators/inflation) ,[policy rate](/indicators/policy_rate) , and other indicator overview pages — where cross-currency comparisons are most useful — and the[release calendar](/dashboard/release-calendar) , where the timing of upcoming announcements meets the forecasts that precede them.

Source: FXMacroData
