To show the gold price in Home Assistant, add a REST sensor that calls goldprice.dev at /v1/spot/XAU-USD-SPOT. Store your API key in secrets.yaml, poll every fifteen minutes, and derive a gram sensor locally. This uses about two thousand nine hundred calls monthly, within the Free plan's 5,000 calls. Free prices arrive fifteen minutes late.
Get your API key and store it
Get a free key at goldprice.dev/onboarding. No credit card is required. Open secrets.yaml in your Home Assistant configuration directory, creating it if needed. Add the entry below, replacing ga_live_... with your complete key. Keep Bearer and the space before the key.
You need access to your Home Assistant configuration files. On Home Assistant OS, you can use the File editor app. Keep the key in secrets.yaml when sharing your other configuration files.
goldprice_auth: "Bearer ga_live_..."Add the gold price REST sensor
Add this block to configuration.yaml. If you already have a rest: section, append the resource entry to its list instead of creating another section. Use spaces for indentation.
The sensor requests US dollars per troy ounce every fifteen minutes. That is ninety six scheduled calls daily, or about two thousand nine hundred monthly. Restarts and manual refreshes can add calls. The timestamp and stale flag become sensor attributes.
rest: - resource: "https://api.goldprice.dev/v1/spot/XAU-USD-SPOT" headers: Authorization: !secret goldprice_auth scan_interval: 900 sensor: - name: "Gold price USD ounce" unique_id: goldprice_usd_ounce value_template: "{{ value_json.price | float(none) }}" unit_of_measurement: "USD/oz" json_attributes: - computed_at - is_staleCalculate the price per gram
Append this block to configuration.yaml. If template: already exists, add the sensor to that section instead. A troy ounce contains 31.1035 g. The calculation divides the ounce price by that weight and rounds to two decimal places.
This sensor makes no API requests. It becomes unavailable when the ounce sensor has no numeric value or its is_stale attribute is not false. A delayed Free price is separate from the API's stale flag.
template: - sensor: - name: "Gold price USD gram" unique_id: goldprice_usd_gram unit_of_measurement: "USD/g" availability: >- {{ is_number(states('sensor.gold_price_usd_ounce')) and state_attr('sensor.gold_price_usd_ounce', 'is_stale') == false }} state: >- {{ ((states('sensor.gold_price_usd_ounce') | float(0)) / 31.1035) | round(2) }}Send a notification above your threshold
Append this separate automation goldprice: block to configuration.yaml. The label lets it sit alongside your existing automation section. Keep that existing section. Edit this automation in the configuration file.
Replace above with your chosen USD per troy ounce threshold. The example uses the sample response price. A crossing above the threshold creates a notification inside Home Assistant when is_stale is false. It does not require a phone notification service.
automation goldprice: - id: goldprice_above_threshold alias: "Gold price above threshold" triggers: - trigger: numeric_state entity_id: sensor.gold_price_usd_ounce above: 4023.54 conditions: - condition: template value_template: >- {{ state_attr('sensor.gold_price_usd_ounce', 'is_stale') == false }} actions: - action: persistent_notification.create data: title: "Gold price alert" message: >- Gold is {{ states('sensor.gold_price_usd_ounce') }} USD/oz. Price timestamp: {{ state_attr('sensor.gold_price_usd_ounce', 'computed_at') }}. notification_id: goldprice_above_threshold mode: singleCheck the configuration and display the prices
Run Home Assistant's configuration check, fix any errors, then restart. In Developer tools, States, find both sensors and inspect computed_at and is_stale. If an entity ID differs from the examples, update every reference to it in the YAML, check again, and restart.
To check the alert, temporarily set the ounce sensor below your threshold, then above it in Developer tools, States. Preserve its attributes with is_stale false. Check Home Assistant's notifications. These local test values are replaced by the next API poll.
Add both sensors to your dashboard. On Free, place a Markdown card beside the prices containing [goldprice.dev](https://goldprice.dev/docs/api-reference). This provides the required visible credit link.
Expected output
{ "symbol": "XAU", "quote_currency": "USD", "unit": "troy_ounce", "contract_type": "spot", "price": "4023.54", "is_stale": false, "computed_at": "2026-10-23T10:51:32.965761+00:00"}This is the API response shape. The API keeps price as a decimal string. Home Assistant converts it to the numeric ounce sensor state and stores computed_at and is_stale as attributes. Developer tools, States shows those fields and the calculated gram sensor.
Common errors
| Code | What you see | Fix |
|---|---|---|
| 401 | The sensor is unavailable and the logs show an authentication error | Replace the placeholder with your complete key in secrets.yaml. The secret must contain Bearer, a space, and the key. Keep Authorization: !secret goldprice_auth in the REST configuration. Restart after changing the secret. |
| 429 | The logs show that requests are rate limited | Check other applications using the same key and stop repeated manual refreshes. Read the Retry-After response header before retrying. Do not add a tight retry loop. Review shared usage against the limits on the pricing page. |
| N/A | The configuration check reports duplicate keys or invalid indentation | Merge the entries into your existing rest: and template: sections. Do not repeat those keys. Keep automation goldprice: at the top level. Use spaces, preserve list indentation, and run the configuration check again. |
| N/A | The ounce sensor works but the gram sensor is unavailable | Check the actual ounce entity ID and its is_stale attribute in Developer tools, States. Update references if the ID differs. The gram sensor deliberately stays unavailable when the ounce state is not numeric or the stale flag is not false. |
| N/A | The price is above the threshold but no notification appears | A numeric state trigger reacts to a crossing, rather than every poll above the threshold. Equality does not count as above. Check that the automation is enabled, the entity ID matches, and is_stale is false. Inspect the automation trace after a crossing. |
Going further
- Add a history graph for the ounce sensor
- Show the price timestamp beside your dashboard prices
- Replace the notification action with your configured phone notifier
- Switch the gold symbol to another supported currency and update both sensor units
- Display a warning when the stale flag is true