OroPocket Blog
Tutorials

A Free Gold and Silver Price API for India: Live Endpoint, No API Key

Mohit M
August 28, 2026
A dark code editor window showing a JSON response, photographed at an angle with soft screen glow in a dim room

Here is the endpoint. No signup, no key, no header. It returns gold and silver buy and sell rates in Indian rupees per gram, plus the GST component and the 24 hour change.

curl https://api.oropocket.com/public/prices

That is the whole integration. The rest of this page is what the fields mean, what the limits actually are, and the one thing you must not do with the response.

Endpoint GET https://api.oropocket.com/public/prices
Auth None
Returns Gold and silver, buy and sell, INR per gram
Rate limit 10 requests per 60 seconds per IP, then HTTP 429
Metals Gold and silver only
History None. Current values only
The catch It is a tradeable quote, not a spot benchmark. Label it correctly

The response

Read live at 02:00 UTC on 25 August 2026:

{
  "statusCode": 200,
  "message": "Asset prices retrieved successfully",
  "data": {
    "gold": {
      "buy": 16849.82,
      "sell": 16339.98,
      "gst": 505.49,
      "currency": "INR",
      "unit": "gram",
      "change24h": { "buy": -0.18, "sell": -0.5 }
    },
    "silver": {
      "buy": 258.54,
      "sell": 242.93,
      "gst": 7.76,
      "currency": "INR",
      "unit": "gram",
      "change24h": { "buy": -0.16, "sell": 0 }
    },
    "timestamp": "2026-08-25T02:00:29.622Z"
  }
}

Field by field:

Field What it is
buy What a buyer pays, per gram, in rupees. Excludes GST
sell What a seller receives, per gram, in rupees
gst The GST component on a one gram purchase. Exactly 3% of buy
currency / unit Always INR and gram today. Do not hardcode the assumption
change24h Percentage change over 24 hours, given separately for buy and sell
timestamp When the quote was generated, ISO 8601, UTC

On that reading, gst was 505.49 against a buy of 16849.82, which is 3.00% exactly. That is the statutory rate on precious metals in India, not a platform fee.

The one thing you must not do with this

A comparison showing that the OroPocket public price endpoint returns a dealer quote rather than a spot benchmark. A benchmark feed returns a single number. This endpoint returns both a buy price and a sell price, and the gap between them was 3.12 per cent for gold and 6.43 per cent for silver when read on 25 August 2026. Displaying the buy price under a label saying gold spot price would therefore be wrong.

This endpoint returns a buy and a sell. A spot benchmark returns one number. That difference is not cosmetic, and it decides how you are allowed to label the value on screen.

On the reading above, the gap between buy and sell was 3.12% for gold and 6.43% for silver. Those are a timestamped observation of one moment, not a fixed spread, and they move.

So:

  • Safe: “OroPocket buy rate, INR per gram”. “Live gold rate”. “Buy price”.
  • Not safe: “Gold spot price”. “LBMA rate”. “MCX rate”. “Market price”.

If your product needs a neutral global reference number, this is the wrong feed and you should use a benchmark provider. We would rather say that than have you ship a screen that misdescribes what it is showing.

Rate limit, measured rather than documented

The response carries its own policy header:

ratelimit-policy: 10;w=60
access-control-expose-headers: set-cookie,X-Response-Time,X-Rate-Limit-Remaining

Ten requests per sixty seconds, per IP. We tested it rather than trusting the header: calls one to ten returned 200, and every call after that returned HTTP 429 until the window rolled.

There is also caching in front of it, and we measured that too rather than guessing. Sampling every 40 seconds for ten minutes, the payload’s own timestamp field regenerated twice, with gaps of 135 and 140 seconds. In between, consecutive requests returned a byte-identical response. The gold buy rate moved once in that window, from 16,849.82 to 16,862.55.

So the underlying quote refreshes on the order of every two to two and a half minutes. That is a short observation window on one morning rather than a published SLA, so treat it as an indication of the right order of magnitude and not a contract. The practical consequence is the same either way: polling faster does not get you fresher data, it just gets you a 429.

For a price ticker, once every 30 to 60 seconds from your server is comfortable and leaves headroom. Cache the result and serve it to your own users from your side.

Copy-paste samples

JavaScript, server side. Do not call this directly from a browser for every visitor, or your users’ IPs each burn their own quota and you lose control of caching.

async function getMetalPrices() {
  const res = await fetch("https://api.oropocket.com/public/prices");
  if (res.status === 429) throw new Error("rate limited, back off");
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
  const { data } = await res.json();
  return {
    goldBuy: data.gold.buy,
    silverBuy: data.silver.buy,
    asOf: new Date(data.timestamp),
  };
}

Python, with a timeout, because a request without one will eventually hang a worker.

import requests

def get_metal_prices(timeout=5):
    r = requests.get("https://api.oropocket.com/public/prices", timeout=timeout)
    if r.status_code == 429:
        raise RuntimeError("rate limited, back off")
    r.raise_for_status()
    d = r.json()["data"]
    return {
        "gold_buy": d["gold"]["buy"],
        "silver_buy": d["silver"]["buy"],
        "as_of": d["timestamp"],
    }

PHP.

<?php
$raw = @file_get_contents("https://api.oropocket.com/public/prices");
if ($raw === false) {
    throw new RuntimeException("price fetch failed");
}
$d = json_decode($raw, true)["data"];
$goldBuy   = $d["gold"]["buy"];
$silverBuy = $d["silver"]["buy"];
$asOf      = $d["timestamp"];

A per-gram value for a holding. The arithmetic people usually get wrong is which side to use. Value what someone already holds at the sell rate, because that is what they would actually receive. Valuing a holding at buy overstates it by the full spread.

def holding_value_inr(grams, prices):
    """What the user would receive today, not what it would cost to buy."""
    return grams * prices["data"]["gold"]["sell"]

What this endpoint does not do

Stated plainly so you do not build on an assumption:

  • No history. No time series, no OHLC, no charts. Current values only.
  • No other currencies or units. INR and grams. If you need USD per troy ounce, this is not it.
  • No other metals. Gold and silver.
  • No streaming. No websocket, no server-sent events. Poll it.
  • No SLA. This is an unauthenticated public convenience endpoint. Treat it as best effort, cache it, and have a fallback for when it is unavailable.

That last one matters. Write the 429 and the timeout paths before you ship, not after.

Which “gold API” do you actually need?

Three different jobs that all get called a gold API. The first is displaying a global reference price, for which a commercial spot benchmark feed in dollars per ounce is the right tool. The second is displaying an Indian rupee per gram rate that a user could actually transact at, which is what the free OroPocket public prices endpoint returns. The third is letting a user actually buy, sell or hold metal inside your own app, which needs an authenticated transactional API rather than a price feed.

Three genuinely different jobs get called the same thing, and picking wrong costs weeks.

If you want a global reference price in dollars per ounce, with history and multiple metals, you want a commercial benchmark feed. That is not what this is, and we are not going to pretend otherwise.

If you want an Indian rate in rupees per gram that a user could actually transact at, to put on a screen or inside a calculator, that is this endpoint, and it is free.

If you want the user to actually buy, sell or hold metal inside your product, no price feed will do it. That needs an authenticated transactional API, KYC, custody and settlement behind it. That is a different category of product, and the reason apps bother is retention rather than the metal itself.

If you do need transactions

Briefly, because it is a different article and we have written the integration walkthrough already, along with a look at paying people in metal instead of points.

The transactional API lives under https://api.oropocket.com/partner and is authenticated with a bearer token, where the token prefix alone selects the mode: oro_test_ for sandbox, oro_live_ for production. Buying is deliberately two steps, a quote and then a confirm, because a metal price cannot be held open indefinitely. The quote locks for ten minutes.

The sandbox is stateful, priced off the same live feed, and fires real signed webhooks stamped as sandbox, so you can build and test the whole flow before any commercial conversation. Sandbox access is immediate.

Two things worth knowing before you start: buys debit the partner’s wallet while sells credit the end user’s rupee wallet, and every write takes an Idempotency-Key that stays valid for at least 24 hours, with a replay returning the original response rather than acting twice.

The honest summary

If you need a free Indian gold or silver rate to display, this endpoint does the job in one line and costs nothing. Cache it, respect ten calls a minute, handle the 429, and label it as a buy or sell rate rather than a spot price.

If you need a benchmark, use a benchmark provider. If you need transactions, you need an authenticated API and a compliance conversation. Knowing which of the three you are actually building is most of the decision.

When a price is not enough

The public prices endpoint is free and needs no key. If you need users to actually buy, sell or hold metal in your app, the sandbox is stateful, priced off the same feed, and fires real signed webhooks. Sandbox access is immediate.

Read the docs →

Put this into practice on OroPocket

Buy 24K digital gold from ₹1. Earn Bitcoin cashback on every purchase.

GET THE APP

Join the Conversation

Be the first to share your thoughts.

READ MORE