# Get the Gold Price per Gram in Python (24K, 22K, 18K)

If your application needs a gold price per gram, do not fetch a price per troy ounce and hide the conversion in presentation code. Request the per-gram purity ladder directly from the public [`/v1/carat` endpoint](/docs/carat).

One request returns 24K, 22K, 21K, 20K, 18K, 16K, 14K, and 10K metal values in the currency you choose. The endpoint is free to try and does not require an API key.

## Fetch the gold price per gram with Python

This example uses only the Python standard library. It requests the current values in euros and parses each price as `Decimal` so later money arithmetic does not introduce binary floating-point drift.

```python
import json
from decimal import Decimal
from urllib.error import HTTPError, URLError
from urllib.parse import urlencode
from urllib.request import Request, urlopen

BASE_URL = "https://api.goldprice.dev/v1/carat"


def gold_price_per_gram(currency: str = "EUR") -> dict[str, Decimal | str]:
    query = urlencode({"currency": currency.upper()})
    request = Request(
        f"{BASE_URL}?{query}",
        headers={"Accept": "application/json"},
    )

    try:
        with urlopen(request, timeout=10) as response:
            payload = json.load(response)
    except HTTPError as error:
        raise RuntimeError(f"Gold API returned HTTP {error.code}") from error
    except URLError as error:
        raise RuntimeError(f"Could not reach the Gold API: {error.reason}") from error

    return {
        "currency": payload["currency"],
        "timestamp": payload["timestamp"],
        "24k": Decimal(payload["price_gram_24k"]),
        "22k": Decimal(payload["price_gram_22k"]),
        "18k": Decimal(payload["price_gram_18k"]),
        "14k": Decimal(payload["price_gram_14k"]),
    }


prices = gold_price_per_gram("EUR")
print(f'24K: {prices["24k"]} {prices["currency"]}/g')
print(f'22K: {prices["22k"]} {prices["currency"]}/g')
print(f'18K: {prices["18k"]} {prices["currency"]}/g')
print(f'Observed: {prices["timestamp"]}')
```

Change `EUR` to any supported three-letter currency code, such as `USD`, `GBP`, `INR`, `IDR`, `AED`, or `JPY`. The same request shape works across the full 31-currency catalog.

## Understand the response

The response contains one price field for each supported purity:

```json
{
  "currency": "EUR",
  "timestamp": "2026-09-22T08:30:00Z",
  "price_gram_24k": "120.16",
  "price_gram_22k": "110.14",
  "price_gram_21k": "105.14",
  "price_gram_20k": "100.13",
  "price_gram_18k": "90.12",
  "price_gram_16k": "80.11",
  "price_gram_14k": "70.09",
  "price_gram_10k": "50.07"
}
```

The numbers above illustrate the response shape; fetch the endpoint for current values. Price fields are JSON strings on purpose. Read them with `Decimal`, not `float`, when you multiply by weights or store monetary results.

The endpoint name uses `carat`, while the response uses labels such as `24k` and `18k`. Both spellings appear in gold markets, but **karat** is the usual term for gold purity and **carat** is also used in some countries.

## Calculate the value of a gold item

To estimate the metal value of a 12.5 gram, 18K item, multiply the returned 18K per-gram price by its weight:

```python
from decimal import Decimal, ROUND_HALF_UP

weight_grams = Decimal("12.5")
metal_value = (weight_grams * prices["18k"]).quantize(
    Decimal("0.01"),
    rounding=ROUND_HALF_UP,
)

print(f"Indicative metal value: {metal_value} {prices['currency']}")
```

The endpoint already expresses each per-gram value at the requested currency's minor-unit precision. Keep that value as `Decimal` and round the final item value once. If a large-weight calculation needs sub-minor-unit precision per gram, start from the ounce price and apply the conversion formula before the final rounding step.

This result is the spot-derived value of the gold content. It is not automatically the retail price or the cash amount a buyer will offer. Jewellery making charges, gemstones, taxes, dealer premiums, refining costs, and buyback discounts are separate.

## How the API converts spot gold to grams and karats

The calculation has three steps:

1. Convert the current XAU price into the requested currency.
2. Divide the per-troy-ounce value by exactly `31.1034768` grams.
3. Multiply by the purity fraction, such as `22 / 24` for 22K or `18 / 24` for 18K.

In compact form:

```text
price per gram by karat
= gold price per troy ounce in the chosen currency
  / 31.1034768
  * karat / 24
```

Calling `/v1/carat` keeps this conversion in one documented boundary. Your application receives the purity ladder from one observation instead of repeating unit and purity arithmetic in every client.

## Add an API key when the application grows

The first request does not need a key. That is useful for a local script, prototype, or one-off spreadsheet refresh. For a deployed application, create a [free account](/signup) and send the key from your server so usage belongs to your account rather than a shared anonymous limit.

```python
import os

api_key = os.environ["GOLDPRICE_API_KEY"]
request = Request(
    f"{BASE_URL}?{urlencode({'currency': 'EUR'})}",
    headers={
        "Accept": "application/json",
        "Authorization": f"Bearer {api_key}",
    },
)
```

Never put an account key in browser JavaScript or commit it to source control. Keep it in a server-side environment variable and handle non-2xx responses before reading the body as a successful price.

## Production checklist

- Keep prices as `Decimal` through the calculation.
- Store the returned `timestamp` with the value.
- Cache successful responses for the freshness your feature actually needs.
- Do not replace a failed refresh with zero or a new timestamp.
- Label the result as indicative, not a dealing or settlement quote.
- Separate metal value from taxes, making charges, premiums, and buyback deductions.

For the complete field contract, see the [karat gold price API documentation](/docs/carat). If you need daily OHLC history instead of a current per-gram value, use the [historical gold price API](/docs/historical).
