How to Get Real-Time Silver (XAG) - Per Troy Ounce Prices with Metals-API using Python requests
Real-time silver (XAG) per troy ounce pricing is a building block for live product pricing, hedging dashboards, factory MRP updates, and quant models in commodities and fintech. In this guide, you’ll fetch live XAG quotes with Metals-API using Python requests, interpret the response fields you’ll actually use (timestamp, base, unit, rates), and productionize your workflow with caching, retries, and weekend/holiday handling. We’ll focus on three endpoints that cover the core lifecycle of a silver data pipeline: Latest Rates (for the current XAG quote), Bid/Ask (for executable spreads), and Time-series (for backfills and signals). If you don’t yet have credentials, you can get an API key from the Metals-API Website and confirm the XAG symbol on the Metals-API Supported Symbols page.
What you’ll build: a real-time XAG price feed you can trust
We’ll walk through how to wire up a small Python client that retrieves the latest XAG price per troy ounce, transforms it to USD per gram for manufacturing cost models, and supplements it with spread-aware bid/ask data for trading and e-commerce markups. You’ll also learn how to pull a daily time-series to calculate rolling metrics (e.g., a simple moving average) and how to harden your integration against finite quotas, network glitches, and scheduled market closures.
Why silver (XAG) — and why “per troy ounce” matters
Silver’s dual identity—precious metal and industrial workhorse—means its price directly impacts electronics manufacturing, solar panel production, medical devices, and even advanced sensor systems. Smart factories and ERP systems need consistent, machine-readable quotes to optimize vendor contracts, BOM updates, and re-order points. Metals-API returns XAG prices “per troy ounce” by default. A troy ounce equals approximately 31.1034768 grams (not the 28.3495 grams of an avoirdupois ounce). Using the wrong ounce standard skews cost models, hedges, and customer pricing, so we’ll show how to convert to grams precisely.
The 3 endpoints you actually need for real-time silver
- Latest Rates: fetch the current XAG price, updated according to your plan’s interval.
- Bid/Ask: retrieve XAG bid and ask for spread-aware decisions (e.g., execution cost, retail markups).
- Time-series: pull historical daily closes for backtests, rolling indicators, and anomaly detection.
For broader capabilities (OHLC bars, conversion, fluctuation analysis, and more), review the Metals-API Documentation. Always verify symbol availability and naming via the Metals-API Supported Symbols list; silver uses the symbol XAG.
Authentication and base behavior
- API key: pass it via the access_key parameter with your requests. Obtain one from the Metals-API Website.
- Base currency: responses are by default relative to USD. That means rates.XAG is “troy ounces of XAG per 1 USD.” To get USD per troy ounce, invert: price_usd_per_oz = 1 / rates.XAG.
- Unit: responses include unit: "per troy ounce" so you can confirm measurement; treat this as the invariance check in your data model.
Endpoint 1: Latest Rates (XAG) — get the real-time quote
Purpose
Fetch the latest silver rate relative to the base currency. For most users, this drives live pricing widgets, alerting rules, and ERP cost updates.
Key parameters
- access_key: your API key.
- symbols: set to XAG (limit the payload and reduce parsing time).
- Optional base: defaults to USD. Keep USD unless you know you need a different base for your accounting currency.
Sample curl request
curl -s "https://metals-api.com/api/latest?access_key=YOUR_API_KEY&symbols=XAG&base=USD"
Sample JSON response (success)
{
"success": true,
"timestamp": 1790036269,
"base": "USD",
"date": "2026-09-22",
"rates": {
"XAG": 0.03815
},
"unit": "per troy ounce"
}
How to read it
- timestamp: Unix epoch seconds for the quote. Store it alongside your computed price for audits.
- base: "USD" confirms the base currency for the rate.
- rates.XAG: 0.03815 means 1 USD buys 0.03815 troy ounces of silver.
- price USD/oz: compute 1 / 0.03815 ≈ 26.21 USD per troy ounce.
- unit: “per troy ounce” confirms the measure. Retain this to sanity-check downstream units.
Python requests example: get XAG per oz and per gram
import os
import requests
API_KEY = os.getenv("METALS_API_KEY", "YOUR_API_KEY")
BASE_URL = "https://metals-api.com/api"
def get_latest_xag():
url = f"{BASE_URL}/latest"
params = {
"access_key": API_KEY,
"symbols": "XAG",
"base": "USD"
}
r = requests.get(url, params=params, timeout=10)
r.raise_for_status()
data = r.json()
if not data.get("success"):
# Surface API-side error detail if provided
raise RuntimeError(f"Metals-API error: {data}")
rate_xag_per_usd = data["rates"]["XAG"] # troy ounces per 1 USD
usd_per_oz = 1.0 / rate_xag_per_usd
TROY_OUNCE_TO_GRAMS = 31.1034768
usd_per_gram = usd_per_oz / TROY_OUNCE_TO_GRAMS
return {
"timestamp": data["timestamp"],
"date": data["date"],
"usd_per_oz": usd_per_oz,
"usd_per_gram": usd_per_gram,
"unit": data.get("unit", "per troy ounce"),
"base": data["base"]
}
if __name__ == "__main__":
quote = get_latest_xag()
print(quote)
Beginner gotchas
- Invert the rate: rates.XAG is ounces per USD, not USD per ounce. Always invert for USD/oz.
- Timezones: timestamps are Unix epoch seconds; date is typically UTC-based. If your UI is local-time, convert appropriately.
- Weekend/holiday behavior: metals markets can be quiet or officially closed. Latest may advance slowly; add UI hints like “updated N minutes ago.”
- Caching: cache the latest response for a few seconds to a few minutes, depending on your plan’s update interval, to reduce API calls and jitter.
Endpoint 2: Bid/Ask for XAG — add spread-aware intelligence
Purpose
Retrieve executable bid and ask quotes for XAG to model transaction costs, dynamic e-commerce margins, and liquidity-aware triggers. For retail pricing, you might mark up from the ask; for liquidation workflows, discount from bid; for mid-price analytics, take (bid+ask)/2.
Key parameters
- access_key
- symbols: XAG
- Optional base: USD unless you need a different base currency context
Sample curl request
curl -s "https://metals-api.com/api/bid-ask?access_key=YOUR_API_KEY&symbols=XAG&base=USD"
Sample JSON response (success)
{
"success": true,
"timestamp": 1790036269,
"base": "USD",
"date": "2026-09-22",
"rates": {
"XAG": {
"bid": 0.0381,
"ask": 0.0382,
"spread": 0.0001
}
},
"unit": "per troy ounce"
}
How to use it
- Each of bid/ask is expressed in troy ounces per 1 USD. Invert to get USD/oz.
- Mid-price in USD/oz = 1 / (avg of bid and ask). Or compute mid in ounces per USD, then invert once.
- Spread: 0.0001 ounces per USD. You can convert this to USD by translating to USD/oz at either side.
Example calculations
- USD per oz at the ask = 1 / 0.0382 ≈ 26.18.
- USD per oz at the bid = 1 / 0.0381 ≈ 26.25.
- Mid USD per oz ≈ (26.18 + 26.25) / 2 ≈ 26.215.
Production tips
- Quote staleness: display timestamp and auto-refresh if older than your SLA threshold.
- Ratcheting: for customer-facing UIs during high volatility, consider sticky ask for N seconds to avoid visible price flicker.
- Risk controls: enforce min/max spreads acceptable for checkout or execution; pause if spreads exceed tolerance.
Endpoint 3: Time-series for XAG — daily history for models and backfills
Purpose
Pull a date range of daily rates to compute trend signals, moving averages, or to backfill analytics. This is ideal for dashboards, alerts (e.g., “7-day momentum crossed zero”), and research notebooks that combine silver with macro indicators and factory utilization.
Key parameters
- access_key
- start_date, end_date: YYYY-MM-DD
- base: default USD
- symbols: XAG
Sample curl request
curl -s "https://metals-api.com/api/timeseries?access_key=YOUR_API_KEY&start_date=2026-09-15&end_date=2026-09-22&base=USD&symbols=XAG"
Sample JSON response (success)
{
"success": true,
"timeseries": true,
"start_date": "2026-09-15",
"end_date": "2026-09-22",
"base": "USD",
"rates": {
"2026-09-15": { "XAG": 0.03825 },
"2026-09-17": { "XAG": 0.03820 },
"2026-09-22": { "XAG": 0.03815 }
},
"unit": "per troy ounce"
}
Interpreting the series
- Gaps: some calendar days may be absent due to weekends/holidays. Your code should not assume contiguous daily keys.
- Rates are ounces per USD; invert day-by-day for USD per ounce prior to analytics.
- Derived indicators: compute rolling averages, day-over-day percent changes, or feed the series to anomaly detectors.
Practical example: moving average for factory re-order thresholds
Many operations teams prefer a rolling 7- or 14-day average to dampen noise before updating vendor orders or BOM cost locks. Compute USD/oz for each day, then average. Use the latest rate to compare against the moving average for momentum-aware purchasing.
Response fields you will actually use
- success: boolean guard before computing; fail fast if false.
- timestamp: canonical time for the quote. Store it; display “as of” in UIs.
- date: ISO date; useful for daily series charts and labeling.
- base: confirms the currency for your rate calculations; usually “USD.”
- rates.XAG: the core numeric payload (ounces per USD). Always invert to get USD/oz if you price in dollars.
- unit: “per troy ounce.” Use this for assertions to prevent silently mixing units.
Units and conversions: troy ounces vs grams
- Metals-API unit: per troy ounce (31.1034768 grams).
- Convert USD/oz to USD/g: divide by 31.1034768.
- Convert to kilograms: multiply grams by 1000. Example: USD/kg = USD/g × 1000.
- Document your unit pipeline. Store both USD/oz and USD/g if different teams need different measures.
Caching, performance, and quotas
- Client-side caching: cache latest and bid/ask responses for a duration aligned with your plan’s update interval. For example, if updates are every 10 minutes, cache for 30–60 seconds in UI layers and a few minutes in server layers to buffer bursts.
- Server aggregation: consolidate requests across services via a small internal pricing service that caches Metals-API responses and fans out internally.
- Retry with backoff: implement exponential backoff on transient network errors; avoid tight loops that waste calls.
- E-tags or conditional fetches: if you proxy behind your own service, add conditional GET logic to cut bandwidth and latency between internal services.
Handling weekends and market closures
- Expect slower or flat updates when markets are closed. Don’t alert repeatedly on unchanged prices.
- In timeseries, dates may skip weekends. Use a trading calendar abstraction in your analytics code.
- On UI, show an “as of” timestamp and a subtle “Market closed” or “Delayed” badge when staleness exceeds threshold.
Security and reliability best practices
- Key management: store access_key in your secret manager or environment variables. Never hardcode in client-side code that ships to browsers.
- Transport: always use HTTPS. Avoid proxies that strip TLS.
- Least privilege: isolate the key to the service that needs it; rotate keys on schedule and on incidents.
- Input validation: validate symbols (XAG) against a local allowlist from the Supported Symbols endpoint to prevent injection of unexpected inputs.
- Observability: log success flags, timestamps, and latencies. Add alerts for sequences of failed calls or staleness beyond SLA.
Architectural patterns for scaling XAG pricing
- Central price service: a microservice that fetches from Metals-API, normalizes units, caches results, and exposes an internal JSON endpoint for downstream apps (checkout, dashboards, risk).
- Event-driven updates: on new quotes, publish to a message bus (e.g., Kafka) so consumer services react without polling.
- Immutable storage: store raw responses for compliance and analytics replay. Derive features (USD/oz, USD/g) in a separate model table.
- High-availability: run active/active instances of your price service behind a load balancer; pre-warm caches at startup.
Applying silver data in smart manufacturing and fintech
- Electronics and solar: convert USD/oz to USD/g to cost printed circuit board (PCB) trace plating and solar cell metallization layers, then automate re-order pricing with moving averages plus a spread buffer.
- Jewelry pricing: compute retail prices using ask-derived USD/oz, add labor and design factors, and enforce minimum gross margins with spread-aware floors.
- Risk dashboards: feed real-time USD/oz and rolling vol into VaR and stress tests; trigger hedges when price deviates from the 20-day average.
- Supply chain tech: integrate with ERP to reprice supplier contracts when USD/oz breaches thresholds, with automatic notifications to purchasing teams.
- Digital market analysis: combine XAG time-series with macro indicators to train signals that predict procurement windows or promotional timing.
Error handling and resilience
- Check success: always gate your logic on success == true. If false, log and surface actionable error detail to SRE/DevOps.
- HTTP errors: treat 4xx as non-retriable (fix input or key); 5xx as retriable with backoff.
- Fallbacks: if latest fails, use the most recent cached value tagged as stale, and notify stakeholders.
- Data sanity: assert unit == "per troy ounce" and base == "USD" to prevent subtle downstream errors.
Putting it all together: a minimal pipeline for XAG
- Fetch latest XAG (symbols=XAG, base=USD). Invert to USD/oz; compute USD/g.
- Fetch bid/ask for XAG to get spread-aware prices. Derive mid or choose ask/bid based on your use case (buying vs selling).
- Backfill with timeseries (daily) to compute rolling averages and volatility estimates.
- Cache results for short durations to smooth load and respect plan update cadence.
- Expose a normalized internal endpoint or message with USD/oz, USD/g, bid/ask-derived metrics, and timestamps.
- Instrument with logs and alerts; store raw JSON for audit.
Additional examples and variations
Latest with only XAG (narrow payload)
{
"success": true,
"timestamp": 1790036269,
"base": "USD",
"date": "2026-09-22",
"rates": {
"XAG": 0.03815
},
"unit": "per troy ounce"
}
Bid/Ask with mid-price calculation note
{
"success": true,
"timestamp": 1790036269,
"base": "USD",
"date": "2026-09-22",
"rates": {
"XAG": {
"bid": 0.0381,
"ask": 0.0382,
"spread": 0.0001
}
},
"unit": "per troy ounce"
}
Compute USD/oz mid as the inverse of the average of bid and ask (in ounces per USD).
Time-series (sparse dates) with gaps
{
"success": true,
"timeseries": true,
"start_date": "2026-09-15",
"end_date": "2026-09-22",
"base": "USD",
"rates": {
"2026-09-15": { "XAG": 0.03825 },
"2026-09-17": { "XAG": 0.03820 },
"2026-09-22": { "XAG": 0.03815 }
},
"unit": "per troy ounce"
}
Algorithmic note: treat missing days as market closures; don’t forward-fill blindly for signal generation unless you mark the data as “no trade.”
Validation checklist before go-live
- Symbol correctness: only XAG used; verified via Supported Symbols.
- Units: assert unit == "per troy ounce" on each response.
- Base currency: ensure base == "USD" if you price in dollars; otherwise, configure your base to match accounting.
- Inversion: consistently convert ounces per USD to USD per ounce before displaying or storing derived values.
- Staleness: time-delta between now and timestamp is within your SLA; otherwise, label stale and refresh.
- Caching: applied at edge or service tier; throttle UI refresh cadence to user needs.
Monitoring and alerting
- Availability: alert on consecutive failed requests or elevated latency.
- Data drifts: alert when spreads expand beyond historical percentiles (could indicate market stress).
- Versioning: track library and API parameter changes; test new params in staging.
- Integrity: periodic assertions on unit/base and anomaly detection on price jumps.
Extending beyond the basics
- OHLC bars: if you need open/high/low/close for XAG, consult the Metals-API Documentation for the OHLC endpoint format and plan availability.
- Currency conversion: if your business prices in EUR or GBP, use the Convert endpoint as documented to transform USD-based results to your home currency.
- Quant signals: combine XAG daily series with macro datasets (e.g., industrial production or PMI) to improve procurement timing. For general reference on macro indicators, central bank and statistical agency sites provide official series.
Frequently asked questions
What is the exact measurement unit returned by Metals-API for XAG?
The unit is “per troy ounce.” That means rates.XAG is troy ounces of silver you get per one unit of the base currency (USD by default). Invert the rate to get USD per troy ounce, and then convert to grams if needed.
Why is my computed USD/oz different from what I see on news sites?
Two common reasons: (1) You might be forgetting to invert the rate (rates.XAG is ounces per USD). (2) Some sites display futures or different quote composites. Ensure your reference is spot-like silver and compare at the same timestamp.
How often is the “latest” updated?
Update frequency depends on your subscription plan. Cache responses sensibly and design UIs that communicate when the last update occurred. Consult the plan details on the Metals-API Website.
How do I handle weekends and holidays?
Expect fewer or no updates; the time-series endpoint may omit those dates. In analytics, avoid assuming a data point exists for every calendar day. In UIs, show “as of” timestamps and explain market closures in tooltips.
Can I price in euros or another currency?
Yes. Metals-API supports multiple base currencies and conversions. See the Metals-API Documentation for conversion usage and parameters.
What’s the best way to minimize API usage across many services?
Create a small internal pricing service that fetches and caches XAG from Metals-API, then serve your downstream apps from that cache. Add short TTLs aligned with your update cadence.
Is bid/ask necessary for retail pricing?
It’s highly recommended. Using the ask to price purchases (or the bid to value inventory liquidation) helps you account for execution costs and protect margins.
How do I get started?
Grab your free API key and review supported symbols. Then try the curl examples above with XAG:
- Get a key: Get a free Metals-API key
- Confirm the XAG code: See Supported Symbols
- Read the details: Explore the Documentation
Conclusion
With three endpoints—Latest, Bid/Ask, and Time-series—you can stand up a robust, real-time silver (XAG) feed that serves trading tools, smart manufacturing, jewelry pricing, and research. The core workflow is straightforward: request XAG with base USD, invert to USD/oz, convert to USD/g if needed, and cache aggressively. Add bid/ask to become spread-aware, use the time-series to compute trends, and build a small internal service to fan out normalized pricing to the rest of your stack. When you’re ready to extend into conversions or OHLC bars, the Metals-API Documentation covers the next steps. Start now by getting your API key on the Metals-API Website and verifying XAG on the Supported Symbols page.