The Easiest Way to Get Westmetall Higher Copper (XCU_WM_H) - Per 100 Kg, via REST API Historical Rates
You need a clean daily history of Westmetall Higher Copper (XCU_WM_H) priced per 100 kg, ready to power analytics, pricing logic, and dashboards. By the end of this guide, you will query historical and time-series rates via a REST API, parse the JSON, and export a daily table for XCU_WM_H that you can drop into a spreadsheet or feed into your app.
What you will build: a daily history table for XCU_WM_H (per 100 kg)
We will assemble a simple, dependable “daily history” dataset for the Westmetall Higher Copper index symbol XCU_WM_H. This dataset will include:
- Date (UTC)
- XCU_WM_H rate with base USD (the number of 100 kg units per 1 USD)
- USD per 100 kg (the inverse from the rate or the convenience field USDXCU_WM_H when available)
We will use two Metals-API endpoints only:
- Single historical date
- Time-series (start_date to end_date)
If you have not yet created an API key, you can get one here: Register. For endpoint and parameter behavior, see the Documentation. To confirm the symbol’s definition and unit (“per 100 kg”), check the Symbols page.
Historical date endpoint: build and test a single-day request
The historical date endpoint lets you retrieve the rate snapshot for a specific day. For XCU_WM_H, include the symbol directly in the symbols list. If you need both the direct rate and the USD-quoted convenience rate, include XCU_WM_H and USDXCU_WM_H together in the symbols parameter.
Single-day curl example (copy/paste)
curl "https://metals-api.com/api/2026-10-02?access_key=YOUR_API_KEY&symbols=XCU_WM_H,USDXCU_WM_H"
Replace YOUR_API_KEY with your actual key. The default base is USD.
Official JSON response example for XCU_WM_H
{"success":true,"timestamp":1790899680,"date":"2026-10-02","base":"USD","rates":{"XCU_WM_H":0.00068384908794488,"USD":1,"USDXCU_WM_H":1462.3109361821691}}
How to read this response
- success: true indicates the request succeeded.
- timestamp: Unix epoch seconds (UTC) when the snapshot was produced. Use it for audit trails or cache keys.
- date: The historical date you asked for (YYYY-MM-DD).
- base: The base currency for rates (USD by default).
- rates:
- XCU_WM_H: 0.00068384908794488 means “per 1 USD, how many 100-kg units of Westmetall Higher Copper.” To get USD per 100 kg, invert it: 1 / 0.00068384908794488 ≈ 1462.310936..., which the API also exposes as USDXCU_WM_H.
- USDXCU_WM_H: 1462.3109361821691 USD per 100 kg. This is convenient for pricing workflows and is numerically the inverse of XCU_WM_H.
Because XCU_WM_H is “per 100 kg,” treat USDXCU_WM_H as a price per 100 kg. For conversions:
- USD per metric ton (1,000 kg) ≈ USDXCU_WM_H × 10
- USD per kilogram ≈ USDXCU_WM_H ÷ 100
- USD per pound ≈ (USDXCU_WM_H ÷ 100) × 2.20462262185
Time-series endpoint: fetch a daily range to backfill and maintain your table
The time-series endpoint returns daily snapshots between start_date and end_date. Use it to backfill history and to append yesterday’s row on a schedule. You can request XCU_WM_H alone, or include USDXCU_WM_H for direct pricing.
Time-series curl example (copy/paste)
curl "https://metals-api.com/api/timeseries?access_key=YOUR_API_KEY&start_date=2026-09-01&end_date=2026-10-02&symbols=XCU_WM_H,USDXCU_WM_H"
Notes:
- Dates are inclusive (YYYY-MM-DD). See the Documentation for available ranges by plan.
- Expect some days to be missing for non-trading days or source holidays. Handle gaps by forward-filling or skipping, depending on your use case.
Code: write XCU_WM_H time-series to CSV
The snippet below requests a date range for XCU_WM_H and writes a CSV with one row per day, including both the direct rate and the USD-quoted price per 100 kg. If the convenience USDXCU_WM_H field is not present for some days, it computes the inverse.
import csv
import os
import sys
import time
import urllib.parse
import urllib.request
import json
API_KEY = os.getenv("METALS_API_KEY", "YOUR_API_KEY")
BASE_URL = "https://metals-api.com/api/timeseries"
params = {
"access_key": API_KEY,
"start_date": "2026-09-01",
"end_date": "2026-10-02",
"symbols": "XCU_WM_H,USDXCU_WM_H"
}
url = f"{BASE_URL}?{urllib.parse.urlencode(params)}"
def fetch(url):
with urllib.request.urlopen(url) as resp:
return json.loads(resp.read().decode("utf-8"))
def to_usd_per_100kg(rates_day):
# Prefer the convenience field if available
usd_per_100kg = rates_day.get("USDXCU_WM_H")
if usd_per_100kg is not None:
return usd_per_100kg
# Fall back to inverting XCU_WM_H if present
xcu_per_usd = rates_day.get("XCU_WM_H")
if xcu_per_usd and xcu_per_usd != 0:
return 1.0 / xcu_per_usd
return None
try:
data = fetch(url)
except Exception as e:
print(f"Request failed: {e}", file=sys.stderr)
sys.exit(1)
if not data.get("success"):
print(f"API error: {data}", file=sys.stderr)
sys.exit(1)
rates = data.get("rates", {}) # expected: dict keyed by 'YYYY-MM-DD'
rows = []
for day, symbols in sorted(rates.items()):
xcu_per_usd = symbols.get("XCU_WM_H")
usd_per_100kg = to_usd_per_100kg(symbols)
# Derive optional convenience conversions
usd_per_kg = usd_per_100kg / 100.0 if usd_per_100kg else None
usd_per_ton = usd_per_100kg * 10.0 if usd_per_100kg else None
rows.append({
"date": day,
"base": data.get("base", "USD"),
"xcu_wm_h_per_usd": xcu_per_usd, # number of 100-kg units per 1 USD
"usd_per_100kg": usd_per_100kg, # price per 100 kg
"usd_per_kg": usd_per_kg, # convenience derived value
"usd_per_metric_ton": usd_per_ton # convenience derived value
})
# Write CSV
out_path = "xcu_wm_h_history.csv"
with open(out_path, "w", newline="") as f:
writer = csv.DictWriter(f, fieldnames=rows[0].keys())
writer.writeheader()
writer.writerows(rows)
print(f"Wrote {len(rows)} rows to {out_path}")
What this script assumes and safeguards:
- The response contains a top-level rates object keyed by ISO date.
- For each day, it searches for XCU_WM_H and USDXCU_WM_H. If the inverse field is missing, it computes USD per 100 kg as 1 / XCU_WM_H.
- It gracefully handles missing or zero values by writing None. Decide how to treat these in downstream logic.
How dates and rates are structured
For single-day calls, you receive a flat rates object keyed by symbol. For time-series calls, you receive rates keyed by date, with each date containing a symbol map. Store your data in a long (tidy) table with date as the primary index. Avoid assuming contiguous dates; missing days are normal for weekends and market holidays.
Practical details that save time (and bugs)
- Units for XCU_WM_H: This symbol is “per 100 kg.” The rate XCU_WM_H in a USD base means “100-kg units per USD.” To price in USD, use USDXCU_WM_H when available or invert XCU_WM_H.
- Base currency: Responses are USD by default. If you need another base, consult the Documentation for supported parameters and plan availability.
- Timestamps and timezone: timestamp is Unix epoch seconds in UTC. date is YYYY-MM-DD in UTC. Align your storage and charting to UTC to avoid off-by-one-day issues.
- Weekends, holidays and closures: Some dates won’t return fresh rates due to non-trading days or source holidays (e.g., European market holidays). Handle gaps by:
- Forward-filling for chart continuity, with a caveat that it repeats the last known close.
- Leaving gaps for precision in event-driven strategies.
- Caching: Cache same-day or recent responses keyed by symbol set + date + base + unit assumptions. The timestamp helps you decide freshness windows. This reduces duplicate API calls and stabilizes dashboards.
- Precision: Treat numeric fields as decimals in downstream calculations. Python’s decimal module (or careful float formatting) helps avoid rounding surprises in financial reports.
- Scaling: For pricing in different units:
- USD per 100 kg → USD per kg: divide by 100
- USD per 100 kg → USD per metric ton: multiply by 10
- USD per kg → USD per lb: multiply by 2.20462262185
- Validation: Sanity-check that (USDXCU_WM_H ≈ 1 / XCU_WM_H) when both are present, within rounding thresholds.
Why XCU_WM_H matters for digital copper workflows
Westmetall Higher Copper is used across procurement, invoicing, and risk management contexts as a transparent benchmark. With a clean historical series for XCU_WM_H:
- Pricing engines can quote catalog SKUs in near-real time, converting per 100 kg into per piece weight or per-meter weights.
- Hedging dashboards can compute rolling averages, drawdowns, and volatility over consistent UTC dates.
- Forecasting models can incorporate copper index trends directly, without manual spreadsheet imports.
Metals-API delivers this data in a developer-friendly JSON format that snaps into Python, JavaScript, and ETL tools. For a full symbol reference and metadata, use Metals-API Supported Symbols. For integration specifics and plan features, see the Metals-API Documentation.
Common patterns: keeping your XCU_WM_H series healthy
- Daily job at 23:59 UTC: Call the single-date endpoint for the current day; write a row if it’s new. If you detect a holiday, skip or forward-fill based on policy.
- Weekly backfill: Run a time-series call for the last 14 days to patch any missing rows due to temporary connectivity or API pauses.
- Event-driven invalidation: If you use intraday or latest endpoints in addition to historical, prefer historical for your end-of-day table to lock in the snapshot associated with that date field.
- Unit conversions at write-time: Normalize to USD per 100 kg and store that as the main price, plus your preferred convenience unit (e.g., USD per kg). This simplifies analytics.
- Checksums: Store 1/XCU_WM_H alongside USDXCU_WM_H to detect unusual divergences caused by transient feed issues.
Endpoint recap and where to go next
- Single historical date: Query by YYYY-MM-DD to get a point-in-time rate set for XCU_WM_H and, optionally, USDXCU_WM_H.
- Time-series: Query a date range for daily rates. Expect gaps; handle accordingly.
- Other useful endpoints exist (latest, OHLC, fluctuation, convert), but for building a reliable daily history, the two endpoints above are sufficient. Explore additional endpoints in the Documentation.
If your workflow intersects with compliance or audit trails, read about Metals-API’s MCP initiative here: MCP.
FAQ
What unit does XCU_WM_H use?
XCU_WM_H is “per 100 kg.” With base USD, XCU_WM_H is the number of 100-kg units per 1 USD. For pricing, invert it or read USDXCU_WM_H directly to get USD per 100 kg.
Do I have to request both XCU_WM_H and USDXCU_WM_H?
No. If you only request XCU_WM_H, you can compute USD per 100 kg as 1 / XCU_WM_H. Requesting USDXCU_WM_H is convenient and removes the need to invert.
Why are some dates missing?
Non-trading days and market holidays may not produce new rates. Decide whether to forward-fill, interpolate, or leave gaps. Align to UTC dates to avoid off-by-one errors.
Can I change the base currency?
Yes, subject to your plan. See the Documentation for parameters and availability.
How should I cache?
Cache by (endpoint, date or date-range, symbols, base). Respect the timestamp and avoid re-fetching the same day repeatedly unless you need the most recent snapshot.
Ready to pull Westmetall Higher Copper history into your toolchain? Grab your API key and start with the two curl calls above: Register.