Integrating Daily New Zealand Dollar Updates into Your App via Indices-API Latest Endpoint
You need a daily New Zealand Dollar (NZD) tile in your app and a simple job that writes the latest NZD value to your datastore before users log in. By the end of this guide, you’ll call the Indices-API /latest endpoint, read the NZD value out of the JSON, store it once per trading day, and know how to handle weekends, caching, and update cadence.
The job: a daily NZD update for dashboards and alerts
Many dashboards show a compact “NZD today” tile or trigger lightweight FX alerts. The smallest useful integration is a once-daily fetch from the Indices-API latest endpoint, extracting the NZD rate and persisting it alongside a timestamp. You can then render it on load, compare to yesterday, and send a push notification if the move exceeds your threshold.
This article focuses on the two endpoints you actually need for this workflow:
- Latest endpoint for today’s NZD value
- Time-series endpoint for backfilling the last N days (optional but recommended)
The Indices-API returns exchange rates with a base currency of USD by default. That means the NZD number you read is “units of NZD per 1 USD.” We’ll cover how to interpret that precisely and how to cache it for efficient delivery to your users.
If you don’t already have an API key, you can create one in minutes. Visit the Indices-API Website and click Get Started to obtain a free API key.
Confirm the NZD symbol and plan your daily run time
Before coding, confirm the exact symbol code for New Zealand Dollar on the symbols page. While “NZD” is the standard ISO code, you should always verify the symbol used by the API you integrate.
- Check the symbol: see the full catalog on Indices-API Supported Symbols. Use the symbol listed there in your requests.
- Pick a schedule: For a daily update, run shortly after your users’ morning peak or your data warehouse’s ingest window. For example, schedule a job at 06:30 UTC. If your app is New Zealand–focused, also consider local-time windows and that FX markets don’t trade on weekends.
Note on FX timing: FX markets are generally active Sunday evening (UTC) through Friday evening (UTC). Over weekends, the latest endpoint will still return the most recent available value and timestamp. Build your UI copy to reflect “Last updated” rather than implying fresh weekend ticks.
Call the latest endpoint for NZD
The latest endpoint returns recent exchange rates in JSON, updated at a cadence determined by your plan (for example, every 60 minutes or every 10 minutes). Authentication is via an access_key query parameter.
Complete curl example
The following curl retrieves the latest rates. We’ll then read NZD from the response’s rates object. Replace YOUR_API_KEY with your actual key:
curl -s "https://indices-api.com/latest?access_key=YOUR_API_KEY"
Illustrative JSON response (fields and structure are representative; values shown are examples only):
{
"success": true,
"timestamp": 1790556084,
"base": "USD",
"date": "2026-09-28",
"rates": {
"NZD": 1.6521
},
"unit": "per index"
}
How to read the fields you’ll actually use:
- success: boolean indicating a successful request.
- timestamp: Unix epoch seconds for data freshness checks and caches.
- base: the base currency of the rates. By default this API returns values relative to USD.
- date: the date associated with this snapshot (useful if you store end-of-day values).
- rates.NZD: the rate quoted as “NZD per 1 USD.” In the example, 1 USD = 1.6521 NZD.
If you need to confirm symbol availability or discover additional symbols, browse the Indices-API Supported Symbols. For request and response reference, see the Indices-API Documentation.
Store one value per trading day with a small script
Below is a compact Python job that fetches the NZD rate once per trading day and writes it to a JSONL file. In production you would likely upsert to your database with a primary key of (date, base, symbol) and attach the source timestamp for lineage.
#!/usr/bin/env python3
import os
import json
import time
import urllib.request
import urllib.error
from datetime import datetime, timezone
API_KEY = os.environ.get("INDICES_API_KEY", "YOUR_API_KEY")
URL = f"https://indices-api.com/latest?access_key={API_KEY}"
SYMBOL = "NZD" # Confirm this on the Symbols page before deploying.
def fetch_latest():
req = urllib.request.Request(URL, headers={"User-Agent": "nzd-daily/1.0"})
with urllib.request.urlopen(req, timeout=20) as resp:
return json.loads(resp.read().decode("utf-8"))
def extract_nzd(payload):
if not payload.get("success"):
raise ValueError("API returned success=false")
base = payload.get("base")
date = payload.get("date")
ts = payload.get("timestamp")
rates = payload.get("rates", {})
if SYMBOL not in rates:
raise KeyError(f"{SYMBOL} not present in rates. Confirm symbol on /symbols.")
nzd_rate = rates[SYMBOL]
return {
"base": base, # typically "USD"
"symbol": SYMBOL, # "NZD"
"date": date, # e.g., "2026-09-28"
"timestamp": ts, # epoch seconds
"rate": nzd_rate # NZD per 1 USD
}
def should_store_today(record, storage_path):
# Idempotence guard: ensure we don't duplicate storage for the same date.
if not os.path.exists(storage_path):
return True
today = record["date"]
# Check last line of the file quickly.
try:
with open(storage_path, "rb") as f:
f.seek(0, os.SEEK_END)
size = f.tell()
block = 4096
data = b""
while size > 0 and data.count(b"\n") < 2:
step = min(block, size)
size -= step
f.seek(size)
data = f.read(step) + data
last_line = data.strip().split(b"\n")[-1]
last = json.loads(last_line.decode("utf-8"))
return last.get("date") != today
except Exception:
# If parsing fails, be conservative and allow write.
return True
def main():
storage_path = "nzd_daily.jsonl"
try:
payload = fetch_latest()
record = extract_nzd(payload)
# Weekend logic: FX may be stale on weekends. This still writes once per new API date.
if should_store_today(record, storage_path):
with open(storage_path, "a", encoding="utf-8") as f:
f.write(json.dumps(record, separators=(",", ":")) + "\n")
print(f"Wrote NZD daily record for {record['date']}: {record['rate']} (base={record['base']})")
else:
print(f"Already stored NZD for {record['date']}; skipping.")
except urllib.error.HTTPError as e:
print(f"HTTP error: {e.code} {e.reason}")
raise
except Exception as e:
print(f"Error: {e}")
raise
if __name__ == "__main__":
# Run this as a cron job once per day. Example (UTC 06:30):
# 30 6 * * 1-5 /usr/bin/env bash -lc "/path/to/script.py >> /var/log/nzd-daily.log 2>&1"
# Adjust days if you prefer 7-day runs; the script's idempotence guard avoids duplicates.
main()
Scheduling notes:
- Run once per day on business days. FX markets do not trade on Saturdays and most of Sunday (UTC). If you schedule daily including weekends, you’ll still store at most one new record when the API
dateadvances. - Idempotence matters. Use the
dateortimestampin the payload to avoid duplicates in your store. - Cron is sufficient for once daily. If you’re on container orchestration, use a scheduled job (e.g., Kubernetes CronJob) with retries and alerting.
Understanding base currency, direction, and units
The API’s base is “USD” by default, so the value you read at rates.NZD is quoted as NZD per 1 USD. For example, if rates.NZD = 1.65, that means 1 USD equals 1.65 NZD.
- If your UI wants “USD per 1 NZD” (i.e., NZD as base), invert it on the client:
usd_per_nzd = 1.0 / rates.NZD. Label carefully. - When comparing daily changes, compare the same direction. Inversion flips the sign of percentage changes only if you mishandle the base direction; keep it consistent across fetches.
The response includes a timestamp and date. Treat timestamp as authoritative for freshness (e.g., to expire caches) and display date for your end-of-day label or daily partitioning. In weekend scenarios, date will not move until the next active session.
Backfill last week with the time-series endpoint
If you’re adding the NZD tile today, you’ll likely want a small chart or at least a day-over-day delta. Use the time-series endpoint to fetch a date range, then persist one point per returned day. Remember that your end_date should not be “today,” because some data providers publish latest values slightly delayed. Use yesterday or the last completed trading day.
Request and parameter details vary by plan; see the Indices-API Documentation for the exact query string format, date rules, and pagination if applicable. After fetching the range, read the same fields you used from /latest: base, rates, and per-day objects keyed by date.
Illustrative time-series response structure (values are examples only):
{
"success": true,
"timeseries": true,
"start_date": "2026-09-21",
"end_date": "2026-09-27",
"base": "USD",
"rates": {
"2026-09-21": { "NZD": 1.6532 },
"2026-09-23": { "NZD": 1.6490 },
"2026-09-27": { "NZD": 1.6521 }
},
"unit": "per index"
}
Practical tips:
- Gaps in dates are normal across weekends. Do not assume every calendar date exists; iterate over keys returned.
- Sort by date as strings in ISO format or parse to date objects and sort; then compute percentage change using consistent base direction.
- Cache the backfill. Use a long TTL for historical data since it does not change.
Caching, freshness, and update frequency
To serve NZD tiles and alerts efficiently, consider a two-tier cache:
- Short TTL cache (e.g., 10–15 minutes) for /latest: The API’s update cadence depends on your plan (for example, every 60 minutes or every 10 minutes). There’s no benefit to hammering the endpoint more frequently than it updates. Cache keyed by symbol and base.
- Long TTL cache (e.g., 30 days or “forever”) for historical/time-series: These values do not change after publication. Invalidate only on ingestion errors.
For UIs that hard-refresh on each visit, back your page with a thin service that answers from your cache or datastore and includes metadata:
- last_updated_at: from
timestamp, converted to your preferred timezone - as_of_date: from
date, the data date (can differ from “now” around market cutoffs)
Important guardrails:
- Do not set
end_dateto “today.” Use the last completed trading day to avoid partial-day or unavailable data. - On weekends and holidays, expect the latest response to reflect the last available business day.
- Always check
successand handle missing symbols gracefully by consulting the symbol directory.
Interpreting NZD in your product
Because the default base is USD, the NZD value returned tells you “how many NZD one USD buys.” A few examples of how teams usually apply this:
- Tile with percent change: Compare today’s
rates.NZDto the previous day’s. If you require “NZD as base,” invert both values first, then compute percentage change. - Alerts: Set thresholds in the same direction you display. If you invert for display, set your alerts on the inverted series too, so users see matching behavior.
- Checkout pricing: If you price in USD but collect in NZD, you can compute estimated converted amounts for pre-checkout displays. For full conversion workflows and precise rounding, review the conversion endpoint in the API docs.
For background on NZD market context and session overlaps, resources like the Reserve Bank of New Zealand’s data and publications can help you explain moves to users: Reserve Bank of New Zealand. For basic FX concepts, see Investopedia: New Zealand Dollar (NZD).
Troubleshooting and hardening
Make your job resilient with these checks:
- HTTP layer: Retry on transient 5xx, back off on rate-limit responses (if any), and log raw responses where permitted.
- Schema validation: Ensure
successis true; ensurebaseis “USD” (or your expected base); ensurerateshas the NZD key. - Idempotence: Write at most one record per
date. If your store is time-partitioned (e.g., daily tables), use upserts to prevent duplicates. - Clock drift: Favor the API’s
timestampanddateover your server’s clock when labeling data. Convert the epoch to your UI’s timezone only for display.
Security and deployment notes
- Store your
access_keyin environment variables or your secret manager. Avoid committing it to code or logs. - If deploying serverless, ensure your function’s cold start plus network SLAs still allow you to run within your schedule window with a retry budget.
- Log payload digests, not full bodies, if your compliance policies restrict PII or secrets in logs. Exchange-rate payloads are generally safe but treat keys as secrets.
When you need more than /latest
Once the daily tile is in place, the next common extensions are:
- Backfilling with the time-series endpoint for a 7–30 day sparkline.
- Day-over-day deltas using either time-series or a daily snapshot table built from /latest.
- Converting amounts via the conversion endpoint for pricing previews (see the documentation for usage).
To explore these and other capabilities, start at the Indices-API Documentation and verify symbols on the Supported Symbols directory. If you’re new to the platform, visit the main website to get your free API key and review plan options.
FAQ
Q: What’s the base currency for NZD in the /latest response?
A: By default the API returns rates relative to USD. Read rates.NZD as “NZD per 1 USD.” If you need USD per NZD, invert it client-side.
Q: Can I query the /latest endpoint on weekends?
A: Yes, but the response will reflect the most recent available snapshot. FX markets don’t update during most weekend hours, so date and timestamp may not advance until the next session. Build your UI to show “Last updated” and avoid implying fresh ticks on Saturdays.
Q: Why shouldn’t I use today as the end_date for time-series backfills?
A: Endpoints often publish the final “today” value after the day is complete or on a slight delay. Use the last completed trading day to avoid partial-day gaps or unexpected nulls.
Q: How often is the latest endpoint refreshed?
A: Update cadence depends on your plan (for example, every 60 minutes or every 10 minutes). Cache your result with a TTL aligned to your plan so you don’t over-fetch between updates.
Q: How do I confirm the correct NZD symbol?
A: Check the Supported Symbols page. While “NZD” is standard, always confirm the canonical code used by the API before deploying.
Ready to ship your daily NZD tile? Grab a free API key on the Indices-API Website, read the documentation, and wire the /latest endpoint into your job runner. You can be live in under an hour.