The Easiest Way to Get Mauritanian Ouguiya (MRO) - N/A Historical Rates (API request example)
You need a daily history table for the Mauritanian Ouguiya (MRO) to backfill charts, reconcile legacy transactions, or validate pricing logic. By the end of this guide you will request MRO historical rates from Metals-API, parse the JSON correctly, and export a clean CSV you can load into your data warehouse or feed into analytics.
What you will build: a daily MRO history table you can ship
The target deliverable is a CSV containing one row per day with the date, base currency, and the MRO exchange rate. You will:
- Query a single historical date when you just need a point-in-time check.
- Query a time window using the time-series endpoint to populate a table.
- Handle practical details like base currency defaults, timestamp handling, and market-closure days.
- Gracefully respond to symbol status (for example, an expired symbol warning) so your pipeline doesn’t break silently.
If you do not yet have an API key, grab one here: Register. Keep the key in an environment variable when running code in CI.
Endpoints to use for MRO history
This walkthrough focuses on two endpoints only—the ones you need for a history table:
- Historical date endpoint: request a single past date by appending the date to the path.
- Time-series endpoint: request a continuous daily series between start_date and end_date.
For complete parameter options and constraints, refer to the Documentation. To verify whether MRO is available in your plan and see replacement or related symbols, open the Symbols list.
Single-day MRO history: curl request and canonical JSON
Use the date-based historical endpoint when you need a single day’s snapshot. Replace YOUR_API_KEY with your key.
curl -s "https://metals-api.com/api/2026-10-05?access_key=YOUR_API_KEY&symbols=MRO&base=USD"
Here is an official example JSON for a historical request. Use it to understand structure and fields you’ll parse:
{"success":true,"timestamp":1791158880,"date":"2026-10-05","base":"USD","rates":{"MRO":0.00248969,"USD":1,"USDMRO":401.65643112194687},"warnings":[{"symbol":"MRO","code":410,"type":"expired_symbol","info":"The requested symbol has expired and is no longer available."}]}
What to read from this response
- success: Boolean—always check this before trusting the payload.
- timestamp: Unix epoch seconds. Treat this as UTC.
- date: The ISO date you requested, echoed back.
- base: The pricing base. By default, Metals-API returns rates relative to USD unless you set base explicitly.
- rates: Key-value map of symbols to rates. For currencies like MRO, the number is the amount of the symbol per one base unit (here, MRO per USD).
- warnings: Array you should log/handle. In this example, the API indicates MRO is an expired symbol. Your code should respond predictably to this status (e.g., switch to a supported symbol listed on the Symbols page or mark the row accordingly).
Note the presence of both MRO and USDMRO in rates. The base is USD, so:
- MRO: the value of 1 USD expressed in MRO units (MRO per USD).
- USDMRO: also represents a USD/MRO relationship. If both fields appear, prefer the field you explicitly requested via symbols for consistency; keep any additional symbols for audit/debug logs.
Time-series MRO history: fetch a date range
When you need a contiguous daily series—for example, to backfill your warehouse—use the time-series endpoint. The API returns a date-indexed object in rates.
curl -s "https://metals-api.com/api/timeseries?access_key=YOUR_API_KEY&start_date=2026-09-28&end_date=2026-10-05&symbols=MRO&base=USD"
Expect a structure similar to other time-series responses in the docs:
- success: true
- timeseries: true
- start_date / end_date: the requested window
- base: USD, unless overridden
- rates: a mapping of YYYY-MM-DD to a nested map of symbols and their rates for that day
When the symbol has status considerations (e.g., expired), you will still receive structured fields and warnings. Always read and act on warnings to avoid ingesting invalid or discontinued series without a control flag.
Python: write the MRO time series to CSV
The snippet below calls the time-series endpoint and writes a tidy CSV (date, base, symbol, rate, warning_code, warning_type). It keeps parsing logic minimal and robust to warnings. Set METALS_API_KEY in your environment before running.
import csv
import os
import sys
import time
import requests
API_KEY = os.getenv("METALS_API_KEY", "YOUR_API_KEY")
BASE = "USD"
SYMBOL = "MRO"
START = "2026-09-28"
END = "2026-10-05"
URL = "https://metals-api.com/api/timeseries"
params = {
"access_key": API_KEY,
"start_date": START,
"end_date": END,
"symbols": SYMBOL,
"base": BASE
}
try:
r = requests.get(URL, params=params, timeout=30)
r.raise_for_status()
data = r.json()
except Exception as e:
print(f"Request failed: {e}", file=sys.stderr)
sys.exit(1)
if not data.get("success", False):
print(f"API reported failure: {data}", file=sys.stderr)
sys.exit(1)
warnings = data.get("warnings", [])
warning_code = None
warning_type = None
if isinstance(warnings, list) and warnings:
# record the first warning at the series level; also log it
warning_code = warnings[0].get("code")
warning_type = warnings[0].get("type")
sys.stderr.write(f"Warning: {warnings[0].get('info')}\n")
rates_by_date = data.get("rates", {})
base = data.get("base", BASE)
with open("mro_timeseries.csv", "w", newline="") as f:
writer = csv.writer(f)
writer.writerow(["date", "base", "symbol", "rate", "warning_code", "warning_type"])
for date_str in sorted(rates_by_date.keys()):
day_map = rates_by_date.get(date_str, {})
# prefer the explicitly requested symbol
if SYMBOL in day_map:
rate = day_map[SYMBOL]
writer.writerow([date_str, base, SYMBOL, rate, warning_code or "", warning_type or ""])
else:
# if absent, persist empty and keep auditing; do not crash the pipeline
writer.writerow([date_str, base, SYMBOL, "", warning_code or "", warning_type or ""])
print("Wrote mro_timeseries.csv")
How the dates and rates are nested
Metals-API responses you’ll use here have two common patterns:
- Single-day historical: top-level date string and a flat rates object keyed by symbol.
- Time-series: top-level start_date and end_date, with rates as a mapping from date string (YYYY-MM-DD) to a nested mapping keyed by symbol.
In both, base is the reference currency that all rates are quoted against. For currencies, there is no unit like “per troy ounce”—that unit applies to metals pricing. For FX-style symbols such as MRO, parse the numeric value directly as “units of SYMBOL per 1 BASE.”
Operational details you should not skip
1) Base currency defaults
By default, the API returns rates relative to USD. If your downstream expects the inverse (e.g., USD per MRO), explicitly set base or compute the inverse yourself. Keep the base consistent throughout your pipeline to avoid silent unit drift.
2) Timestamps and timezone
- timestamp is Unix epoch seconds (UTC). Convert using your platform’s standard libraries.
- date values in historical and time-series payloads are calendar dates in ISO format (YYYY-MM-DD). Treat them as UTC-trading day cutoffs.
3) Weekends and market-closure days
- FX markets have reduced liquidity on weekends and holidays. Daily series may reflect carry-forward values or no updates for closure days. Do not assume seven observations per week.
- When building charts, forward-fill or gap-flag weekends depending on your product’s needs. Store the raw returned series as a canonical source, and apply transformations downstream.
4) Symbol availability and warnings
The example response above includes a warning that MRO is an expired symbol. Your ingestion should:
- Always check a warnings array when present. Log it with enough context (symbol, date range, code).
- Validate the symbol against the live catalog before bulk ingestion. Use the Symbols page to confirm current availability and discover related or successor symbols.
- When a symbol is expired, decide on a policy: halt ingestion and alert, or map to an alternate symbol determined by your business rules.
5) Caching to save requests
- Historical data does not change after publication. Cache it aggressively (HTTP cache, object store snapshots, or local files hashed by date range and parameters).
- For repeated jobs (e.g., rolling windows), only fetch the missing tail rather than the full history on every run.
6) Error handling and retries
- Check success before reading rates. Handle HTTP-level errors and JSON decoding errors cleanly.
- On intermittent network failures, implement bounded retries with exponential backoff. Log response payloads that include warnings or partial data.
7) Pagination and windowing
- Time-series windows are bounded per plan. If you need long spans, iterate across adjacent windows, sleep between calls if required by your plan, and concatenate results deterministically by date.
- Keep a monotonic merge: do not overwrite existing rows unless the API version or base parameters change.
8) Units: currencies vs metals
- For currencies like MRO, there is no metals unit. The number represents SYMBOL per BASE (e.g., MRO per USD).
- If you also consume metals prices in the same system, those often include a unit field like “per troy ounce.” Keep currency and metal series distinct in your schema: separate tables or a unit column that unambiguously distinguishes FX from metals.
Putting it together: a minimal ingestion workflow
- Validate symbol availability using the Symbols list. Record any replacements or deprecations.
- Run a single-date check via the historical endpoint to confirm structure and warnings for your symbol and base configuration.
- Request the time series for your desired window. If your plan has window limits, segment the request by month or quarter.
- Persist raw JSON responses for audit and reprocessing. Then normalize to a table with fields: date (UTC), base, symbol, rate, source_timestamp, warning_code, warning_type.
- Cache completed historical windows to avoid re-fetching immutable data. Only refresh the most recent partial window as needed.
- Monitor for warnings or structural changes. Surface them to observability so product owners aren’t surprised by symbol transitions.
Why developers use Metals-API for currency history alongside metals
If your application prices metal products, hedges exposure, or reconciles commodity-linked invoices, you often need both the metal price and the currency translation for billing or reporting. The same JSON shape and authentication model across endpoints keeps your ingestion simple while you scale both FX and metals in one place. Explore endpoint behaviors and constraints in the Documentation.
If you plan to enrich time-series analytics or compliance reporting further, review programmatic workflows in your stack and, when relevant, investigate additional reference materials from neutral institutions such as the Bank for International Settlements statistics or IMF Data to complement your internal policies. Those sources are external references; your canonical pricing for product logic should come from your Metals-API calls for consistency.
Troubleshooting MRO specifically
The example payload shows a symbol-level warning indicating MRO has expired. Your options:
- Confirm status on the Symbols page before building a historical backfill job.
- Decide on an internal mapping: keep MRO for legacy records but migrate to the currently supported symbol for new transactions. Store both the original symbol and the mapped symbol in your database for lineage.
- When warnings are returned, store warning_code and warning_type in your facts table so analysts can filter or flag rows during audits.
Quick reference: what to log and store
- Request parameters: endpoint, base, symbols, start_date, end_date.
- Response metadata: success, timestamp, and any warnings.
- Rates: per date and per symbol values as decimals with sufficient precision. Do not round before storage.
- Data lineage: response checksum or raw JSON path in object storage.
FAQ
Q1: Can I get a long multi-year MRO history in one call?
A: Time-series windows are bounded per plan. If you need multi-year coverage, iterate over adjacent windows (e.g., month-by-month) and merge the results. See the Documentation for date window constraints.
Q2: Why do I see a warnings array for MRO?
A: The API can return symbol status messages, such as expired_symbol. Always log and handle warnings. Verify current support on the Symbols page and, if needed, use your organization’s mapping policy for legacy symbols.
Q3: Are rates quoted as USD per MRO or MRO per USD?
A: Rates are quoted as SYMBOL per BASE. With base=USD, the value is MRO per USD. If you need the inverse, compute 1/value or set base accordingly.
Q4: How should I handle weekends and holidays?
A: Expect no updates or carry-forward behavior on closure days. Decide whether to forward-fill or omit non-trading days in your charts. Always store the raw series as delivered for audit.
Q5: Do metals units affect currency series?
A: No. Metals responses may include a unit like “per troy ounce.” Currency series like MRO do not use metals units—treat them as FX values relative to base.
Ready to implement this in your stack? Get your API key and start querying MRO history now: Register. Explore endpoint details and parameters in the Documentation, confirm symbol availability on Symbols, and review program resources like MCP if you’re standardizing integrations across teams.