Run a short script on a schedule to read the spot price and compare it with your level. At gold's $3,996.00 price on 24 October 2026, a first call with a $4,000 threshold stores the starting state without an alert. Free uses the previous UTC day's close, so a Free alert on a daily schedule fires at most once a day.
Do it with the API
- Get a key and set the threshold Get a free key and keep it in the
NARWHAL_API_KEYenvironment variable. Narwhal uses one account and one API key across its data APIs, with the same key for REST and MCP; the script sends it in theAuthorization: Bearer YOUR_KEYheader and compares gold in USD per troy ounce withTHRESHOLD. - Save the Python script The request reads
pricefrom the gold spot endpoint; a price equal to or aboveTHRESHOLDcounts as above, and a lower price counts as below. The script compares that side with the value saved ingold_state.json, prints an alert when the side changes, then saves the new state and prints the price.Python, alert when gold crosses 4,000import json, os, pathlib import requests THRESHOLD = 4000.00 # alert when gold crosses this level, in USD per troy ounce STATE = pathlib.Path("gold_state.json") # remembers which side of the line we were on price = float(requests.get("https://api.narwhalapi.com/v1/commodities/spot/XAU/USD", headers={"Authorization": f"Bearer {os.environ['NARWHAL_API_KEY']}"}, timeout=10).json()["price"]) above = price >= THRESHOLD was_above = json.loads(STATE.read_text())["above"] if STATE.exists() else None if was_above is not None and above != was_above: print(f"ALERT: gold {'rose above' if above else 'fell below'} {THRESHOLD:.2f} at {price:.2f}") # send an email or chat message here STATE.write_text(json.dumps({"above": above})) print(f"gold {price:.2f}") - Put the script on a schedule Use a daily schedule on Free because its spot price is the previous UTC day's close. Free allows 5,000 requests a month and 30 a minute; one request a day uses about 30 a month.
- Connect the alert to a message The
printline inside the condition is the place to send an email or chat message; keep the state file available between scheduled calls so the script can compare each price with the saved side. It alerts in either direction, above the threshold after being below, or below it after being above, and the final price print happens even when there is no crossing.
On a paid plan with live prices, poll sparingly because each poll uses a request from the quota. A crossing comparison uses the prices returned by those requests. The script makes a spot request each time it is called. Set the schedule outside the script, which has no scheduling loop. See schedule a daily data pull for scheduling.
Use THRESHOLD for the price level and STATE for the path to the saved JSON file. The comparison is price >= THRESHOLD. The alert text uses rose above when above is true and fell below when it is false. It includes both the threshold and the returned price, so the message carries the level that triggered it and the price used in the comparison. The saved JSON contains the above value that the following call reads.
Do it without code
In Zapier or Make, start with a schedule trigger and add an HTTP request to https://api.narwhalapi.com/v1/commodities/spot/XAU/USD. Send the key in the Bearer header so the request uses your Narwhal account. Add a filter on the returned price, followed by an email or chat action; the filter determines whether that price meets your level. Free spot responses use the previous UTC day's close, so a daily schedule matches that price timing. The Bearer header uses the same Narwhal key as the Python request, and REST and MCP share that key too.
Use the Zapier tutorial or Make tutorial for that route. The Python script includes saved crossing state; the no-code workflow has a price filter and a message action. Decide whether your condition is a price above the threshold or a change from the previously saved side before treating those conditions as the same alert.
Which option to use when
| Situation | Best option | Why |
|---|---|---|
| A daily level alert on Free | The script on a daily schedule | A daily request matches Free's previous UTC day's close |
| A minute-by-minute alert | A price stream on Basic or Pro | Hold the WebSocket price stream open for supported metals or FX pairs |
| An alert without code | Zapier, Make or n8n with an HTTP request step | Use an HTTP request in the workflow; Zapier and Make can filter price before an email or chat action |
How do I reset the saved crossing state?
Remove gold_state.json to reset the saved side. When that file is absent, was_above is None, so the alert condition does not fire. The script stores the returned price's side as its starting state. Removing the file therefore starts the crossing comparison again; it does not make the first price produce an alert.
Can a webhook send a commodity price alert?
Narwhal webhooks do not cover price levels. They carry economic releases, yield curves, holiday calendars and prediction events. For a price threshold, use polling or, on Basic or Pro, hold a WebSocket price stream open at wss://api.narwhalapi.com/v1/prices/stream. The price comparison belongs in the script or workflow that reads those prices.
Can I stream an oil or copper alert?
Oil and copper are REST only, so use polling for those alerts. Only the metals XAU, XAG, XPT and XPD, plus FX pairs, can be streamed. Polling works for every spot code, including XAU, XAG, XPT, XPD, XCU, BRENT and WTI.
Worked example: threshold 4,000
Start with the gold price of $3,996.00 on 24 October 2026 and a threshold of $4,000. On this first call, the price is below the threshold and there is no saved side. The script stores false in the state file and prints gold 3996.00, with no alert.
For example, suppose the price is $4,012.50 on Day 2 and $4,020 on Day 3. These later prices are made-up illustrations. On Day 2, the saved side is below and the new side is above, so the script prints the crossing alert. On Day 3, both the saved side and the new side are above, so there is no repeated alert.
| Call | Gold price | Saved side after the call | Alert |
|---|---|---|---|
| Day 1, 24 October 2026 | $3,996.00 | Below | None |
| Day 2, for example | $4,012.50 | Above | ALERT: gold rose above 4000.00 at 4012.50 |
| Day 3, for example | $4,020 | Above | None |
Published .
