The Easiest Way to Get Angolan Kwanza (AOA) - N/A Historical Rates: using a REST API endpoint
You need a reliable way to pull Angolan Kwanza (AOA) historical rates into your product—so you can backfill charts, build a pricing history table, or run currency exposure analysis. By the end of this guide, you’ll have a repeatable process that queries AOA historical data via a REST API, inspects the JSON payload, and writes a clean daily CSV you can feed into dashboards or models.
What you’ll build: a daily AOA history table you can ship
You’ll create a lightweight pipeline that:
- Fetches AOA rates for specific dates and for a date range.
- Parses the JSON structure to extract the values you actually use.
- Saves a CSV with daily rows for AOA versus USD (both directions for convenience).
We’ll use two endpoints only—historical-by-date and time-series—so you can keep your integration small and reliable. If you later need more functionality, see the full Metals-API Documentation.
The endpoints you’ll call (focused on AOA historical data)
We’ll use exactly two endpoints:
- Historical Rates (single date): Get the rate snapshot for a given YYYY-MM-DD.
- Time-Series: Get daily rates between start_date and end_date.
AOA is a supported currency symbol. You can confirm codes on the Metals-API Supported Symbols page. Rates are returned relative to a base currency (USD by default), which is what we’ll use below.
1) Historical (single date) request for AOA
Use this when you need the rate on a specific date (for example, to reconcile a past trade or fill a single-day gap):
curl -s "https://metals-api.com/api/2026-10-10?access_key=YOUR_API_KEY&base=USD&symbols=AOA"
Notes:
- Replace YOUR_API_KEY with your key. If you don’t have one, you can Register for a free key.
- Set base=USD to keep interpretation straightforward: “how many AOA per 1 USD.”
- Set symbols=AOA to limit the payload to the Kwanza.
2) Time-series request for AOA
Use this when you need a daily series between two dates (for chart backfills, P&L, or regression windows):
curl -s "https://metals-api.com/api/timeseries?access_key=YOUR_API_KEY&base=USD&symbols=AOA&start_date=2026-10-01&end_date=2026-10-10"
Tips:
- Dates are inclusive. You’ll receive daily entries for each available day in the range.
- If you query long windows, cache the response and store it; you can incrementally extend later.
Understand the JSON you’ll parse
Below is a real sample payload for a historical AOA request. Use this to wire your parser and tests.
{"success":true,"timestamp":1791591660,"date":"2026-10-10","base":"USD","rates":{"AOA":917.5,"USD":1,"USDAOA":0.0010899182561307902}}
What matters for your pipeline:
- success: Boolean. Check this before using the data.
- timestamp: Unix epoch seconds (UTC). Good for cache control and audit logs.
- date: The effective date for this rate snapshot (YYYY-MM-DD).
- base: The reference currency. Here it’s USD.
- rates: A dictionary of symbols to numeric values.
- rates.AOA = 917.5 means 1 USD equals 917.5 AOA on 2026-10-10.
- rates.USD = 1 reflects the base currency normalization.
- rates.USDAOA is present in this sample. You can rely on rates.AOA for “AOA per USD” and compute the inverse yourself if you need “USD per AOA.”
Practical conversions:
- USD → AOA: amount_usd * rates.AOA
- AOA → USD: amount_aoa / rates.AOA
Short Python example: write AOA daily rates to CSV
This script requests a time-series window for AOA, then writes a CSV with three columns: date, AOA_per_USD, and USD_per_AOA (the inverse). You can drop this into your data job or notebook.
import csv
import datetime as dt
import os
import sys
import time
import urllib.parse
import urllib.request
import json
API_KEY = os.getenv("METALS_API_KEY", "YOUR_API_KEY")
def fetch_timeseries(base, symbols, start_date, end_date):
# Build the query
params = {
"access_key": API_KEY,
"base": base,
"symbols": symbols,
"start_date": start_date,
"end_date": end_date
}
url = "https://metals-api.com/api/timeseries?" + urllib.parse.urlencode(params)
# Basic fetch with simple retry
for attempt in range(3):
try:
with urllib.request.urlopen(url, timeout=20) as resp:
data = json.loads(resp.read().decode("utf-8"))
if not data.get("success", False):
raise RuntimeError("API returned success=false: %s" % data)
return data
except Exception as e:
if attempt == 2:
raise
time.sleep(1.5 * (attempt + 1))
def write_csv(data, out_path="aoa_timeseries.csv"):
# Expected shape:
# {
# "success": true,
# "timeseries": true,
# "start_date": "YYYY-MM-DD",
# "end_date": "YYYY-MM-DD",
# "base": "USD",
# "rates": { "YYYY-MM-DD": {"AOA": 917.5, ...}, ... }
# }
base = data.get("base", "USD")
rates_by_date = data.get("rates", {})
rows = []
for date_str, day_rates in rates_by_date.items():
aoa_per_usd = day_rates.get("AOA")
if aoa_per_usd is None:
continue
# Inverse for convenience
usd_per_aoa = 1.0 / aoa_per_usd if aoa_per_usd else None
rows.append((date_str, aoa_per_usd, usd_per_aoa))
# Sort by date ascending
rows.sort(key=lambda r: r[0])
with open(out_path, "w", newline="") as f:
w = csv.writer(f)
w.writerow(["date", "AOA_per_USD", "USD_per_AOA"])
w.writerows(rows)
return out_path
if __name__ == "__main__":
# Example window; change as needed or accept CLI args
start = "2026-10-01"
end = "2026-10-10"
payload = fetch_timeseries(base="USD", symbols="AOA", start_date=start, end_date=end)
path = write_csv(payload, out_path="aoa_%s_to_%s.csv" % (start, end))
print("Wrote:", path)
What to customize:
- Set METALS_API_KEY in your environment for CI/containers.
- Swap the date window for your backfill period, then schedule it (cron, Airflow, dbt, etc.).
- Store the output where your analytics stack reads it (S3, GCS, blob storage, or a warehouse ingest job).
How dates and rates are organized in time-series responses
For time-series, the shape is nested by day first, then by symbol. Expect:
- Top-level keys: success, timeseries, start_date, end_date, base, rates.
- rates: an object keyed by YYYY-MM-DD. Each day contains symbol:value pairs, i.e., { "AOA": number }.
Access pattern in pseudocode:
for each date_str in sorted(rates.keys()):
aoa_value = rates[date_str]["AOA"]
# aoa_value is AOA_per_USD for that date
Practical details that save time in production
- Date format: Always pass dates as ISO strings YYYY-MM-DD. The response uses the same format.
- Base currency: Defaults to USD. Keep base=USD for AOA unless you have a strong reason to change. If you do change base, your math and labels should change accordingly.
- Units: AOA is a fiat currency. Values represent “units of AOA per 1 USD” when base=USD. There are no metal weight units involved for this symbol.
- Timestamps & timezone: timestamp is Unix epoch seconds in UTC. Use it for cache keys and for provenance logs.
- Weekends and holidays: Expect days with no new pricing activity to be represented with the last available rate or simply fewer calendar entries in some endpoints. Your charting or accounting logic should handle missing days (forward-fill for visuals if needed, but keep raw truth in storage).
- Caching: For historical pulls, cache and persist results. Historical values don’t change frequently. Add E2E tests to confirm your parser still works when you extend the date range.
- Rollover windows: For long backfills, chunk the window and merge outputs. This reduces request size and makes retries cheaper if a single segment fails.
- Precision: Store values as decimals in your DB if you need strict reproducibility. CSV is fine for quick workflows, but consider Parquet/Arrow for larger datasets.
- Error handling: Check success before consuming data. Log base, date, and symbols from the payload to help downstream debugging.
When to use single-date vs. time-series for AOA
| Task | Endpoint | Why |
|---|---|---|
| Reconcile a specific booking date | Historical (single date) | Exact day’s snapshot with minimal payload. |
| Backfill a 3-month currency chart | Time-series | Daily values in one structured response. |
| Fill a one-off gap day in a warehouse | Historical (single date) | Targeted read; easy to retry and cache. |
| Compute rolling volatility across a window | Time-series | You need contiguous daily values for a range. |
Validation checklist before you ship
- Confirm AOA appears on the Symbols page.
- Use base=USD in both requests and UI labels (e.g., “AOA per 1 USD”).
- Guard against missing dates by forward-filling only in presentation layers.
- Persist the raw JSON for auditability or regenerate by date if you prefer stateless ops.
- Document your currency math: USD→AOA multiplies; AOA→USD divides.
Resources: dig deeper and compare
- API quick start and parameter reference: Metals-API Documentation
- Symbols and coverage: Metals-API Supported Symbols
- Market coverage and policy: Metals-API MCP
- Background on currency data and exchange rates: IMF Data, World Bank Open Data, FRED Economic Data
- API home for service status and product overview: Metals-API
FAQ
Q: How do I interpret the AOA number when base=USD?
A: It’s “AOA per USD.” For example, rates.AOA = 917.5 means 1 USD equals 917.5 AOA on that date. To convert AOA to USD, divide AOA by 917.5.
Q: What if I need the reverse (USD per AOA) in my CSV?
A: Compute the inverse: USD_per_AOA = 1 / AOA_per_USD. The Python snippet above writes both columns so you can choose at read time.
Q: Do I need to request weekends?
A: Request the full calendar range you need. Some days may not have new values; handle missing dates in your processing or forward-fill in visualization layers only.
Q: Can I change the base currency from USD?
A: Yes. If you do, your interpretation and math changes accordingly. Keep your base consistent across pipelines unless there’s a clear business reason to change it.
Q: How should I handle large backfills?
A: Split into monthly or quarterly windows, persist each response, and merge. This keeps requests smaller and retries cheaper.
Get your API key and start pulling AOA history
Spin up your AOA pipeline in minutes: get your key from the Register page, copy one of the curl commands above, and then drop the Python snippet into your data job. For parameter options and edge cases, refer to the Documentation and confirm symbols on Symbols. Then wire it into your trading tools, pricing engines, or research notebooks.