By the end of this guide you will be able to query any macroeconomic indicator, discover
the full catalogue of available data, and check upcoming release dates — all through the
FXMacroData GraphQL endpoint — using nothing more than curl,
Python, or JavaScript. You will also know how to batch multiple queries into a single
round-trip so your scripts stay lean and fast.
Prerequisites
- • A FXMacroData API key — USD indicators and the data catalogue are free without a key; all other currencies require one. Get yours at fxmacrodata.com
- •
curl(or any HTTP client) for the initial test calls - • Python 3.9+ with the
requestslibrary (pip install requests) — for the Python examples - • Node.js 18+ — for the JavaScript examples
- • Basic familiarity with GraphQL query syntax (a field list inside curly braces)
Why GraphQL instead of REST?
The FXMacroData REST API serves each indicator at its own endpoint — one round-trip per currency/indicator combination. GraphQL lets you declare exactly the fields you need and combine multiple independent queries into a single HTTP request. If you want the EUR inflation series and the GBP policy rate and the upcoming release calendar for both currencies, that is one POST instead of four GET requests.
The GraphQL surface mirrors the public REST endpoints exactly: the same authentication
rules, the same data, and the same field names — just served through a single
POST /api/v1/graphql endpoint with a JSON body.
GraphQL endpoint at a glance
- URL:
https://fxmacrodata.com/api/v1/graphql - Method: POST
- Auth:
?api_key=YOUR_API_KEYquery parameter - Content-Type:
application/json - Free access: USD indicators and
dataCatalogue/calendar(no key required) - Query fields:
announcements,dataCatalogue,calendar
Step 1 — Send your first GraphQL query
Every GraphQL request is a JSON object with a query key whose value is your
GraphQL query string. Start with a free USD inflation query — no API key required:
curl -s -X POST "https://fxmacrodata.com/api/v1/graphql" \
-H "Content-Type: application/json" \
-d '{
"query": "{ announcements(currency: \"USD\", indicator: \"inflation\") { currency indicator data { date val pctChange } } }"
}'
The response is standard GraphQL JSON wrapped in a data envelope:
{
"data": {
"announcements": {
"currency": "USD",
"indicator": "inflation",
"data": [
{ "date": "2025-01-01", "val": 3.0, "pctChange": null },
{ "date": "2025-02-01", "val": 2.8, "pctChange": -6.67 },
{ "date": "2025-03-01", "val": 2.4, "pctChange": -14.29 }
]
}
}
}
For any non-USD currency, append your API key as a query parameter on the endpoint URL:
https://fxmacrodata.com/api/v1/graphql?api_key=YOUR_API_KEY
pctChange is the month-over-month (or period-over-period)
change relative to the previous data point. The first point in a series always returns
null because there is no prior value to compare against.
Step 2 — Discover available indicators with dataCatalogue
Before querying a specific indicator you can ask the API what data it has for any
currency. The dataCatalogue query returns every available indicator slug,
its human-readable name, unit, release frequency, and whether the central bank publishes
an official forecast for it.
curl -s -X POST "https://fxmacrodata.com/api/v1/graphql" \
-H "Content-Type: application/json" \
-d '{
"query": "{ dataCatalogue(currency: \"EUR\") { currency indicators { slug name unit frequency hasOfficialForecast } } }"
}'
Example response (abbreviated):
{
"data": {
"dataCatalogue": {
"currency": "EUR",
"indicators": [
{ "slug": "inflation", "name": "Inflation (CPI)", "unit": "%", "frequency": "monthly", "hasOfficialForecast": false },
{ "slug": "policy_rate", "name": "Policy Rate", "unit": "%", "frequency": "irregular", "hasOfficialForecast": true },
{ "slug": "gdp", "name": "GDP Growth", "unit": "%", "frequency": "quarterly", "hasOfficialForecast": false },
{ "slug": "unemployment", "name": "Unemployment", "unit": "%", "frequency": "monthly", "hasOfficialForecast": false }
]
}
}
}
The slug values are the exact strings you pass as the indicator
argument in subsequent announcements queries. You can browse the full indicator
catalogue interactively at the
API data docs.
Step 3 — Fetch historical data with optional date filters
The announcements query accepts optional startDate and
endDate arguments in YYYY-MM-DD format. Without them the API
returns a sensible default window (typically 12–24 months). You can also request the
central bank target alongside the series — useful when comparing the live reading against
the official rate target.
curl -s -X POST "https://fxmacrodata.com/api/v1/graphql?api_key=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "query { announcements(currency: \"AUD\", indicator: \"policy_rate\", startDate: \"2024-01-01\") { currency indicator hasOfficialForecast cbTarget { description current { effectiveFrom target } } data { date val announcementDatetime } } }"
}'
Response highlights:
{
"data": {
"announcements": {
"currency": "AUD",
"indicator": "policy_rate",
"hasOfficialForecast": true,
"cbTarget": {
"description": "RBA cash rate target band",
"current": { "effectiveFrom": "2023-11-07", "target": 4.35 }
},
"data": [
{ "date": "2024-02-06", "val": 4.35, "announcementDatetime": 1707199200 },
{ "date": "2024-03-19", "val": 4.35, "announcementDatetime": 1710813600 }
]
}
}
}
announcementDatetime is a Unix timestamp (seconds, UTC) of the official
publication. You can find field-level documentation for AUD indicators at the
AUD policy rate docs.
Step 4 — Query the release calendar
The calendar query returns the scheduled UTC announcement times for every
upcoming indicator release for a given currency. Pass an optional indicator
argument to narrow the results to a single indicator.
curl -s -X POST "https://fxmacrodata.com/api/v1/graphql?api_key=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "{ calendar(currency: \"GBP\", indicator: \"inflation\") { currency data { release announcementDatetime } } }"
}'
{
"data": {
"calendar": {
"currency": "GBP",
"data": [
{ "release": "inflation", "announcementDatetime": 1745917200 }
]
}
}
}
Convert announcementDatetime to a human-readable UTC time in Python with
datetime.utcfromtimestamp(1745917200), or in JavaScript with
new Date(1745917200 * 1000).toISOString().
For the GBP inflation indicator details see the
GBP inflation docs.
Step 5 — Batch multiple queries in one request
GraphQL's biggest practical advantage is the ability to name and send multiple independent
queries in a single HTTP POST. Use query aliases to avoid field name conflicts — each
alias becomes a separate key in the data response object.
curl -s -X POST "https://fxmacrodata.com/api/v1/graphql?api_key=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "query MultiIndicator { eurInflation: announcements(currency: \"EUR\", indicator: \"inflation\") { currency indicator data { date val } } gbpRate: announcements(currency: \"GBP\", indicator: \"policy_rate\") { currency indicator data { date val } } audCalendar: calendar(currency: \"AUD\") { currency data { release announcementDatetime } } }"
}'
The response carries all three results in one payload:
{
"data": {
"eurInflation": { "currency": "EUR", "indicator": "inflation", "data": [ ... ] },
"gbpRate": { "currency": "GBP", "indicator": "policy_rate", "data": [ ... ] },
"audCalendar": { "currency": "AUD", "data": [ ... ] }
}
}
Step 6 — Python client
The pattern below wraps GraphQL requests in a small helper so your application code stays readable. It supports single queries and batched alias queries with the same function.
import requests
GRAPHQL_URL = "https://fxmacrodata.com/api/v1/graphql"
API_KEY = "YOUR_API_KEY" # leave empty for free USD/catalogue endpoints
def gql(query: str) -> dict:
"""Send a GraphQL query and return the parsed `data` object."""
params = {"api_key": API_KEY} if API_KEY else {}
resp = requests.post(
GRAPHQL_URL,
params=params,
json={"query": query},
headers={"Content-Type": "application/json"},
timeout=15,
)
resp.raise_for_status()
payload = resp.json()
if "errors" in payload:
raise RuntimeError(f"GraphQL errors: {payload['errors']}")
return payload["data"]
# ── Discover indicators for AUD ──────────────────────────────────────────────
catalogue = gql('{ dataCatalogue(currency: "AUD") { indicators { slug name frequency } } }')
for ind in catalogue["dataCatalogue"]["indicators"]:
print(f" {ind['slug']:25s} {ind['name']} ({ind['frequency']})")
# ── Fetch EUR inflation + GBP policy rate in one round-trip ─────────────────
batch = gql('''
query {
eurInflation: announcements(currency: "EUR", indicator: "inflation") {
currency indicator data { date val pctChange }
}
gbpRate: announcements(currency: "GBP", indicator: "policy_rate") {
currency indicator data { date val }
}
}
''')
eur_latest = batch["eurInflation"]["data"][-1]
gbp_latest = batch["gbpRate"]["data"][-1]
print(f"EUR CPI {eur_latest['date']}: {eur_latest['val']}% ({eur_latest['pctChange']:+.2f}% MoM)")
print(f"GBP Rate {gbp_latest['date']}: {gbp_latest['val']}%")
Step 7 — JavaScript / Node.js client
The native fetch API (Node.js 18+) handles GraphQL requests with minimal
boilerplate. The pattern mirrors the Python helper above.
const GRAPHQL_URL = "https://fxmacrodata.com/api/v1/graphql";
const API_KEY = "YOUR_API_KEY"; // set to "" for free USD/catalogue endpoints
async function gql(query) {
const url = API_KEY ? `${GRAPHQL_URL}?api_key=${API_KEY}` : GRAPHQL_URL;
const resp = await fetch(url, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ query }),
});
if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
const payload = await resp.json();
if (payload.errors) throw new Error(JSON.stringify(payload.errors));
return payload.data;
}
// Batched query: EUR inflation + calendar
const data = await gql(`
query {
eurInflation: announcements(currency: "EUR", indicator: "inflation") {
data { date val pctChange }
}
eurCalendar: calendar(currency: "EUR", indicator: "inflation") {
data { release announcementDatetime }
}
}
`);
const latest = data.eurInflation.data.at(-1);
const nextRelease = data.eurCalendar.data[0];
console.log(`EUR CPI ${latest.date}: ${latest.val}% (${latest.pctChange > 0 ? "+" : ""}${latest.pctChange?.toFixed(2)}% MoM)`);
if (nextRelease) {
const dt = new Date(nextRelease.announcementDatetime * 1000).toISOString();
console.log(`Next EUR inflation release: ${dt}`);
}
Step 8 — Handle errors gracefully
GraphQL returns HTTP 200 even when a query field fails. Errors appear in a top-level
errors array alongside any partial data that did succeed. Check
for this array before using the response — a failed alias in a batched query will not
prevent the other aliases from returning data.
payload = resp.json()
# Partial success: some aliases may have data, others may have errors
if "errors" in payload:
for err in payload["errors"]:
print(f"[GraphQL error] {err.get('message')} — path: {err.get('path')}")
data = payload.get("data") or {}
if "eurInflation" in data and data["eurInflation"]:
process(data["eurInflation"])
- • Unsupported currency — the
errorsarray will contain a message like "Unsupported currency: XYZ". Check your currency code against the API docs. - • Invalid indicator — run a
dataCataloguequery first to confirm the indicator slug exists for your target currency. - • Authentication error — HTTP 401 or a GraphQL error citing an invalid key. Verify
api_keyis appended to the URL, not the JSON body.
What you accomplished
- ✓ Sent your first GraphQL query to
https://fxmacrodata.com/api/v1/graphql - ✓ Used
dataCatalogueto discover every available indicator for a currency - ✓ Fetched filtered historical data using
startDateandendDatearguments - ✓ Retrieved upcoming release timestamps with the
calendarquery - ✓ Batched multiple independent queries into a single HTTP POST using named aliases
- ✓ Built reusable GraphQL helper functions in both Python and JavaScript
- ✓ Handled partial errors without discarding valid data from other aliases
Next steps
Now that you can query the GraphQL endpoint fluently, a few natural extensions will make your integration production-ready:
-
Schedule queries around release times. Combine the
calendarquery with the scheduling pattern described in How to Use the Release Calendar API to Schedule Indicator Fetches — wake up just before each announcement and fire yourannouncementsquery the moment new data is published. -
Explore the full schema interactively. If you have access to a dev
environment with
ENABLE_GRAPHIQL=true, open/api/v1/graphqlin your browser to use the built-in GraphiQL IDE with autocomplete and inline documentation for every field. -
Extend your coverage to more currencies. Run
dataCataloguefor each of the supported currencies — USD, EUR, GBP, AUD, CAD, JPY, CHF, and NZD — to build a full picture of what data is available across the G8 FX universe.
— The FXMacroData Team