StructureX

Home › Guides › Platforms

Pine Script webhook alerts: send clean JSON with alert()

A webhook sends your alert to another program instead of your phone. That program needs a message it can read. JSON is the usual format, and one missing quote breaks it. Here's how to build it safely.

Beginner guide · 9-minute read · Updated 2026-10-21

What a webhook is

Most alerts go to you: a pop-up, an email, a phone notification.

A webhook sends the alert to a web address instead. A program waiting at that address reads the message and does something with it. It might log it, post it to a chat, or pass it to other software.

The message is plain text. But programs read JSON best. JSON looks like this:

{"ticker": "AAPL", "side": "buy", "price": 182.4}

Names in double quotes, a colon, then a value. Text values in double quotes too. Numbers without quotes. Commas between pairs.

This page builds that message in Pine Script. The basics of alerts are in Pine Script alerts. What happens on the receiving side is in TradingView webhook alerts to a bot.

What you need first

The script

This indicator sends a JSON message when a candle closes above its 20-candle average:

//@version=6
indicator("Webhook JSON example", overlay=true)
avg = ta.sma(close, 20)
plot(avg, "Average", color=color.orange)
crossUp = ta.crossover(close, avg)
q = '"'
msg = "{" + q + "ticker" + q + ": " + q + syminfo.ticker + q + ", " + q + "event" + q + ": " + q + "close_above_avg" + q + ", " + q + "price" + q + ": " + str.tostring(close) + ", " + q + "avg" + q + ": " + str.tostring(avg) + ", " + q + "tf" + q + ": " + q + timeframe.period + q + "}"
if crossUp
    alert(msg, alert.freq_once_per_bar_close)

Every line, in plain words

The result looks like this:

{"ticker": "AAPL", "event": "close_above_avg", "price": 182.4, "avg": 180.95, "tf": "15"}

Notice that price and avg have no quotes. They're numbers. ticker, event and tf do. They're text.

Turning it on

  1. Save the script and add it to a chart.
  2. Open TradingView's Alerts panel and create a new alert.
  3. For the condition, pick your script, then look for Any alert() function call.
  4. In the notification settings, tick the webhook option and paste your web address.
  5. Save.

The message comes from your code, so leave the alert's own message box alone.

Why build it in code?

TradingView has placeholders like {{ticker}} and {{close}}. They work well in the message box of an alertcondition() alert.

With alert(), the message is built by your script while it runs. So you can include any value it works out, like the average, a stop price or a size. The safe habit is to build every value in code with str.tostring(), as above. That way, what you test is exactly what gets sent.

Why "once per bar close" matters here

A webhook may trigger other software. Firing it on a live candle can send a message for a cross that undoes itself a minute later.

alert.freq_once_per_bar_close waits until the candle is finished. That matches a rule we use for every level: only a candle body closing past it counts.

The other choices, alert.freq_once_per_bar and alert.freq_all, can fire mid-candle. Use them only if you've thought through what happens on a false start.

Test before you send it anywhere

  1. Copy a real message from the alert log. TradingView keeps a list of fired alerts.
  2. Paste it into any JSON checker. It should say "valid".
  3. Point the webhook at a test address first, one that only logs what arrives.
  4. Check the numbers against the chart. Same price? Same timeframe?

Then remember: an edited script needs a new alert. The old alert keeps running the old code.

A message is not a decision. A webhook carries information. If anything acts on it automatically, that thing needs its own limits: a size from the stop, a daily loss limit, and a way to switch it off. See trading bot risk controls.

Keep it safe

Short names travel well. "tf" and "avg" are fine. Spaces, quotes or line breaks inside names are where JSON breaks.

Learning from a real script

Our course includes the full source code of the StructureX chart tool to learn from and customize, including adding your own alerts and messages. It's source code, not a ready-made trading bot.

Common mistakes

Questions

How do I send JSON from a TradingView alert?

Build the JSON text in Pine Script with + and str.tostring(), send it with alert(), then create an alert on "Any alert() function call" with a webhook URL.

Do TradingView webhooks need a paid plan?

Yes. Webhook notifications aren't on the free plan, and TradingView also asks for 2-factor sign-in. Check its current plans for details.

Why is my webhook JSON invalid?

Usually a missing quote, a quoted number, or a comma after the last item. Copy a fired message from the alert log into a JSON checker to find it.

Can I use {{close}} in a Pine Script alert() message?

Placeholders are made for alertcondition() and the alert message box. With alert(), build the value in code with str.tostring(close) instead.

Want the next step? We'll walk you through it.

Four free lessons by email, one every few days — each with a 10-minute exercise on a real chart.

Send Me the Free Lessons 4 short emails · No spam · Unsubscribe anytime

Or see the whole method, step by step:

See What’s Inside the Course Try everything free first. Decide when you're ready. · Open the free chart tool (works in the TradingView phone app)

One chart idea a day, in plain English. Follow along:

Follow on XFollow on TradingView