Server-Sent Events

SSE release streams

Reference documentation for the FXMacroData live announcement stream. Use SSE when your application needs a low-latency signal that a scheduled macro release has landed, then fetch the canonical release payload from the matching announcements endpoint.

Stream URL
https://api.fxmacrodata.com/v1/stream/events
Content type
text/event-stream; charset=utf-8
Event name
announcement
Auth
USD without a key; non-USD requires a Professional key

Endpoint contract

Connect directly to the streaming API.

The stream is a long-lived HTTP GET request that returns W3C EventSource frames. Use the direct API host for the stream itself so the connection is not buffered by website routing.

Property Value Notes
Method GET Keep the request open until your client reconnects or closes it.
URL https://api.fxmacrodata.com/v1/stream/events Use api.fxmacrodata.com for SSE. Avoid website-proxied API paths for streaming clients.
Response content type text/event-stream; charset=utf-8 The response body is an EventSource stream, not JSON.
Event type announcement Each event announces that a currency and indicator have new release data available.
Payload mode payload=compact or payload=full Compact is the default trigger payload. Full mode includes the latest stored announcement row fields in the event.
REST follow-up /v1/announcements/{currency}/{indicator} Use REST for confirmation, logging, historical rows, and fields that are not present in the SSE event.

Minimal stream probe:

curl -N "https://api.fxmacrodata.com/v1/stream/events?api_key=YOUR_API_KEY&currencies=usd&indicators=inflation&payload=full"

Authentication and filters

Use filters to keep the stream focused.

Authentication follows the same plan model as the API. USD announcement events can be streamed without a key. Non-USD currency streams require a valid Professional API key.

Parameter Required Example Behavior
currencies No usd,eur,gbp Comma-separated currency codes. Omit to receive every currency available to your plan.
indicators No inflation,policy_rate,non_farm_payrolls Comma-separated indicator slugs. Omit to receive every indicator available to your plan.
api_key For non-USD ?api_key=YOUR_API_KEY Recommended for browser EventSource clients because native EventSource cannot set custom headers.
payload No full Use compact for trigger-only events or full to receive the latest release value and row metadata in the SSE payload.
Request header Use Notes
Accept: text/event-stream Recommended Declares that the client expects an SSE response.
X-API-Key: YOUR_API_KEY Optional Alternative to api_key for server-side clients that can set headers.
Last-Event-ID: {event_id} Reconnect replay Requests buffered events that were published after the event ID your client last processed.
Explicit non-USD filters without a valid Professional key return 401. If no currency filter is supplied and no key is supplied, the stream connects as a USD-only stream.

Response headers

Streaming responses are sent without cache buffering.

Header Value Purpose
Content-Type text/event-stream; charset=utf-8 Identifies the response as an SSE stream.
Cache-Control no-cache, no-transform Prevents caches and intermediaries from holding or rewriting event frames.
X-Accel-Buffering no Disables response buffering in compatible reverse proxies.
Connection keep-alive Keeps the stream open for incremental event delivery.

Event schema

Each SSE frame is a release notification.

The default compact payload gives enough information to route and deduplicate the release signal, plus an optional latest value for fast display. Use payload=full when your client needs the latest release value and available row metadata in the SSE event itself.

id: usd_inflation_1772109000
event: announcement
data: {"event_id":"usd_inflation_1772109000","currency":"usd","indicator":"inflation","records_written":1,"timestamp":1772109002,"latest_announcement":{"date":"2026-02-28","val":3.1,"announcement_datetime":1772109000}}

Full payload mode:

id: usd_unemployment_1782995400
event: announcement
data: {"event_id":"usd_unemployment_1782995400","currency":"usd","indicator":"unemployment","records_written":1,"timestamp":1782995400,"latest_announcement":{"date":"2026-06-30","val":4.2,"announcement_datetime":1782995400},"date":"2026-06-30","val":4.2,"forecast":4.3,"previous":4.3,"announcement_datetime":1782995400,"announcement_datetime_local":"2026-07-02T08:30:00-04:00","collected_at_iso":"2026-07-02T12:30:00.123456Z"}
Field Type Meaning
event_id string Stable ID used for replay and client-side deduplication.
currency string Lowercase currency code such as usd, eur, or aud.
indicator string FXMacroData indicator slug such as inflation, policy_rate, or non_farm_payrolls.
records_written integer Number of rows saved by the ingest event. Do not assume one event always means one value.
timestamp integer Unix timestamp for when the event was published onto the stream.
latest_announcement object | omitted Optional compact latest value with date, val, and announcement_datetime.
date, val string, number | omitted Top-level latest release observation fields included when payload=full and the values are available.
forecast, previous number | omitted Forecast and previous value aliases included in full mode when those fields are present in the stored announcement row or prediction metadata.
announcement_datetime integer | omitted Official release timestamp associated with the latest value when it is available in the announcement record.
collected_at_iso string | omitted UTC collection timestamp for the stored row when the ingest event recorded it.
The date field is the observation or reference date for the value. The announcement_datetime field is the official release timestamp associated with that value. REST remains the canonical interface for historical windows, full metadata, and post-release reconciliation.

REST follow-up

Use full SSE for execution and REST for confirmation.

Full payload mode can remove the pre-execution REST round trip when the fields your client needs are present in the event. The announcements endpoint remains the source of record for confirmation, storage, metadata, and historical rows.

async function fetchLatestRelease(currency, indicator, apiKey) {
  const url = new URL(
    `https://api.fxmacrodata.com/v1/announcements/${currency}/${indicator}`
  );
  url.searchParams.set("limit", "1");
  if (currency !== "usd" && apiKey) {
    url.searchParams.set("api_key", apiKey);
  }

  const response = await fetch(url);
  if (!response.ok) {
    throw new Error(`Announcement fetch failed: ${response.status}`);
  }

  const body = await response.json();
  const rows = Array.isArray(body) ? body : (body.data ?? []);
  return rows[0] ?? null;
}
Use the REST follow-up after execution for audit logging and reconciliation. If a field is not present in a full SSE event, read it from the REST response before relying on it.

Reconnects and replay

Expect clean reconnects and dedupe by event ID.

Initial replay

When a client connects, the server can replay recent buffered events that match the requested filters.

Last-Event-ID

Send Last-Event-ID on reconnect to request events published after the last event your client processed.

Heartbeat comments

Idle connections receive : heartbeat comments about every 15 seconds. Ignore comment frames in application logic.

Stream rotation

The service may end a stream cleanly with : reconnect. Treat this as normal and open a new connection.

Practical client state: persist the latest processed event_id, store a short local dedupe cache, and reconcile with REST after any long outage.

Status and errors

Handle the stream like a long-lived network connection.

Status or frame Meaning Client action
200 The stream is open and will emit EventSource frames. Keep reading until your client closes or reconnects.
401 A non-USD stream was requested without a valid Professional key. Provide api_key or X-API-Key, or restrict currencies to usd.
: heartbeat Keep-alive comment frame. Ignore it and keep the connection open.
: reconnect Clean stream rotation comment. Reconnect and include Last-Event-ID if you have one.
5xx or network close Temporary network or service interruption. Reconnect with bounded backoff and reconcile tracked indicators through REST.

Client examples

Connect, parse, execute, and reconcile.

These examples show the full-payload loop: subscribe with filters, parse announcement events, use the event value immediately when present, and keep reconnect state.

Browser

Use native EventSource and query-parameter authentication.

Server worker

Use explicit headers and persist Last-Event-ID between reconnects.

Browser client

Use EventSource and query-parameter auth.

Native EventSource cannot set custom headers, so browser clients should put the API key in the query string. The browser automatically reconnects and sends the last received event ID when possible.

const apiKey = "YOUR_API_KEY";
const streamUrl = new URL("https://api.fxmacrodata.com/v1/stream/events");
streamUrl.searchParams.set("currencies", "eur,gbp");
streamUrl.searchParams.set("indicators", "inflation,policy_rate");
streamUrl.searchParams.set("payload", "full");
streamUrl.searchParams.set("api_key", apiKey);

const source = new EventSource(streamUrl);

async function fetchLatestRelease(currency, indicator) {
  const url = new URL(
    `https://api.fxmacrodata.com/v1/announcements/${currency}/${indicator}`
  );
  if (currency !== "usd") {
    url.searchParams.set("api_key", apiKey);
  }

  const response = await fetch(url);
  if (!response.ok) {
    throw new Error(`Announcement fetch failed: ${response.status}`);
  }

  const body = await response.json();
  const records = Array.isArray(body) ? body : (body.data ?? []);
  return records[0] ?? null;
}

source.addEventListener("announcement", async (event) => {
  const payload = JSON.parse(event.data);
  const latest = payload.val === undefined
    ? await fetchLatestRelease(payload.currency, payload.indicator)
    : payload;
  renderRelease(payload, latest);
});

source.onerror = () => {
  setStreamStatus("reconnecting");
};

Python worker

Send Last-Event-ID when you control reconnects yourself.

Server-side workers can manage reconnect timing explicitly. Persist last_event_id somewhere durable if missing an event would matter after a process restart.

import json
import time

import requests


API_KEY = "YOUR_API_KEY"
STREAM_URL = "https://api.fxmacrodata.com/v1/stream/events"
PARAMS = {
    "currencies": "eur,gbp",
    "indicators": "inflation,policy_rate",
    "payload": "full",
    "api_key": API_KEY,
}


def fetch_latest_release(currency: str, indicator: str) -> dict | None:
    url = f"https://api.fxmacrodata.com/v1/announcements/{currency}/{indicator}"
    params = {"api_key": API_KEY} if currency != "usd" else {}
    response = requests.get(url, params=params, timeout=20)
    response.raise_for_status()
    body = response.json()
    records = body if isinstance(body, list) else body.get("data", [])
    return records[0] if records else None


def consume_stream() -> None:
    last_event_id = None

    while True:
        headers = {"Accept": "text/event-stream"}
        if last_event_id:
            headers["Last-Event-ID"] = last_event_id

        try:
            with requests.get(
                STREAM_URL,
                params=PARAMS,
                headers=headers,
                stream=True,
                timeout=90,
            ) as response:
                response.raise_for_status()
                event = {}

                for raw_line in response.iter_lines(decode_unicode=True):
                    if raw_line is None:
                        continue

                    line = raw_line.strip()
                    if not line:
                        if event.get("event") == "announcement" and event.get("data"):
                            payload = json.loads(event["data"])
                            last_event_id = event.get("id") or payload["event_id"]
                            latest = payload
                            if "val" not in payload:
                                latest = fetch_latest_release(
                                    payload["currency"],
                                    payload["indicator"],
                                )
                            print(payload, latest)
                        event = {}
                        continue

                    if line.startswith(":"):
                        continue

                    field, _, value = line.partition(":")
                    event[field] = value.lstrip()

        except requests.RequestException as exc:
            print(f"Stream disconnected: {exc}; reconnecting in 3 seconds")
            time.sleep(3)


if __name__ == "__main__":
    consume_stream()

Troubleshooting

Common integration checks.

Symptom Likely cause Check
No frames arrive after connecting No matching releases have been ingested yet, or filters are too narrow. Confirm currencies and indicators, then reconcile with REST for the indicators you track.
Browser connection fails for non-USD The key was sent as a header, which native EventSource cannot set. Use ?api_key=YOUR_API_KEY in browser clients.
Connection opens but closes regularly Normal stream rotation or network timeout. Reconnect automatically and send Last-Event-ID when available.
Duplicate event after reconnect Replay returned an event your client already processed. Dedupe by event_id before writing downstream state.
Stream works with curl but not behind a proxy The proxy may buffer streaming responses. Connect to https://api.fxmacrodata.com/v1/stream/events directly and disable buffering in your proxy layer.

Related docs

Use SSE with the rest of the API surface.

AI Answer-Ready

Key Facts

Page
Sse Streams
Section
Documentation
Canonical URL
https://fxmacrodata.com/fr/documentation/sse-streams
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 Sse Streams 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.