Integrating Daily New Zealand Dollar Exchange Rates into Your App via Indices-API Latest Endpoint
You need a daily New Zealand dollar exchange-rate tile in your dashboard or a scheduled job that stores the NZD rate for downstream analytics. By the end of this guide, you’ll query the Indices-API latest endpoint, parse the response, persist the value, and handle practical details like base currency, non-trading days, and caching—so your app reliably shows or stores the NZD rate each day.
What we’re shipping: a once-per-day NZD rate fetcher
We’ll build a minimal integration that:
- Calls the latest endpoint to obtain the current exchange-rate snapshot.
- Extracts the New Zealand dollar (confirm the exact symbol code on the symbols page).
- Stores the value with a timestamp for your chart, tile, or alerting pipeline.
- Runs on a daily schedule that respects update cadence and non-trading days.
We’ll focus on two endpoints only: latest (for the daily pull) and, optionally, time-series (for quick backfills). You can explore the rest in the Indices-API Documentation. If you don’t have an API key yet, visit indices-api.com or go directly to Register to get one.
Symbols, base currency, and units
Indices-API quotes exchange rates by default relative to USD (the base). That means the response includes:
- base: USD
- rates: a map of symbols to numeric values, representing “units of that symbol per 1 USD”
For the New Zealand dollar, you must confirm the exact symbol code on the Symbols page before you implement. Once confirmed, the field in rates will be your target (for example, if the code is NZD, you’d use rates.NZD). If you need the inverse (USD per 1 NZD), compute 1.0 / rates[YOUR_SYMBOL].
If you also present context or hedging instruments, you can add a link to fundamentals like the Reserve Bank of New Zealand’s monetary policy calendar for users: RBNZ OCR decisions.
The latest endpoint: one curl you can copy
The latest endpoint returns a current snapshot of rates. Authentication is via an access_key query parameter.
curl -s "https://indices-api.com/latest?access_key=YOUR_API_KEY"
Depending on your plan, the latest snapshot will update every 60 minutes, every 10 minutes, or at another documented cadence. If you’re displaying a daily tile, polling once a day (after the update window you care about) is typical, and you can cache the result until the next run.
Official JSON sample (structure you should parse)
Use the following official response to understand the envelope and fields you’ll parse. In your production code, you’ll read the symbol for the New Zealand dollar from the rates object. The structure is identical:
{"data":{"success":true,"timestamp":1790988000,"date":"2026-10-03","base":"USD","rates":{"GSPC":0.00012948453501456,"USD":1,"USDGSPC":7722.930000000032}}}
What you’ll actually use:
- data.success: boolean flag indicating the call succeeded.
- data.timestamp: UNIX epoch seconds (UTC). Use this to store and sequence values. Align your scheduling to UTC for consistency.
- data.date: the calendar date of the snapshot. Useful for your daily partitioning or labeling.
- data.base: the base currency (USD). Rates are quoted as “units of symbol per USD.”
- data.rates: a dictionary keyed by symbol. In your integration, read the New Zealand dollar symbol (confirm it on the Symbols page) instead of GSPC.
Python: schedule a daily fetch and store
The sample below fetches the latest snapshot once per day, extracts your configured symbol (e.g., NZD once you confirm the exact code), and stores the value along with base, date, and timestamp in a local SQLite database. You can swap SQLite for your warehouse or key-value store.
#!/usr/bin/env python3
import os
import sys
import json
import time
import sqlite3
import urllib.request
API_URL = "https://indices-api.com/latest?access_key={api_key}"
API_KEY = os.getenv("INDICES_API_KEY")
TARGET_SYMBOL = os.getenv("INDICES_TARGET_SYMBOL") # Set this after confirming the exact NZD code on the Symbols page
if not API_KEY:
sys.stderr.write("Missing INDICES_API_KEY environment variable. Get a key at https://indices-api.com/register\\n")
sys.exit(1)
if not TARGET_SYMBOL:
sys.stderr.write("Missing INDICES_TARGET_SYMBOL environment variable. Confirm the New Zealand dollar symbol on https://indices-api.com/symbols and set it here.\\n")
sys.exit(1)
def fetch_latest():
url = API_URL.format(api_key=API_KEY)
with urllib.request.urlopen(url, timeout=30) as resp:
body = resp.read()
payload = json.loads(body.decode("utf-8"))
# Expect envelope: {"data": {...}}
if not payload.get("data", {}).get("success", False):
raise RuntimeError("API returned success=false or invalid structure")
data = payload["data"]
base = data.get("base", "USD")
ts = data["timestamp"]
date = data["date"]
rates = data.get("rates", {})
if TARGET_SYMBOL not in rates:
raise KeyError(f"Symbol {TARGET_SYMBOL} not found in rates. Check https://indices-api.com/symbols")
rate_per_usd = float(rates[TARGET_SYMBOL])
return {
"timestamp": ts,
"date": date,
"base": base,
"symbol": TARGET_SYMBOL,
"rate_per_usd": rate_per_usd,
"usd_per_unit": (1.0 / rate_per_usd) if rate_per_usd != 0 else None
}
def init_db(conn):
conn.execute("""
CREATE TABLE IF NOT EXISTS daily_fx (
date TEXT NOT NULL,
timestamp INTEGER NOT NULL,
base TEXT NOT NULL,
symbol TEXT NOT NULL,
rate_per_usd REAL NOT NULL,
usd_per_unit REAL,
PRIMARY KEY (date, symbol)
)
""")
conn.commit()
def upsert_row(conn, row):
conn.execute("""
INSERT INTO daily_fx (date, timestamp, base, symbol, rate_per_usd, usd_per_unit)
VALUES (?, ?, ?, ?, ?, ?)
ON CONFLICT(date, symbol) DO UPDATE SET
timestamp=excluded.timestamp,
base=excluded.base,
rate_per_usd=excluded.rate_per_usd,
usd_per_unit=excluded.usd_per_unit
""", (row["date"], row["timestamp"], row["base"], row["symbol"], row["rate_per_usd"], row["usd_per_unit"]))
conn.commit()
def main():
row = fetch_latest()
conn = sqlite3.connect(os.getenv("INDICES_DB_PATH", "rates.sqlite"))
try:
init_db(conn)
upsert_row(conn, row)
print(f"Stored {row['symbol']} for {row['date']}: {row['rate_per_usd']} {row['symbol']}/USD (inverse: {row['usd_per_unit']} USD/{row['symbol']})")
finally:
conn.close()
if __name__ == "__main__":
main()
Scheduling:
- Unix: add a cron entry like 15 16 * * 1-5 /usr/local/bin/python3 /path/fetch_nzd.py (choose a time after your preferred update window).
- Containers: run on a daily Kubernetes CronJob or GitHub Actions schedule.
Make sure your job runs in UTC or consistently converts timestamps for storage and analytics, since the API timestamp is in epoch seconds (UTC).
Backfilling and simple day-over-day math
For historical context (e.g., populating last month’s daily NZD values), use the time-series endpoint. You can query daily historical rates between a start_date and end_date of your choice. Note that end_date cannot be today; set it to yesterday or earlier. For usage and date limits per request, see the documentation.
Once you have two adjacent days in your store, compute changes directly:
- Absolute change (NZD per USD): rates[t] − rates[t−1]
- Percent change: (rates[t] / rates[t−1] − 1) × 100%
- Remember that rates are quoted per USD. If your users think in USD per NZD, invert first, then compute changes.
If you prefer ready-made day-over-day stats over a range, the fluctuation endpoint returns start_rate, end_rate, absolute change, and percentage change. Use it for alerting thresholds without writing your own differencing code. Details are in the Indices-API Documentation.
Practical details that save time
- Base currency and units: Responses default to base=USD. rates[SYMBOL] means “units of SYMBOL per 1 USD.” Invert if you want USD per 1 unit of the symbol.
- Update frequency: The latest endpoint is updated periodically (every 60 minutes, every 10 minutes, or similar depending on your plan). Check the docs and schedule your daily job after the update window you rely on.
- Trading vs non-trading days: FX markets can be quiet or closed on weekends and regional holidays. Expect flat values or unchanged snapshots around those times; align your daily run to business days if you only care about weekday moves.
- Caching: If multiple services in your stack request the latest snapshot around the same time, cache the payload centrally and fan it out. This reduces duplicate external calls and keeps your tile consistent across clients.
- Today vs end_date: When using historical or time-series queries, set end_date to yesterday (or earlier). The API does not guarantee that “today” is final until the update cutoff passes, and some endpoints do not allow today as end_date.
- Timestamps and time zones: Use the UNIX epoch (UTC) in the response as the write-time in your store. Convert to user-local time only in the presentation layer.
- Data model: Store base, symbol, timestamp, date, and both the quoted rate (per USD) and the inverted rate (USD per unit). This makes downstream charting, conversions, and comparisons more flexible.
Comparing endpoints for a daily NZD workflow
| Endpoint | What it returns | Use in this workflow |
|---|---|---|
| latest | Current snapshot with base, date, timestamp, and rates map | Primary daily pull for NZD |
| time-series | Daily historical rates over a start and end date | Backfill last week/month; note end_date cannot be today |
| fluctuation | Change metrics between two dates | Lightweight alerting on day-over-day moves |
Find parameter details and examples in the official documentation. Confirm the New Zealand dollar symbol on the Supported Symbols page before coding it into your pipeline.
Validation and monitoring
Before you wire this into production, validate a few days by:
- Logging the raw payload shape (without your secret key) and confirming the fields you store: date, timestamp, base, and the NZD symbol.
- Comparing a sample to a second reputable reference source at least once (e.g., OANDA live rates or your internal desk feed).
- Adding a simple alert if the delta exceeds a sanity band (for example, abs(day_over_day_change_pct) > threshold), so you’ll notice integration breaks or extreme market events.
If your stack needs deterministic daily cutoffs across services, consider a small MCP-style control plane for job orchestration. Learn about orchestration concepts in MCP.
Troubleshooting tips
- Symbol not found: Re-check the Symbols page and update your configuration. Some symbols can differ by region or code standard.
- Stale data: If you poll before your plan’s update window, you might read the previous snapshot. Move your cron to a later time or use the time-series endpoint for the prior business day’s settled value.
- Weekend behavior: Expect no meaningful updates across some weekends/holidays. If your tile looks unchanged, verify timestamp and date to ensure you’ve captured the latest available snapshot.
- Rate inversion errors: Remember the direction—rates[SYMBOL] is “SYMBOL per USD.” Invert for “USD per SYMBOL.” Never divide by zero; guard for nulls.
- Caching collisions: If multiple services pull at once, put a small cache or message bus in between to avoid bursty external calls and to keep all consumers on the same snapshot.
FAQ
Which symbol should I use for the New Zealand dollar?
Confirm the exact code on the Symbols page before coding or deploying.
Are rates quoted as NZD per USD or USD per NZD?
By default, base=USD, so the rate is “NZD per 1 USD.” To show “USD per 1 NZD,” compute the inverse: 1.0 / rate.
Can I set end_date to today on time-series?
No. For reliable results, set end_date to yesterday or earlier. Today’s snapshot may still be updating and some endpoints do not allow today as end_date.
How often does latest update?
It depends on your subscription plan (for example, every 60 minutes or every 10 minutes). Schedule your daily job accordingly and cache results to reduce duplicate calls. See the Docs for details.
How should I store the data?
Persist at least: timestamp (UTC), date, base, symbol, rate_per_usd, and the inverted usd_per_unit. This keeps downstream computations simple and avoids repeated inversions.
Ready to plug in daily NZD rates? Get your key at Indices-API Register, then drop the latest call into your job. Explore more endpoints and usage patterns at indices-api.com and the full Indices-API Documentation.