API to Get the Uranium Jan 2026 (UXF26) - Per Pound Price with WebSocket streaming
You need a programmable way to pull the Uranium January 2026 contract (UXF26), compute a per‑pound price, and push it live into dashboards and trading tools over WebSocket. By the end of this guide you’ll query UXF26 from the Metals-API latest endpoint, interpret the response (including an “expired” warning), convert to USD per pound, and relay the updates to your users via a WebSocket you control.
What UXF26 delivers and how to get a per‑pound price
Metals-API returns exchange rates relative to a base currency (default USD). For UXF26 you will typically see both:
- rates.UXF26: the amount of UXF26 units per 1 USD (i.e., “units per USD”).
- rates.USDUXF26: the inverted rate — USD per 1 UXF26 unit.
Most pricing UIs want USD per contract unit. For UXF26, use rates.USDUXF26 directly if available. If you only have rates.UXF26, invert it: USD per unit = 1 / rates.UXF26.
Per‑pound conversion depends on the symbol’s native unit. Many metals on Metals-API are quoted “per troy ounce.” If your UXF26 unit is per troy ounce, convert to “USD per pound” by multiplying by 14.5833333 (since 1 lb avoirdupois = 14.5833333 troy ounces). Always confirm the symbol unit on the Metals-API Supported Symbols page before converting.
Important: UXF26 is a dated (January 2026) contract and is now expired. Metals-API still returns data with an “expired_symbol” warning. Use the warning to decide whether to roll to the next active symbol for live pricing, or to continue using UXF26 for historical backfills and P&L reconciliation.
Quickstart: query UXF26 from the latest endpoint
The latest endpoint returns the most recent available data for requested symbols. Copy and run:
curl "https://metals-api.com/api/latest?access_key=YOUR_API_KEY&symbols=UXF26,USDUXF26"
Official response example (do not alter values):
{"success":true,"timestamp":1792800540,"date":"2026-10-24","base":"USD","rates":{"UXF26":0.011037527593819,"USD":1,"USDUXF26":90.59999999999988},"warnings":[{"symbol":"UXF26","code":410,"type":"expired_symbol","info":"The requested symbol has expired and is no longer available."}]}
What the fields mean for pricing and alerts
- base: "USD" — all rates are relative to USD.
- rates.UXF26: 0.0110375 — contract units per 1 USD (useful if you prefer to invert yourself).
- rates.USDUXF26: 90.6 — USD per 1 UXF26 unit (use this directly for price displays).
- timestamp: 1792800540 — UNIX epoch seconds (UTC). Cache and compare this to detect staleness.
- warnings[*].type: "expired_symbol" — indicates UXF26 is expired; switch to the current active uranium symbol for streaming quotes.
From USD per unit to USD per pound
Follow these steps:
- Read USD per unit: take rates.USDUXF26 (90.6 in the sample).
- Verify the native unit for UXF26 on the Symbols page.
- If the unit is per troy ounce, convert to per pound: usd_per_lb = usd_per_oz_t * 14.5833333.
- If the unit is already per pound, use rates.USDUXF26 as‑is.
Tip: persist both the raw API quote and your derived per‑pound value. That makes audits and reconciliation easier when specifications change or you roll to a new symbol.
Python code: fetch UXF26 and compute per‑pound
This snippet requests UXF26, checks for the expired warning, and computes USD per pound when the symbol’s unit is troy ounces.
import os
import time
import requests
API_KEY = os.getenv("METALS_API_KEY", "YOUR_API_KEY")
URL = "https://metals-api.com/api/latest"
def fetch_uxf26():
params = {
"access_key": API_KEY,
"symbols": "UXF26,USDUXF26"
}
r = requests.get(URL, params=params, timeout=10)
r.raise_for_status()
data = r.json()
if not data.get("success", False):
raise RuntimeError(f"Metals-API error: {data}")
return data
def usd_per_pound_from_response(data, assumes_troy_oz=True):
rates = data.get("rates", {})
usd_per_unit = rates.get("USDUXF26")
if usd_per_unit is None:
uxf26_per_usd = rates.get("UXF26")
if not uxf26_per_usd:
raise RuntimeError("Neither USDUXF26 nor UXF26 present in response.")
usd_per_unit = 1.0 / uxf26_per_usd
if assumes_troy_oz:
# Convert troy ounces to pounds (avoirdupois)
TROY_OZ_PER_POUND = 14.5833333
usd_per_lb = usd_per_unit * TROY_OZ_PER_POUND
else:
usd_per_lb = usd_per_unit # already per pound
return usd_per_unit, usd_per_lb
def main():
data = fetch_uxf26()
ts = data.get("timestamp")
dt_utc = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(ts)) if ts else "n/a"
# Warning handling
for w in data.get("warnings", []):
if w.get("symbol") == "UXF26":
print(f"Warning for UXF26: {w.get('type')} - {w.get('info')}")
usd_per_unit, usd_per_lb = usd_per_pound_from_response(data, assumes_troy_oz=True)
print(f"Base: {data.get('base')} | As-of (UTC): {dt_utc}")
print(f"USD per UXF26 unit: {usd_per_unit}")
print(f"USD per pound (derived): {usd_per_lb}")
if __name__ == "__main__":
main()
Note: set assumes_troy_oz=False if the UXF26 specification says the native unit is per pound. Always verify unit definitions on the Symbols page.
Stream UXF26 to clients: build your own WebSocket relay
Metals-API exposes a simple JSON REST API; it does not provide a WebSocket endpoint. To deliver “streaming” UXF26 to browsers and terminals, run a lightweight relay that polls the latest endpoint and pushes updates to subscribers over your own WebSocket channel.
Architecture pattern:
- Backend poller: fetches latest UXF26 on a cadence allowed by your plan’s update frequency. Use If-Modified-Since or cache the last timestamp to avoid redundant pushes.
- WebSocket server: keeps client connections and broadcasts the newest normalized price (including per‑pound) when data changes.
- Client: subscribes to your WebSocket and renders the newest price, OHLC, or deltas.
Practical tips:
- Use exponential backoff on HTTP error codes and network failures.
- Throttle broadcasts to avoid spamming clients when data hasn’t changed.
- Propagate the Metals-API timestamp so downstream systems can reason about staleness.
Minimal Node.js relay (poll + broadcast)
This example polls latest UXF26 and broadcasts to connected WebSocket clients only when the timestamp or price changes. It shows the pattern; adapt intervals to your plan’s update frequency described in the Documentation.
// npm install ws node-fetch
import fetch from "node-fetch";
import { WebSocketServer } from "ws";
const API_KEY = process.env.METALS_API_KEY || "YOUR_API_KEY";
const POLL_MS = 60_000; // align with your plan's update interval
const URL = `https://metals-api.com/api/latest?access_key=${API_KEY}&symbols=UXF26,USDUXF26`;
const TROY_OZ_PER_POUND = 14.5833333;
let lastBroadcast = null;
const wss = new WebSocketServer({ port: 8080 });
wss.on("connection", (ws) => {
ws.send(JSON.stringify({ type: "hello", message: "Subscribed to UXF26" }));
});
async function pollAndBroadcast() {
try {
const res = await fetch(URL, { timeout: 10000 });
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data = await res.json();
if (!data.success) throw new Error(`API error: ${JSON.stringify(data)}`);
const base = data.base;
const ts = data.timestamp;
const rates = data.rates || {};
let usdPerUnit = rates.USDUXF26;
if (usdPerUnit == null && rates.UXF26 != null) usdPerUnit = 1 / rates.UXF26;
// Assume per troy ounce unless your symbol notes say per pound:
const usdPerLb = usdPerUnit != null ? usdPerUnit * TROY_OZ_PER_POUND : null;
const payload = {
type: "uxf26_tick",
base,
timestamp: ts,
date: data.date,
expired: (data.warnings || []).some(w => w.symbol === "UXF26"),
usd_per_unit: usdPerUnit,
usd_per_pound: usdPerLb
};
// Avoid rebroadcasting identical payloads
const serialized = JSON.stringify(payload);
if (serialized !== lastBroadcast) {
lastBroadcast = serialized;
wss.clients.forEach((client) => {
if (client.readyState === 1) client.send(serialized);
});
}
} catch (err) {
// Log and keep polling
console.error("Polling error:", err.message);
} finally {
setTimeout(pollAndBroadcast, POLL_MS);
}
}
pollAndBroadcast();
console.log("WebSocket relay on ws://localhost:8080 (UXF26)");
Historical backfills and symbol rollovers
Because UXF26 is expired, you’ll often combine:
- latest: to read the final state and keep a single reference price of the expired contract for reports.
- historical/time-series: to build a price history for charts, P&L explains, or backtesting.
For details and date limits, refer to the Documentation. When you roll to a live uranium symbol, retrieve its exact code and unit from the Symbols page and update your polling symbols list and unit conversion.
Operational details that save time
- Base currency: Metals-API defaults to USD; the examples above assume base="USD". Your app logic should not assume a different base unless you explicitly request it.
- Units: Many metals are quoted per troy ounce. Pounds are “avoirdupois” (453.59237 g). 1 lb = 14.5833333 troy oz. Confirm each symbol’s unit before converting.
- Timestamps and timezone: timestamp is UNIX seconds in UTC. Use this to determine staleness and to sequence events in your downstream systems.
- Market closures and weekends: If the underlying market is closed, new timestamps may not appear. Cache the last good response and avoid rebroadcasting unchanged data.
- Caching and request economy: Store the last seen timestamp and values. Only compute deltas and push updates when values change. This reduces HTTP calls and client traffic.
- Warnings: Handle the warnings array programmatically. For expired_symbol, consider switching users to the current active symbol automatically, and annotate UIs with a rollover message.
- Resilience: Apply reasonable timeouts on HTTP (10s is typical), retry with backoff, and surface errors to observability tools so you can tune polling cadence per plan.
Where to find symbols, units, and endpoint details
- Live endpoints, parameters, and limits: read the Metals-API Documentation.
- Exact symbol codes and their units: see the Metals-API Supported Symbols page.
- Manage your key and plan: visit MCP.
End-to-end checklist
- Get an API key and verify you can call /api/latest.
- Request symbols=UXF26,USDUXF26 and confirm you receive rates and possibly an expired_symbol warning.
- Normalize to USD per unit (prefer rates.USDUXF26 when present).
- Convert to USD per pound after confirming the native unit for UXF26.
- Cache the last timestamp and only broadcast updates when values change.
- When UXF26 is expired, roll your UI to the active uranium symbol from the Symbols page.
FAQ
Does Metals-API provide a WebSocket feed?
No. Metals-API is a JSON REST API. To deliver “streaming” UXF26 to clients, run a small WebSocket service that polls the latest endpoint and broadcasts changes.
What unit does UXF26 use?
Units vary by symbol. Check UXF26 on the Symbols page and convert accordingly (for troy ounces multiply USD/oz by 14.5833333 to get USD/lb).
How do I know if UXF26 data is current?
Use the timestamp field (UTC). If the timestamp doesn’t advance between polls, the market may be closed or the symbol expired. Also check the warnings array for expired_symbol.
How frequently should I poll?
Poll at or below your plan’s update frequency. Cache and only push updates when the timestamp or price changes to conserve requests and bandwidth. See the Documentation for endpoint behavior.
How do I backfill a UXF26 chart?
Use the historical or time-series endpoints to fetch daily data for your date range, then compute USD per pound for each day using the same unit conversion rules you apply to latest.
Ready to build? Get your API key and start integrating UXF26 into your pricing and streaming stack: Register. Explore endpoint details in the Documentation and manage your plan in MCP.