Get the Gold Price per Gram in Python (24K, 22K, 18K)
Fetch gold prices per gram in Python without an API key, then calculate 24K, 22K, and 18K values safely with Decimal across 31 currencies.
Read →A complete, production-ready Python script that polls the live spot price, checks it against a threshold, and sends a notification. Uses the REST API with retry logic and a local TTL cache.
This tutorial builds a standalone Python script that polls the live gold spot price and fires an alert when a threshold is crossed. It:
No SDKs required—only the standard library plus requests.
pip install requestsThe spot endpoint returns the current price along with source metadata:
import requests
API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.goldprice.dev/v1"
def fetch_spot_price() -> float:
"""Return the current XAU-USD spot price in USD per troy ounce."""
resp = requests.get(
f"{BASE_URL}/prices",
params={"symbol": "XAU-USD-SPOT", "include": "sources"},
headers={"Authorization": f"Bearer {API_KEY}"},
timeout=10,
)
resp.raise_for_status()
data = resp.json()
# include=sources adds the sources[] array. Use the first live spot source.
for source in data.get("sources", []):
if source.get("type") == "spot" and not source.get("stale", True):
return float(source["price"])
raise ValueError("No live spot price in response")
Requesting ?include=sources adds a sources[] array that lets you inspect the live spot source behind each price. If a source is flagged stale: true, skip it—the response may carry multiple sources and some may be delayed.
Polling every second against a REST endpoint is wasteful and burns quota. A simple in-memory cache with a configurable TTL is enough for most alert use cases:
import time
from typing import Optional
_cache: dict[str, tuple[float, float]] = {} # key -> (value, expiry)
def cached_spot_price(ttl_seconds: int = 60) -> float:
"""Return a cached spot price, refreshing only when TTL has elapsed."""
key = "XAU-USD-SPOT"
now = time.monotonic()
if key in _cache:
value, expiry = _cache[key]
if now < expiry:
return value
price = fetch_spot_price()
_cache[key] = (price, now + ttl_seconds)
return price
At 60-second TTL you use at most 1,440 calls per day. Free covers about 3.5 days of testing; Basic and up cover continuous polling. For a deeper look at cache strategy and rate-limit headers, see Caching gold prices and staying inside rate limits.
Network failures and rate-limit responses (HTTP 429) are transient. Wrap the fetch with exponential backoff:
import time
import requests
MAX_RETRIES = 4
BACKOFF_BASE = 2.0 # seconds
def fetch_spot_price_with_retry() -> float:
for attempt in range(MAX_RETRIES):
try:
return fetch_spot_price()
except requests.exceptions.HTTPError as exc:
if exc.response is not None and exc.response.status_code == 429:
wait = BACKOFF_BASE ** attempt
print(f"Rate limited. Retrying in {wait:.0f}s…")
time.sleep(wait)
else:
raise
except requests.exceptions.RequestException as exc:
wait = BACKOFF_BASE ** attempt
print(f"Request error: {exc}. Retrying in {wait:.0f}s…")
time.sleep(wait)
raise RuntimeError("Max retries exceeded fetching spot price")
Define thresholds and fire a notification. Here we use print as the notifier—swap in email, Slack, SMS, or any webhook:
def send_alert(message: str) -> None:
"""Replace this with your preferred notification channel."""
print(f"[ALERT] {message}")
def check_and_alert(
above: Optional[float] = None,
below: Optional[float] = None,
) -> None:
"""Fire an alert if the live price crosses either threshold."""
price = cached_spot_price(ttl_seconds=60)
print(f"XAU-USD spot: ${price:,.2f}")
if above is not None and price >= above:
send_alert(f"Gold crossed ABOVE ${above:,.0f} — current: ${price:,.2f}")
if below is not None and price <= below:
send_alert(f"Gold fell BELOW ${below:,.0f} — current: ${price:,.2f}")
Wire everything into a polling loop:
import time
def run_alert_loop(
above: Optional[float] = None,
below: Optional[float] = None,
poll_interval: int = 60,
) -> None:
"""
Poll forever, checking thresholds on each tick.
Args:
above: Fire when price >= this value (USD/oz). None = no upper alert.
below: Fire when price <= this value (USD/oz). None = no lower alert.
poll_interval: Seconds between checks (minimum 60 recommended).
"""
print(f"Starting gold alert. above={above}, below={below}, interval={poll_interval}s")
while True:
try:
check_and_alert(above=above, below=below)
except Exception as exc:
print(f"Error during check: {exc}")
time.sleep(poll_interval)
if __name__ == "__main__":
# Alert if gold goes above $3,500 or below $3,000
run_alert_loop(above=3500, below=3000, poll_interval=60)
Putting it all together in gold_alert.py:
"""
gold_alert.py — Poll the live gold spot price and fire threshold alerts.
Requires: pip install requests
"""
import time
from typing import Optional
import requests
API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.goldprice.dev/v1"
MAX_RETRIES = 4
BACKOFF_BASE = 2.0
_cache: dict[str, tuple[float, float]] = {}
def fetch_spot_price() -> float:
resp = requests.get(
f"{BASE_URL}/prices",
params={"symbol": "XAU-USD-SPOT", "include": "sources"},
headers={"Authorization": f"Bearer {API_KEY}"},
timeout=10,
)
resp.raise_for_status()
data = resp.json()
for source in data.get("sources", []):
if source.get("type") == "spot" and not source.get("stale", True):
return float(source["price"])
raise ValueError("No live spot price in response")
def fetch_spot_price_with_retry() -> float:
for attempt in range(MAX_RETRIES):
try:
return fetch_spot_price()
except requests.exceptions.HTTPError as exc:
if exc.response is not None and exc.response.status_code == 429:
wait = BACKOFF_BASE ** attempt
time.sleep(wait)
else:
raise
except requests.exceptions.RequestException:
time.sleep(BACKOFF_BASE ** attempt)
raise RuntimeError("Max retries exceeded")
def cached_spot_price(ttl_seconds: int = 60) -> float:
key = "XAU-USD-SPOT"
now = time.monotonic()
if key in _cache:
value, expiry = _cache[key]
if now < expiry:
return value
price = fetch_spot_price_with_retry()
_cache[key] = (price, now + ttl_seconds)
return price
def send_alert(message: str) -> None:
print(f"[ALERT] {message}")
def check_and_alert(
above: Optional[float] = None,
below: Optional[float] = None,
) -> None:
price = cached_spot_price(ttl_seconds=60)
print(f"XAU-USD spot: ${price:,.2f}")
if above is not None and price >= above:
send_alert(f"Gold crossed ABOVE ${above:,.0f} — current: ${price:,.2f}")
if below is not None and price <= below:
send_alert(f"Gold fell BELOW ${below:,.0f} — current: ${price:,.2f}")
def run_alert_loop(
above: Optional[float] = None,
below: Optional[float] = None,
poll_interval: int = 60,
) -> None:
print(f"Starting gold alert. above={above}, below={below}, interval={poll_interval}s")
while True:
try:
check_and_alert(above=above, below=below)
except Exception as exc:
print(f"Error: {exc}")
time.sleep(poll_interval)
if __name__ == "__main__":
run_alert_loop(above=3500, below=3000, poll_interval=60)
The send_alert function is the only thing you need to swap out. A few common patterns:
Slack webhook:
import requests as req
def send_alert(message: str) -> None:
req.post(
"https://hooks.slack.com/services/YOUR/WEBHOOK",
json={"text": message},
timeout=5,
)
Email via SMTP:
import smtplib
from email.message import EmailMessage
def send_alert(message: str) -> None:
msg = EmailMessage()
msg["Subject"] = "Gold Price Alert"
msg["From"] = "alerts@yourdomain.com"
msg["To"] = "you@yourdomain.com"
msg.set_content(message)
with smtplib.SMTP_SSL("smtp.yourdomain.com", 465) as s:
s.login("alerts@yourdomain.com", "YOUR_PASSWORD")
s.send_message(msg)
| Plan | Calls/month | At 60s poll | Days of coverage |
|---|---|---|---|
| Free | 5,000 | ~1,440/day | ~3.5 days (testing) |
| Basic | 100,000 | ~1,440/day | Full month |
| Plus | 300,000 | ~1,440/day | Full month |
| Pro | 1,000,000 | ~1,440/day | Full month |
For continuous 60-second polling, any paid plan is appropriate. Free tier is useful for testing the integration before upgrading. See the pricing page for plan details.
related guides
Fetch gold prices per gram in Python without an API key, then calculate 24K, 22K, and 18K values safely with Decimal across 31 currencies.
Read →Import a ready-to-use gold portfolio tracker into Google Sheets, update one live price cell, and calculate indicative value, cost, and change by holding.
Read →Learn how a live gold price chart combines spot quotes, OHLC bars, UTC timestamps, and controlled polling, with a working TypeScript SVG example.
Read →goldprice.dev
Live gold prices, historical OHLC, and multi-source aggregation — available via REST and SSE.