Skip to content

Announcement series variants

One endpoint, explicit macro series parameters.

FXMacroData uses a stable announcement path and query parameters to select the exact macro series variant. This keeps existing URLs working while exposing the basis fields customers need for cross-currency comparison: seasonal adjustment, real or nominal basis, returned frequency, source series ID, revision view, and pagination.

Stable path
https://api.fxmacrodata.com/announcements/{currency}/{indicator}
Default rows
limit=20, most-recent-first, maximum 100
Compatibility
Existing v1 clients keep receiving the canonical series when selectors are omitted.

Endpoint model

Use parameters instead of endpoint sprawl.

The public route stays /api/v1/announcements/{currency}/{indicator}. Customers then add selectors only when they need a non-default variant. For example, GDP can be requested as real or nominal and unemployment can expose whether the selected source is seasonally adjusted. We do not create parallel slugs such as real_gdp, gdp_nominal_yoy, or unemployment_sa.

Canonical by default

/usd/gdp returns the current canonical GDP series. For GDP, FXMacroData uses a real official series where one is available.

Selectors are explicit

basis=nominal, seasonality=sa, frequency=yoy, and revisions=first make the requested variant auditable.

Unsupported requests fail clearly

If a selector is not available for that endpoint, the API returns 400 unsupported_series_option with supported values.

Query parameters

Selectors available on announcement endpoints.

These parameters are available on the announcement endpoint family. Not every indicator supports every selector. Read supported_options in the response, or the data catalogue, before building a selector UI.

Parameter Values Default Purpose
seasonality sa, nsa Canonical endpoint series Selects seasonally adjusted or not seasonally adjusted data when both are available. The response metadata reports seasonal_adjustment as SA, NSA, UNKNOWN, or NOT_APPLICABLE.
frequency level, yoy, qoq, mom Canonical endpoint series Selects the returned observation basis. Use level for the level/index/rate itself, or a change basis when the endpoint supports one.
revisions latest, first, final, all latest Controls whether rows use the latest known value, the first published value, final revised value, or include all stored revision events in revisions[].
basis real, nominal Canonical endpoint series Selects inflation-adjusted real data or current-price nominal data where both are available. The response metadata reports price_basis as REAL, NOMINAL, or UNKNOWN.
series_mode raw, canonical raw Controls whether configured continuity remaps are applied. Use canonical when you want FXMacroData's continuity rules across source methodology transitions.
start_date, end_date YYYY-MM-DD Endpoint default window Restricts rows by observation period date. Rows are still sorted most-recent-first.
limit, offset, page limit 1 to 100, offset 0+, page 1+ limit=20, offset=0 Paginates most-recent-first data[] after date filters are applied. page is one-based and derives offset as (page - 1) * limit.
api_key Your FXMacroData key Not required for public USD freemium windows up to 100 requests/day, delivered on a 15-minute delay Recommended in public examples. Required for non-USD, paid-only, higher-volume, or full-history requests. Server-side clients may also use X-API-Key.

Pagination and sparse windows

Use the built-in pagination contract for long histories.

Announcement endpoints support broad historical windows. Date filters are applied first, rows are sorted most-recent-first, and the response page is controlled by limit plus either offset or page. To fetch the next page, reuse the same filters and pass offset=pagination.next_offset. Do not split broad ranges into custom shorter-window retries unless your application is intentionally sampling a specific sub-period.

Latest-row signal

page_includes_latest_available appears at the top level and inside pagination. It is true when the current page contains latest_available_date. If it is false, the latest observation is on another page or the current response is a historical page.

Sparse windows

Monthly, quarterly, and irregular series can be valid but have no observations inside a narrow recent date window. That is an empty result, not a missing series: the API returns 200 with data: [] and a no_data object carrying the coverage the series actually has, so you can widen the window without guessing. A 404 on this endpoint always means the currency or indicator slug is wrong.

{
  "currency": "NZD",
  "indicator": "core_inflation",
  "requested_start_date": "2026-04-01",
  "requested_end_date": "2026-06-22",
  "requested_window_has_data": false,
  "earliest_available_date": "1999-03-31",
  "latest_available_date": "2026-03-31",
  "no_data": {
    "error_code": "NO_DATA_IN_REQUESTED_WINDOW",
    "message": "No observations available for NZD/core_inflation in requested range (2026-04-01 to 2026-06-22).",
    "earliest_available_date": "1999-03-31",
    "latest_available_date": "2026-03-31",
    "recommended_start_date": "2026-03-31",
    "available_observation_count": 109
  },
  "data": []
}
Anonymous callers: USD access without an API key returns the most recent 90 days, and a release becomes readable 15 minutes after publication. A quarterly or annual series whose latest observation is older than that window returns the same empty 200, with no_data.freemium_clamped=true. Supply an API key to read it.
Daily market-level exception: some daily level series, such as government bond yields, may return the latest eligible official observation before the requested window when it is recent enough. Those responses set requested_window_has_data=false and mark the row with outside_requested_window=true.

Examples

Common request shapes.

Canonical GDP

GET https://api.fxmacrodata.com/announcements/usd/gdp

Real GDP growth

GET https://api.fxmacrodata.com/announcements/usd/gdp?basis=real&frequency=yoy&limit=20

Nominal GDP level

GET https://api.fxmacrodata.com/announcements/usd/gdp?basis=nominal&frequency=level&api_key=YOUR_API_KEY

Seasonally adjusted unemployment

GET https://api.fxmacrodata.com/announcements/sek/unemployment?seasonality=sa&api_key=YOUR_API_KEY

First-published release values

GET https://api.fxmacrodata.com/announcements/usd/gdp?basis=real&revisions=first

Second page of history

GET https://api.fxmacrodata.com/announcements/usd/gdp?limit=20&offset=20

Python requests

Copyable Python selector examples

Use these snippets when testing announcement selectors from a notebook, job, or service. The params dict mirrors the query string exactly.

Canonical USD GDP

Default announcement series with pagination controls.

import requests

url = "https://api.fxmacrodata.com/v1/announcements/usd/gdp"
params = {
    "limit": "20",
    "page": "1",
}
response = requests.get(url, params=params, timeout=20)
response.raise_for_status()
payload = response.json()

print(payload.get("data", payload))

Nominal GDP selector

Explicit basis and frequency selectors, with query-parameter authentication.

import requests

url = "https://api.fxmacrodata.com/v1/announcements/usd/gdp"
params = {
    "basis": "nominal",
    "frequency": "level",
    "api_key": "YOUR_API_KEY",
}
response = requests.get(url, params=params, timeout=20)
response.raise_for_status()
payload = response.json()

print(payload.get("data", payload))

SEK unemployment selector

Non-USD example with seasonality and API key in the query string.

import requests

url = "https://api.fxmacrodata.com/v1/announcements/sek/unemployment"
params = {
    "seasonality": "sa",
    "limit": "20",
    "page": "1",
    "api_key": "YOUR_API_KEY",
}
response = requests.get(url, params=params, timeout=20)
response.raise_for_status()
payload = response.json()

print(payload.get("data", payload))

Response fields

Top-level fields explain the selected series.

Treat the top-level metadata as part of the data contract. It tells downstream systems exactly which source series, seasonal adjustment basis, price basis, and selector combination produced the rows in data[].

Field Type Meaning
currency, indicator, name, value_name String Identity fields for the requested currency and indicator.
source, source_url, source_url_scope, source_series_id, source_series_name, source_local_name String or null Official source metadata. source_url is optional; when present, source_url_scope identifies it as an exact release, broader dataset, or underlying series link. source_series_id is the audit key customers should store when comparing variants.
seasonal_adjustment Enum SA, NSA, UNKNOWN, or NOT_APPLICABLE. This field makes SA/NSA comparability explicit.
price_basis Enum REAL, NOMINAL, or UNKNOWN. This distinguishes inflation-adjusted series from current-price series.
filters Object Echoes the selector parameters that were applied to the response.
selected_series_id, selected_series String, object The resolved source-series variant. Use this for audit logs and stable downstream joins.
supported_options Object Lists valid selector values for this endpoint. Build client dropdowns from this object rather than assuming every indicator supports every value.
pagination Object Contains limit, offset, returned_count, total_count, has_more, next_offset, and page_includes_latest_available.
earliest_available_date, latest_available_date, start_date, end_date Date string or null Coverage and requested-window dates for the selected series.
requested_start_date, requested_end_date Date string The effective date window used for the request after endpoint defaults are resolved.
requested_window_has_data Boolean False when the response returns the latest eligible observation before the requested window rather than an observation inside the window.
page_includes_latest_available Boolean True when the current page contains latest_available_date. Also mirrored in pagination.page_includes_latest_available.
data_quality Object Standardized source, freshness, fallback/proxy, timestamp-completeness, and point-in-time safety diagnostics. Announcement endpoints may also add requested-window and pagination flags.
provenance Object Machine-readable provenance such as storage layer, timestamp field, value field, source URL, and source series ID.
is_proxy, proxy_note, policy_role, policy_structure, comparison_compatible, policy_family Optional fields Additional comparability fields used on policy-rate or proxy-backed series where relevant.

Source-link availability

A supported indicator does not guarantee an exact official release permalink on every row. Display source_url only when present and use source_url_scope to label its precision honestly. If your product requires an exact BLS, BEA, central-bank, or other agency release link for every event, probe the required series before launch and provide a clear unavailable state.

Data quality

Quality flags are standardized across source-backed endpoints.

Use data_quality before treating a payload as analysis-ready. It describes the whole requested window, not the current page, so the same object is returned for every page of one query.

point_in_time_safe is true when no row in that window can surface earlier than it was actually public. Official release calendars do not reach the full length of most macro series. Where a calendar stops, the publication timestamp is derived from the largest publication lag and the latest release clock that same series has shown, snapped to a valid trading day, and the row is flagged release_time_assumed. Because that bound is the slowest release the series has ever produced, a derived row cannot appear before the real one did, and it does not clear point_in_time_safe. Those rows also carry release_time_upper_bound.

A derived timestamp is still not an observed one: it is calibrated, not exact, and it is deliberately late rather than early. Read assumed_release_time_count against row_count to size how much of the window is derived, and gate per row on release_time_assumed when a study needs captured timestamps only. point_in_time_safe still goes false when a row has no timestamp at all, or when its timestamp predates the upper-bound rule and may land early; unbounded_release_time_count counts those. For reporting, also store source_type, source_name, latest_available_date, and the fallback/proxy flags.

Worked example: /v1/announcements/usd/inflation over its full history returns row_count 1349 with assumed_release_time_count 997. Those 997 rows are dated from the slowest release this series has shown, so none of them can appear early and the response stays point-in-time safe. The count is what tells you how much of the window is calibrated rather than captured; gate on release_time_assumed if your study needs only the 352 captured rows.

Source flags

is_official source_type source_name is_proxy is_fallback is_derived

source_type is normalized to official, public, fallback, or derived.

Freshness flags

latest_available_date last_updated data_lag_days is_stale stale_after_days

Staleness thresholds are frequency-aware: daily, weekly, monthly, quarterly, and annual series use different default windows.

Backtest flags

has_announcement_datetime point_in_time_safe has_assumed_release_times assumed_release_time_count announcement_datetime_count missing_announcement_datetime_count quality_scope

A missing timestamp and a derived timestamp both clear point_in_time_safe. The two counts separate them: missing_announcement_datetime_count is rows with no publication time, assumed_release_time_count is rows whose publication time was derived.

Observation rows

Each row states how its publication time was established.

Required row fields

announcement_id date val

date is the economic period, while announcement_datetime is when the value became known to the market.

Release timing

announcement_datetime announcement_datetime_local release_time_assumed

Backtests should gate on the announcement timestamp, not the period date. release_time_assumed is present and true only when that timestamp was derived from the series' measured publication lag rather than captured from the release; a captured row omits the field.

Change fields

val_mom pct_change pct_change_12m pct_change_qoq pct_change_yoy

These fields are present where meaningful for the selected series. Clients should tolerate missing or null change fields.

Previous observation

previous_value previous_date previous_announcement_datetime

These fields refer to the preceding observation in the selected chronological series when one is available. They are distinct from revisions to the current observation.

Revision fields

revisions[] epoch val

Use revisions=all when the application needs the stored revision trail rather than the latest row view.

Sample payload

USD GDP real-basis response shape.

Values below are illustrative of the contract. Always read supported_options from the live response before requesting a non-default variant.

{
  "currency": "USD",
  "indicator": "gdp",
  "name": "GDP",
  "source": "BEA",
  "source_series_id": "BEA:real_gdp",
  "source_series_name": "Real Gross Domestic Product",
  "seasonal_adjustment": "SA",
  "price_basis": "REAL",
  "requested_start_date": "2020-01-01",
  "requested_end_date": "2026-06-22",
  "requested_window_has_data": true,
  "page_includes_latest_available": true,
  "earliest_available_date": "2020-03-31",
  "latest_available_date": "2026-03-31",
  "filters": {
    "basis": "real",
    "frequency": "level",
    "revisions": "latest"
  },
  "selected_series_id": "usd_gdp_real_sa_level",
  "selected_series": {
    "basis": "real",
    "frequency": "level",
    "seasonality": "sa",
    "source_series_id": "BEA:real_gdp"
  },
  "supported_options": {
    "basis": ["real", "nominal"],
    "frequency": ["level", "qoq", "yoy"],
    "seasonality": ["sa"],
    "revisions": ["latest", "first", "final", "all"]
  },
  "pagination": {
    "limit": 20,
    "offset": 0,
    "returned_count": 20,
    "total_count": 63,
    "has_more": true,
    "next_offset": 20,
    "page_includes_latest_available": true
  },
  "data_quality": {
    "is_official": true,
    "is_proxy": false,
    "is_fallback": false,
    "is_stale": false,
    "has_announcement_datetime": true,
    "point_in_time_safe": true,
    "has_assumed_release_times": false,
    "assumed_release_time_count": 0,
    "latest_available_date": "2026-03-31",
    "last_updated": null,
    "data_lag_days": 83,
    "source_name": "BEA",
    "source_type": "official",
    "is_derived": false,
    "row_count": 63,
    "announcement_datetime_count": 63,
    "missing_announcement_datetime_count": 0,
    "quality_scope": "full_result",
    "stale_after_days": 125,
    "requested_window_has_data": true,
    "page_includes_latest_available": true
  },
  "data": [
    {
      "announcement_id": "usd_gdp_2026-03-31",
      "date": "2026-03-31",
      "val": 6038.164,
      "pct_change_qoq": 0.4,
      "pct_change_yoy": 2.57,
      "announcement_datetime": 1777552200,
      "announcement_datetime_local": "2026-04-30T08:30:00-04:00",
      "revisions": [{ "epoch": 1777552200, "val": 6038.164 }]
    }
  ]
}

Client workflow

How customers should discover variants.

Recommended flow

Call the canonical endpoint first, inspect supported_options, then request only the variant needed by the application. Store source_series_id, seasonal_adjustment, and price_basis with downstream observations.

Pagination flow

Read pagination.has_more and request the next page with offset=pagination.next_offset. Use page_includes_latest_available to know whether the latest observation is on the current page.

Design rule: there is no public "return all series variants" selector. Customers choose one series variant per request, which keeps responses predictable and prevents large repeated pulls of slow-moving macro history.

Errors and compatibility

What changes for existing users.

Additive v1 change

Existing calls such as /api/v1/announcements/usd/inflation continue to work. New metadata fields are additive, so clients should ignore unknown fields they do not use.

Selector errors

400 unsupported_series_option means the selector value is valid globally but not available for that specific currency and indicator. Read supported_options and retry.

Auth and limits

401 or 403 indicates missing or insufficient API access. 429 indicates rate limiting. Use ?api_key=YOUR_API_KEY in public examples.

Missing data

A plain availability 404 means the requested currency, indicator, or selected series is not published. Use the coverage pages or /api/v1/data_catalogue/{currency} to check availability.

No rows in window

200 with data: [] and a no_data object (error_code=NO_DATA_IN_REQUESTED_WINDOW) means the series exists but the requested date range has no observations. Use latest_available_date or no_data.recommended_start_date, or broaden the date window. This is not an error and does not need a retry.

Client parsing: do not assume every row has every derived field. GDP may expose pct_change_qoq and pct_change_yoy; monthly inflation may expose val_mom; some level series have no meaningful change field.

AI Answer-Ready

Key Facts

Page
Announcement Endpoint
Section
Documentation
Canonical URL
https://fxmacrodata.com/documentation/announcement-endpoint
Source
FXMacroData editorial and official publisher references
Last Updated
See page metadata

Provenance And Trust

Cite the canonical URL and source field above. Where available, this page maps to official publisher releases and timestamped updates.

Quick Q&A

What is this page about? This page explains Announcement Endpoint with directly usable context for trading, research, and API workflows.

What source should be cited? Use the canonical URL and the listed source field; cite official publisher references when available.

How fresh is this content? The last updated value above reflects the page metadata or latest available data timestamp.

Can this be used in AI assistants? Yes. This section is intentionally structured for retrieval and citation in chat assistants.

Prompt Packs

Use these in ChatGPT, Claude, Gemini, Mistral, Perplexity, or Grok for consistent source-aware outputs.