Skip to content
Bullion API

Bullion API prices in n8n

Import a workflow that reads hourly weekday metal prices from Bullion API and appends each price, with its observation time, to a Google Sheet.

Prices refresh hourly on weekdays. Every price carries its own UTC observation time, and the workflow writes that time next to the price.

The sample reads gold in USD per troy ounce. Change the metal, currency or unit in the HTTP Request node.

The row the workflow appends

Placeholders show the shape. The values come from the API response at run time.

Columns written to the Prices tab, with placeholder values
metalcurrencyunitpriceobserved_at
goldUSDtroy_oz<decimal string><UTC timestamp>

What the workflow does

  1. Schedule Trigger

    Runs at 15 minutes past each hour, Monday to Friday, in UTC, after the hourly refresh is due.

  2. Bullion API price

    An HTTP Request calls /v1/gold/price with the key in an X-API-Key header, taken from a Header Auth credential.

  3. Shape row

    A Code node reads the observation's value and date and keeps both as text.

  4. Append to Google Sheets

    Adds one row per run. Columns are matched by name: metal, currency, unit, price and observed_at.

How fresh the prices are

Prices refresh hourly on weekdays. A run that falls between refreshes, such as the weekday 22:00 UTC hour or a manual run at the weekend, returns the newest stored observation.

Its observed_at value shows when that price was taken. If the same price and time appear on several rows, no newer observation existed when the workflow ran.

Set up n8n

  1. Download the workflow file and import it into n8n with its import-from-file option. It starts inactive.
  2. Create a Header Auth credential. Set the name to X-API-Key and the value to your key. Select that credential in the Bullion API price node.
  3. Connect a Google Sheets credential. In the Append node, choose your spreadsheet and a tab named Prices. Put the headers metal, currency, unit, price and observed_at in row 1. After the first run, check that the price cell holds a number, not text. If it holds text, set the Append node's Cell Format option to Let Google Sheets format, then run the workflow again. Then format the price column to two decimal places.
  4. Run the workflow once and check the new row, then activate it.

Keep the key in n8n's credential store. Do not paste it into a Code node, an expression, a workflow you share, or code that runs in a browser. Until you add your key, the placeholder is bullion_YOUR_API_KEY.

Code node: keep prices as text

The Shape row node copies the API's decimal string without converting it. Round only when you display it, to two decimals.

const observation = $input.first().json.series[0].observations[0];
return [
  {
    json: {
      metal: 'gold',
      currency: 'USD',
      unit: 'troy_oz',
      price: observation.value,
      observed_at: observation.date,
    },
  },
];

Try the endpoints from a terminal

Set BULLION_KEY to your key first, so the key stays out of each command. The price and change endpoints return decimal strings in the requested unit. The carat endpoint returns an eight-place decimal string per gram for each karat.

export BULLION_KEY=<your key>

curl "https://api.bullionapi.dev/v1/gold/price?currency=USD&unit=troy_oz" \
  -H "X-API-Key: $BULLION_KEY"

curl "https://api.bullionapi.dev/v1/silver/change?period=1w&currency=USD&unit=troy_oz" \
  -H "X-API-Key: $BULLION_KEY"

curl "https://api.bullionapi.dev/v1/gold/carat?currency=USD" \
  -H "X-API-Key: $BULLION_KEY"

A trimmed price response looks like this:

{
  "status": "success",
  "metric": "price",
  "metal": "gold",
  "currency": "USD",
  "unit": "troy_oz",
  "series": [
    {
      "id": "gold_price",
      "observations": [{ "date": "<UTC timestamp>", "value": "<decimal string>" }]
    }
  ]
}

Errors the workflow can see

StatusCodeWhat it meansWhat to do
401missing_api_key or invalid_api_keyThe header is missing, or the key is invalid or revoked.Check the Header Auth credential.
404not_foundNo API operation exists at the URL.Check the URL, such as the metal name.
429rate_limitedThe key has used its rolling request window.Let the next scheduled run try again.
429quota_exceededThe monthly usage limit has been reached.Check your plan on the pricing page.

An error body has this form. The n8n node shows the status and code.

{
  "status": "error",
  "error": {
    "code": "invalid_api_key",
    "message": "Invalid or revoked API key"
  }
}

Building your own integration?

Use the API directly in your application.

Read the API documentation