To get a gold price in Ruby, call https://api.goldprice.dev/v1/spot/XAU-USD-SPOT with Net::HTTP and your goldprice.dev API key. The client below uses only Ruby’s standard library. It keeps prices as BigDecimal, caches each successful response for sixty seconds, honours Retry-After on rate limits, and raises if the API marks the price as stale.
Set your API key
Get a free key at goldprice.dev/onboarding. No credit card is needed. Run these commands, then paste your key when prompted. Keys start with ga_live_.
The Free plan includes 5,000 calls a month and 10 requests a minute. Free prices are fifteen minutes late. If you display them publicly, add a visible link to goldprice.dev near the prices.
printf 'Paste your goldprice.dev API key: 'IFS= read -r GOLDPRICE_API_KEYexport GOLDPRICE_API_KEYSave the Ruby client
Save this as gold_price.rb. It runs on Ruby 2.6 and newer with no gems to install. The client reads the key from the environment and makes an HTTPS request.
Successful responses stay in memory for sixty seconds. The client rejects stale data, validates computed_at and converts the price string to BigDecimal. It makes at most three attempts when rate limited.
Retry-After can contain seconds or an HTTP date. Missing or invalid headers use increasing delays. Zero or elapsed delays wait at least a second. Other HTTP errors raise immediately.
require "net/http"require "json"require "bigdecimal"require "time"class GoldPriceClient URL = URI("https://api.goldprice.dev/v1/spot/XAU-USD-SPOT") CACHE_SECONDS = 60 MAX_TRIES = 3 def initialize @key = ENV.fetch("GOLDPRICE_API_KEY", "").strip raise "Set GOLDPRICE_API_KEY before running" if @key.empty? @cached = nil @expires_at = 0 end def spot return @cached if @cached && monotonic_time < @expires_at MAX_TRIES.times do |attempt| http = Net::HTTP.new(URL.host, URL.port) http.use_ssl = true http.open_timeout = 5 http.read_timeout = 10 http.max_retries = 0 request = Net::HTTP::Get.new(URL) request["Authorization"] = "Bearer #{@key}" response = http.request(request) if response.code == "429" raise "goldprice: HTTP 429 after #{MAX_TRIES} tries" if attempt == MAX_TRIES - 1 sleep retry_delay(response["Retry-After"], attempt) next end raise "goldprice: HTTP #{response.code}" unless response.is_a?(Net::HTTPSuccess) raw = JSON.parse(response.body) raise "goldprice: stale or missing freshness flag" unless raw["is_stale"] == false Time.iso8601(raw.fetch("computed_at")) text = raw.fetch("price") unless text.is_a?(String) && text.match?(/\A\d+(?:\.\d+)?\z/) raise "goldprice: invalid decimal price" end data = {} %w[symbol quote_currency unit contract_type price is_stale computed_at].each do |field| data[field] = raw.fetch(field) end data["price"] = BigDecimal(text) @cached = data @expires_at = monotonic_time + CACHE_SECONDS return data end end private def monotonic_time Process.clock_gettime(Process::CLOCK_MONOTONIC) end def retry_delay(header, attempt) value = header.to_s.strip delay = if value.match?(/\A\d+\z/) value.to_i else Time.httpdate(value) - Time.now end [delay, 1].max rescue ArgumentError 2**attempt endendif __FILE__ == $PROGRAM_NAME client = GoldPriceClient.new result = client.spot puts JSON.pretty_generate(result.merge("price" => result.fetch("price").to_s("F")))endRun the file
In the same terminal, run the command below from the folder containing gold_price.rb. It prints JSON with the price kept as a decimal string. The sample shows the response shape; your price and timestamp will differ.
To use the cache in an application, load this file and reuse a GoldPriceClient instance. Call client.spot whenever you need the quote. Separate command runs start with an empty cache.
ruby gold_price.rbExpected 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"}The terminal prints JSON. The price is US dollars per troy ounce. Inside the client, the price is a BigDecimal; printed JSON converts it back to a decimal string.
Common errors
| Code | What you see | Fix |
|---|---|---|
| 401 | goldprice: HTTP 401 | The supplied key was rejected. Copy your key from your account and set GOLDPRICE_API_KEY again in the terminal that runs Ruby. Never print or share the key while debugging. |
| 429 | spot raises after repeated rate limits | The client stops after three total attempts and respects Retry-After between them. Reduce requests and reuse the same client instance. A short cache does not guarantee that you stay within your monthly quota. Check your limits on the pricing page. |
| N/A | Set GOLDPRICE_API_KEY before running | The environment variable is missing or blank. Run the key setup commands in the same terminal before starting Ruby. This client requires a key even though the gold spot endpoint also supports access without one. |
| N/A | goldprice: stale or missing freshness flag | The response is marked stale or lacks an explicit fresh flag. The client refuses to cache it or return an expired quote instead. Try again later and use computed_at when investigating when the price was calculated. |
Going further
- Adapt the endpoint for gold in EUR or GBP and keep each symbol in its own cache entry
- Add daily history through
/v1/barsusing the API reference - Use
/v1/convertfor gold values by gram or kilogram - Handle client exceptions in your application and show a clear message when a price is unavailable
- Compare the Python tutorial or Node.js tutorial