Patna Silver (PATN-XAG) - Per Gram Price API in Multiple Currencies: USD and EUR examples

Metals-API 12 min read
Patna Silver   (PATN-XAG) - Per Gram Price API in Multiple Currencies: USD and EUR examples

Your team needs a reliable per-gram price for Patna Silver in USD and EUR, suitable for pricing, quoting, or marking-to-market inside your app. By the end of this guide, you will: 1) understand how the PATN-XAG city symbol is restricted, 2) fetch real-time Silver (XAG) with Metals-API, 3) convert troy ounces to grams, 4) produce USD and EUR per-gram outputs, and 5) handle caching, market-closure, and base-currency nuances correctly.

What “PATN-XAG” unlocks, and the restriction you must handle first

PATN-XAG identifies a city-specific silver price for Patna. When you try to use PATN-XAG directly on the generic /latest endpoint, the API enforces a routing rule: Indian city symbols are restricted to a specialized endpoint. If you miss this, your integration will fail on day one.

Illustration: Patna Silver (PATN-XAG) - Per Gram Price API in Multiple Currencies: USD and EUR examples

Here’s the exact error envelope you will see when calling /api/latest with PATN-XAG:

{"success":false,"error":{"code":403,"type":"restricted_symbols","info":"The specified symbols are restricted to the gold-price-india endpoint only.","restricted_symbols":["PATN-XAG"],"endpoint_required":"\/api\/gold-price-india","message":"Indian gold city symbols can only be used with the \/api\/gold-price-india endpoint."}}

What this means for your build:

  • You cannot use PATN-XAG on /api/latest. The response will be a 403 error with the guidance above.
  • If you need a city-level Indian quote, route calls to the endpoint shown in endpoint_required. Keep business logic for city quotations separate from your generic metals feed logic.
  • If your use case is to compute a global silver reference per gram (USD/EUR) for Patna workflows, you can use standard Silver (XAG) from /api/latest and then apply your own city premiums, taxes, or logistics adjustments upstream.

For the symbol taxonomy and discoverability across metals and currencies, refer to the catalog at Metals-API Supported Symbols. For deeper integration mechanics, see the Metals-API Documentation.

Plan: compute per-gram price for Silver (XAG) in USD and EUR

City symbols aside, most systems that need “Patna Silver per gram in USD/EUR” can proceed with a clear, auditable pipeline:

  1. Fetch Silver (XAG) from /api/latest. Note: base is USD by default and unit is per troy ounce in Metals-API.
  2. Invert the XAG rate to obtain USD per troy ounce. With base=USD, rates.XAG gives ounces per 1 USD; invert to get USD/oz.
  3. Convert from troy ounces to grams (1 troy ounce = 31.1034768 grams).
  4. For EUR per gram, convert the USD price to EUR via your FX logic. You can do this with Metals-API’s conversion capabilities if your plan includes the required currencies. Keep currency logic explicit and cached to minimize calls.

This produces a reference-grade per-gram price you can use in Patna workflows, while keeping the city-specific logic (e.g., local premiums) in your domain layer. When you do need a city symbol like PATN-XAG, switch to the mandated endpoint noted in the error envelope.

Latest XAG: curl request and what to read from the response

Use the latest endpoint to retrieve Silver (XAG). Below is a copy-pasteable call scoped to XAG:

curl "https://metals-api.com/api/latest?access_key=YOUR_API_KEY&symbols=XAG"

If you mistakenly include PATN-XAG on /latest, you will get the restriction error above. The fix is to either call the endpoint specified by endpoint_required for city quotes, or omit PATN-XAG and fetch standard XAG for your reference price pipeline.

Here is the official sample shape of a successful latest response where XAG is present among other metals. You will use the base, timestamp, unit, and the rates.XAG field specifically:

{
"success": true,
"timestamp": 1792455005,
"base": "USD",
"date": "2026-10-20",
"rates": {
"XAU": 0.000482,
"XAG": 0.03815,
"XPT": 0.000912,
"XPD": 0.000744,
"XCU": 0.294118,
"XAL": 0.434783,
"XNI": 0.142857,
"XZN": 0.344828
},
"unit": "per troy ounce"
}

Fields you’ll actually read:

  • base: USD by default.
  • unit: per troy ounce. Your per-gram calculation must divide by 31.1034768 after you compute USD/oz.
  • rates.XAG: ounces per 1 USD when base=USD. Invert to get USD/oz. For example, USD_per_oz = 1 / rates.XAG.
  • timestamp and date: use for caching and staleness checks. Timestamps are Unix seconds.

From ounces to grams, and from USD to EUR

With base=USD, Metals-API returns XAG as oz per USD. Convert to USD per oz by inverting, then divide by 31.1034768 to get USD per gram.

  • USD_per_oz = 1.0 / rates.XAG
  • USD_per_gram = USD_per_oz / 31.1034768

For EUR per gram, either:

  • Convert USD_per_gram to EUR by multiplying by your USD→EUR rate from your FX source (can be Metals-API if your plan includes currency rates), or
  • Use the convert endpoint to work in EUR terms directly. For instance, you can convert a EUR amount to XAG and then invert to get EUR per oz, then divide by 31.1034768.

Note: Do not assume base=EUR is available to you; handle conversion explicitly so your math is auditable.

End-to-end code: handle PATN-XAG restriction, then compute USD and EUR per gram using XAG

This Python snippet demonstrates a robust flow:

  • First, attempt PATN-XAG on /latest (to show how to handle the restriction error).
  • Then fetch standard XAG and compute USD/gram.
  • Optionally call the convert endpoint to get EUR terms for your EUR/gram output.
import os
import math
import requests

API_BASE = "https://metals-api.com/api"
API_KEY = os.getenv("METALS_API_KEY", "YOUR_API_KEY")
TROY_OUNCE_TO_GRAMS = 31.1034768

def get_latest(symbols):
url = f"{API_BASE}/latest"
params = {
"access_key": API_KEY,
"symbols": symbols
}
r = requests.get(url, params=params, timeout=10)
r.raise_for_status()
return r.json()

def convert_amount(from_code, to_code, amount):
url = f"{API_BASE}/convert"
params = {
"access_key": API_KEY,
"from": from_code,
"to": to_code,
"amount": amount
}
r = requests.get(url, params=params, timeout=10)
r.raise_for_status()
return r.json()

def compute_usd_per_gram_from_latest_xag(latest_json):
# With base=USD and unit=per troy ounce, rates.XAG is oz per 1 USD.
xag_per_usd = latest_json["rates"]["XAG"]
usd_per_oz = 1.0 / xag_per_usd
usd_per_gram = usd_per_oz / TROY_OUNCE_TO_GRAMS
return usd_per_oz, usd_per_gram

def eur_per_gram_via_convert():
# One approach: Convert 1 EUR to XAG, then invert to get EUR per oz, then per gram.
j = convert_amount("EUR", "XAG", 1.0)
# j["result"] is the amount of XAG per 1 EUR (per the sample schema)
xag_per_eur = j["result"]
eur_per_oz = 1.0 / xag_per_eur
eur_per_gram = eur_per_oz / TROY_OUNCE_TO_GRAMS
return eur_per_oz, eur_per_gram, j

def main():
# 1) Demonstrate handling the PATN-XAG restriction on /latest.
try:
patna_try = get_latest("PATN-XAG")
if not patna_try.get("success", False):
err = patna_try.get("error", {})
print("PATN-XAG restricted response:", err)
except requests.HTTPError as e:
print("HTTP error on PATN-XAG latest:", e)

# 2) Fetch standard XAG for reference pricing.
latest_xag = get_latest("XAG")
if not latest_xag.get("success", False):
raise RuntimeError(f"Latest XAG failed: {latest_xag}")

usd_per_oz, usd_per_gram = compute_usd_per_gram_from_latest_xag(latest_xag)
print("USD/oz (XAG):", usd_per_oz)
print("USD/gram (XAG):", usd_per_gram)

# 3) Optional: produce EUR/gram using /convert and the same inversion logic.
try:
eur_per_oz, eur_per_gram, convert_raw = eur_per_gram_via_convert()
print("EUR/oz (XAG):", eur_per_oz)
print("EUR/gram (XAG):", eur_per_gram)
# For auditability, you may log convert_raw["info"]["timestamp"] and convert_raw["info"]["rate"]
except requests.HTTPError as e:
print("HTTP error during EUR convert:", e)

if __name__ == "__main__":
main()

Notes for production:

  • Cache latest responses keyed by timestamp to minimize calls and stabilize UIs.
  • Store both oz and gram prices to avoid repeated conversions in hot paths.
  • Keep city-specific workflows (like PATN-XAG) isolated: they may require different endpoints and can carry local adjustments.

EUR example via the Convert endpoint

When you want a EUR-based per-gram price without assuming an EUR base feed, a practical pattern is to use /convert to work in EUR terms and then apply the ounce-to-gram math. The general-purpose call looks like:

curl "https://metals-api.com/api/convert?access_key=YOUR_API_KEY&from=EUR&to=XAG&amount=1"

From the sample schema, the convert response includes:

  • query.from/query.to/query.amount
  • info.timestamp and info.rate
  • result and unit (“troy ounces” for metals)

Interpretation for EUR/gram:

  • result gives XAG per 1 EUR. Invert to get EUR per troy ounce.
  • Divide by 31.1034768 to get EUR per gram.

If you’re converting larger cart sizes (e.g., 250 g or 1 kg), do the gram math first, then multiply by grams. This is numerically stable and avoids repeating conversions.

Optional: monitoring daily change (fluctuation or OHLC) for supply chain alerts

If you’re building daily alerts for procurement or scheduling production jobs when Silver is favorable, consider pairing your per-gram pipeline with a simple daily change query. The API provides time-windowed deltas (fluctuation) and OHLC views. Here is an official sample for fluctuation (note: XAG included):

{
"success": true,
"fluctuation": true,
"start_date": "2026-10-13",
"end_date": "2026-10-20",
"base": "USD",
"rates": {
"XAU": {
"start_rate": 0.000485,
"end_rate": 0.000482,
"change": -3.0e-6,
"change_pct": -0.62
},
"XAG": {
"start_rate": 0.03825,
"end_rate": 0.03815,
"change": -0.0001,
"change_pct": -0.26
},
"XPT": {
"start_rate": 0.000915,
"end_rate": 0.000912,
"change": -3.0e-6,
"change_pct": -0.33
}
},
"unit": "per troy ounce"
}

When base=USD, change and change_pct are expressed on the “oz per USD” side. If your alerts are calibrated to USD/gram, remember to invert consistently before computing thresholds.

For endpoint details beyond the scope of this article, see the Metals-API Documentation.

Practical considerations that save time in production

1) Units: troy ounces vs grams

  • All metal units are per troy ounce in Metals-API responses noted here.
  • 1 troy ounce = 31.1034768 grams. Use a precise constant and centralize it.
  • When base=USD, rates.XAG is “oz per USD.” Invert to USD per oz before gram math.

2) Base currency is USD by default

  • With base=USD, all metals in rates are quoted as metal units per 1 USD.
  • To produce a fiat price per gram, invert first (USD/oz) then convert units.
  • For EUR per gram, use the convert endpoint or your own FX source, then mirror the same unit math.

3) Timestamps, timezone, and weekend/holiday behavior

  • timestamp is Unix seconds. Persist it alongside computed prices so downstream services know freshness.
  • If you call during weekends or market closures, expect fewer updates; cache accordingly and surface a “last updated” label in UI.
  • Avoid hammering the API during stale windows—serve cached responses until a new timestamp appears.

4) Caching and retries

  • Cache latest by timestamp and symbols set. On equal timestamps, return cached conversions (USD/gram, EUR/gram) to save calls.
  • Back off and retry only on transient errors. For 403 with restricted_symbols (as above), reroute instead of retrying.
  • Consider a small time-to-live for EUR conversions to limit convert calls.

5) City-level routing and auditing

  • PATN-XAG is a city symbol restricted to a dedicated endpoint. Keep that logic behind a feature flag or service boundary.
  • Log the exact endpoint and parameters used to fetch each price. Attach the timestamp and unit to every computed value (USD/oz, USD/g, EUR/g) for audit trails.

Why Silver (XAG) reference data matters for manufacturing and fintech in Patna

Silver sits at the center of modern manufacturing and smart supply chains. From high-conductivity electronics to photovoltaics and antimicrobial uses in medical devices, volatility in XAG can ripple through Bills of Materials and job costing. A consistent per-gram reference price simplifies:

  • Dynamic SKU pricing in jewelry catalogs.
  • Job-shop costing in smart manufacturing MES/ERP integrations.
  • Hedging analysis and alerting in quant and commodities tools.
  • Backtesting and procurement timing in data science notebooks.

By separating “global XAG reference” from “city adjustments,” developers can test models quickly, deploy with confidence, and add localized layers (e.g., PATN-XAG via the required endpoint) when needed.

One more thing: bid/ask and OHLC when modeling spreads

If your application needs microstructure details (e.g., to show indicative spreads around reference prices), the API also covers bid/ask and OHLC. Here is an official OHLC sample that includes XAG:

{
"success": true,
"timestamp": 1792455005,
"base": "USD",
"date": "2026-10-20",
"rates": {
"XAU": {
"open": 0.000485,
"high": 0.000487,
"low": 0.000481,
"close": 0.000482
},
"XAG": {
"open": 0.03825,
"high": 0.0383,
"low": 0.0381,
"close": 0.03815
},
"XPT": {
"open": 0.000915,
"high": 0.000918,
"low": 0.00091,
"close": 0.000912
}
},
"unit": "per troy ounce"
}

If you compute USD/gram from OHLC values, invert consistently at each step: open/close/high/low are still “oz per USD” with base=USD. This helps you derive session VWAP-like indicators or display candle charts per gram.

Complete, copy-pasteable curl for PATN-XAG (showing the restriction) and for XAG

To surface the PATN-XAG routing rule in your logs during development:

curl "https://metals-api.com/api/latest?access_key=YOUR_API_KEY&symbols=PATN-XAG"

Use standard XAG for your per-gram reference feed:

curl "https://metals-api.com/api/latest?access_key=YOUR_API_KEY&symbols=XAG"

For conversions in EUR terms without assuming an EUR base feed:

curl "https://metals-api.com/api/convert?access_key=YOUR_API_KEY&from=EUR&to=XAG&amount=1"

Explore all supported symbols and currency/metals codes on the Symbols page. For full parameter options and additional endpoints, see the Documentation.

Quick reference: unit conversion and inversion

  • Given base=USD and unit=per troy ounce:
    • rates.XAG = oz per 1 USD.
    • USD per oz = 1 / rates.XAG.
    • USD per gram = (1 / rates.XAG) / 31.1034768.
  • For EUR per gram:
    • Either multiply USD per gram by USD→EUR, or
    • Use /convert with from=EUR,to=XAG, invert to EUR/oz, then divide by 31.1034768.

Security, performance, and integration hygiene

  • Do not hardcode API keys. Use environment variables and secrets managers.
  • Sanitize and log error envelopes. For restricted symbols, respect endpoint_required rather than retrying.
  • Apply exponential backoff only on transient network failures.
  • Cache results keyed by (symbol, timestamp). Publish a “last updated” indicator to UIs or downstream services.
  • Document your inversion math in code comments to avoid regressions when adding new currencies or units.

Where this lands in modern manufacturing and digital market analysis

Silver’s role in electronics, renewable energy, and precision components means small changes in XAG ripple through MRP, ERP, and e-commerce pricing. An automated USD/EUR per-gram pipeline lets you:

  • Reprice catalogs in near-real time without manual spreadsheet steps.
  • Backfill historical charts and trigger alerts when materials cross internal thresholds.
  • Run cost simulations against BOMs during quoting to identify sensitivity to Silver moves.

When a Patna-specific view is required, incorporate the city endpoint mandated in the error envelope and blend any localized adjustments in your pricing layer, but keep the XAG reference pipeline unchanged and well-tested.

FAQ

Q: Why does PATN-XAG fail on /api/latest?
A: City-level Indian symbols are restricted to a dedicated endpoint. The /api/latest call returns a 403 with endpoint_required set to /api/gold-price-india. Use that endpoint for city quotes and use standard XAG for global per-gram references.

Q: Is rates.XAG a price?
A: With base=USD, rates.XAG is ounces of Silver per 1 USD, not a direct USD price. Invert it to get USD per troy ounce, then divide by 31.1034768 for USD per gram.

Q: How do I get EUR per gram without switching the API base?
A: Use the /convert endpoint (e.g., from=EUR,to=XAG,amount=1), invert the result to get EUR per troy ounce, then divide by 31.1034768 for EUR per gram. Cache the conversion to reduce request volume.

Q: What timezone is the timestamp in the response?
A: The timestamp is a Unix epoch (seconds since 1970-01-01 UTC). Use it for staleness checks and cache invalidation.

Q: How should I handle weekends or holidays?
A: Expect fewer or no updates during closures. Serve cached data until a new timestamp arrives. Surface a “last updated” label and avoid aggressive retries during known closures.

Get an API key and start prototyping your Patna Silver per-gram pipeline today. Register at Metals-API Register, explore the Metals-API MCP, and keep the Documentation open as you wire in latest, convert, and your unit conversions.