High Grade Copper Sep 2025 (HGU25) - Per Pound Real-Time Price API
You need a per‑pound, real‑time feed for High Grade Copper Sep 2025 (HGU25) to power pricing, risk, or dashboards. By the end of this guide, you will query Metals-API for HGU25, detect if the contract is expired, and implement a robust fallback to keep your copper-per‑pound output flowing using the same endpoint and consistent math.
What we’re building: a resilient HGU25 per‑pound price feed
Futures contracts roll and expire. Your application still has to display a copper price per pound that updates reliably. We’ll:
- Call the Latest endpoint for HGU25 and parse the response.
- Detect the explicit “expired_symbol” warning if the contract is no longer tradable.
- Explain the unit model (troy ounces) and the exact conversion to USD per pound.
- Outline a safe fallback strategy you can adopt the moment HGU25 is expired (without guessing prices).
If you’re new to Metals-API, review the Documentation and get an API key via Register. There is no free trial; Copper Monthly is $19.99/month.
HGU25 vs. XCU and how units work
HGU25 denotes the September 2025 High Grade Copper futures contract. As contracts expire, direct quotes can become unavailable. For continuity, many systems fall back to a spot-like copper symbol (XCU) or the current front-month contract when a specific month contract is not available.
Key unit and inversion facts you’ll use in code:
- Base: USD by default. Rates are expressed as metal units per 1 USD (e.g., troy ounces per USD).
- Inverse: To get USD per troy ounce, take 1 / rates.SYMBOL.
- Troy ounce to pound: 1 pound (avoirdupois) = 14.5833333333 troy ounces.
- USD per pound = (USD per troy ounce) × 14.5833333333.
Because copper pricing in North American markets is often per pound, that last step is essential to transform Metals-API’s per‑troy‑ounce basis into the per‑pound format your users expect.
To see what symbols are available at any time (including copper variants), use the up-to-date list at Metals-API Supported Symbols.
Request HGU25 from the Latest endpoint
Start with the Latest endpoint for HGU25. This shows you how to detect an expired contract cleanly without guessing.
cURL request
curl "https://metals-api.com/api/latest?access_key=YOUR_API_KEY&symbols=HGU25"
Official sample response
{"success":true,"timestamp":1791763680,"date":"2026-10-12","base":"USD","rates":{"USD":1},"warnings":[{"symbol":"HGU25","code":410,"type":"expired_symbol","info":"The requested symbol has expired and is no longer available."}]}
What you’ll actually use from this payload:
- success: Whether the call succeeded at the transport level.
- timestamp and date: When the response was generated; cache by timestamp to avoid unnecessary requests.
- warnings: An array that can include symbol-specific issues. Here you must treat HGU25 as unavailable because it is explicitly flagged as expired_symbol.
- rates: Because HGU25 is expired, no HGU25 quote is present. Do not attempt to derive a price from this payload.
Implement expiration handling and per‑pound math
The correct behavior when a contract is expired is to respect the explicit warning and route to a fallback your business logic allows (for example, switch to XCU or your house-selected active copper contract code). Below is a Python snippet that:
- Requests HGU25 from the Latest endpoint.
- Checks warnings for an “expired_symbol”.
- If expired, demonstrates where you would branch to your fallback symbol logic.
- Shows the exact per‑pound conversion formula you will apply when you have a per‑troy‑ounce USD price.
import requests
from decimal import Decimal, InvalidOperation
API_URL = "https://metals-api.com/api/latest"
API_KEY = "YOUR_API_KEY"
REQUEST_SYMBOL = "HGU25"
def fetch_latest(symbol):
params = {
"access_key": API_KEY,
"symbols": symbol
}
r = requests.get(API_URL, params=params, timeout=10)
r.raise_for_status()
return r.json()
def extract_usd_per_pound_from_rate(rate_value_per_oz):
# rate_value_per_oz is USD per troy ounce (a Decimal)
TROY_OUNCES_PER_POUND = Decimal("14.5833333333")
return rate_value_per_oz * TROY_OUNCES_PER_POUND
def main():
data = fetch_latest(REQUEST_SYMBOL)
# Check for symbol-level issues
warnings = data.get("warnings", []) or []
expired = any(w.get("symbol") == REQUEST_SYMBOL and w.get("type") == "expired_symbol" for w in warnings)
if expired:
# Do not guess. Branch to your fallback policy here.
# Example (not executed here): fallback_symbol = "XCU"
# Then issue a second call with symbols=fallback_symbol and proceed.
print(f"{REQUEST_SYMBOL} is expired; switch to your chosen copper fallback symbol.")
return
# If not expired and you received a metals quote:
# Metals-API responses are base=USD by default; for metals, rates map is <SYMBOL>: troy_ounces_per_USD.
# To compute USD per troy ounce, invert: 1 / rates[SYMBOL].
try:
rates = data.get("rates", {})
metal_per_usd = Decimal(str(rates[REQUEST_SYMBOL])) # e.g., troy ounces per 1 USD
if metal_per_usd == 0:
raise InvalidOperation("Division by zero")
usd_per_troy_ounce = Decimal("1") / metal_per_usd
usd_per_pound = extract_usd_per_pound_from_rate(usd_per_troy_ounce)
print(f"USD per troy ounce: {usd_per_troy_ounce}")
print(f"USD per pound: {usd_per_pound}")
except (KeyError, InvalidOperation, ValueError) as e:
print(f"Could not compute price for {REQUEST_SYMBOL}: {e}")
if __name__ == "__main__":
main()
Notes on the math and flow:
- Do not proceed with price calculations if the symbol is expired or missing in rates.
- When you do have a valid metals quote for copper, you will invert the rate (troy ounces per USD → USD per troy ounce), then multiply by 14.5833333333 to produce USD per pound.
- Use Decimal for financial math to avoid binary floating-point surprises.
Operational guidance that saves time
- Base currency and inversion: With base=USD, rates.SYMBOL is “troy ounces per USD.” To display USD per troy ounce, invert. To display USD per pound, invert then multiply by 14.5833333333.
- Timestamps and timezone: The timestamp is UNIX epoch seconds; align caching and UI timestamps accordingly. Avoid spamming the endpoint between identical timestamps.
- Caching: Cache by the combination of endpoint, symbol set, and timestamp. Many plans update at fixed intervals; honoring the timestamp prevents redundant calls.
- Weekends/non-trading days: Metals markets can be less active or closed; the latest timestamp may not advance. In that case, keep your last-known-good value and annotate “last updated.”
- Error handling: Inspect “success” and “warnings.” The explicit expired_symbol type should be treated as a hard stop for that code path.
- Units in UX: Label clearly as “USD/lb” after conversion. If you also show metric, 1 lb = 0.45359237 kg.
Endpoint choices for copper workflows
For HGU25 specifically, focus on these two patterns and keep the rest of your integration modular:
- Latest endpoint for intraday updates and status checks (like the expired_symbol warning).
- Time-series or OHLC for analytical backfills and candles when your selected copper symbol is available. Review parameters in the Documentation and use them with your chosen active copper symbol.
Because contract-specific symbols can expire, build your copper pipeline around a “symbol router” that decides which symbol to request today, while still honoring the unit and inversion math consistently.
Symbol discovery and lifecycle
HGU25 is a dated contract symbol. When it is not available, Metals-API will tell you explicitly via warnings. Before you promote a symbol to production, confirm its availability via the up-to-date Symbols list. Automate a daily check to swap your “active” copper symbol when a contract nears expiration or rolls.
If your workflow follows exchange calendars, you may also want to track rollover schedules at the exchange. Reference product resources like CME Group Copper Futures contract specifications or LME Copper for lifecycle context. Your API logic should still defer to the real-time availability signals that Metals-API returns.
Smart integration tips for production
- Guardrails: Treat any non-empty warnings array as actionable. Log, alert, and branch logic accordingly.
- Batching: If you fetch multiple symbols, group them in one request to reduce overhead and ensure consistent timestamps across your portfolio snapshot.
- Precision: Use Decimal at least to 4–6 decimal places for USD/lb in analytics; round only at presentation time.
- Idempotence: If the timestamp has not progressed, skip writes to downstream stores to avoid churn.
- Monitoring: Track “last success timestamp per symbol” in metrics. Spikes in expired_symbol or missing symbols should trigger a rotation to your fallback set.
- Plan fit: Update frequency differs by plan tier. Size your polling interval to the update cadence referenced in the Documentation.
Why per‑pound matters for copper applications
Copper is a backbone of electrification, data centers, EVs, and grid upgrades. Many operational systems in manufacturing, construction, and procurement price copper per pound, so transforming troy‑ounce quotes to per‑pound is not optional—it’s the interface your stakeholders understand. Metals-API’s consistent base and units let you compute USD/lb deterministically and, once you resolve to a live copper symbol, keep your KPIs aligned across trading and operations.
For more on how Metals-API supports metals pricing and currency conversion in modern stacks, explore Metals-API, and if you need curated market content for your app, check out MCP.
Testing checklist
- Verify your Latest call returns success=true.
- Assert that warnings is either empty or, if non-empty, implement the documented branch (e.g., expired_symbol).
- When receiving a valid copper rate, compute USD/oz as 1 / rate, then USD/lb by multiplying by 14.5833333333.
- Round/format only for the UI; preserve full precision in your datastore.
- Cache until the timestamp advances; do not re-poll faster than your plan’s update cadence.
FAQ
Can I get a live per‑pound HGU25 price directly?
When HGU25 is active and returned by Metals-API, you can compute USD/lb from the USD/oz quote using the formula above. If the symbol is expired (expired_symbol warning), do not extrapolate—switch to your designated live copper symbol.
What if the response shows only {"USD": 1} in rates?
This indicates no valid quote for your requested symbol set (often due to expiration). Check the warnings array for the reason and follow your fallback policy.
How do I convert to another currency?
Use the conversion capabilities documented in the Documentation. Maintain the same inversion and pound conversion math after you have USD/oz, or convert the final USD/lb into your target currency.
Why does the rate look inverted compared to exchange quotes?
Metals-API defaults to base=USD and returns metal units per 1 USD. Exchange quotes are typically USD per unit. Always invert 1 / rate to get USD per troy ounce before computing USD/lb.
Is there a free trial?
No. There is no free trial. Copper Monthly is $19.99/month.
Ship your copper feed with confidence: get your API key at Register, consult the Documentation for endpoint details, and confirm copper symbols anytime via Symbols. If you need editorial market content alongside your data, explore MCP.