Edgoro
Automation · Free tool

TradingView Webhook Alert Builder

Build a TradingView alert message in JSON with the right placeholders, check it before it fails, and get the Pine alert() code that sends it.

For your own endpoint. The secret is a long random string that your server checks before acting; never a password or an exchange key.

Alert on
This alert sends a

Insert a placeholder at the cursor

What TradingView will send
Valid JSON
Content-Typeapplication/json
Placeholders5
Characters203

No problem found. Paste the message into the Message box of the alert and the URL into its Webhook field.

TradingView posts the message to your webhook URL when the alert fires. A message that is valid JSON is sent as application/json; anything else as text/plain. Webhook URLs must use port 80 or 443.

Sample of what your server receives (placeholders filled with example values)

json
{
  "secret": "replace-with-a-long-random-string",
  "ticker": "BTCUSDT",
  "exchange": "BINANCE",
  "interval": "60",
  "action": "buy",
  "price": 89250.5,
  "time": "2026-11-11T14:03:27Z"
}

The same message from Pine Script with alert()

For an indicator you write yourself: alert() builds the message from Pine values, so one alert set to “Any alert() function call” covers every signal.

Pine Script v6
//@version=6
indicator("Webhook alert message", overlay = true)

// Example signal: replace it with your own condition.
fast   = ta.ema(close, 9)
slow   = ta.ema(close, 21)
signal = ta.crossover(fast, slow)

// alert() builds its message at run time from Pine values, so it needs no {{placeholders}}.
msg = '{"secret": "replace-with-a-long-random-string","ticker": "' + syminfo.ticker + '","exchange": "' + syminfo.prefix + '","interval": "' + timeframe.period + '","action": "buy","price": ' + str.tostring(close) + ',"time": "' + str.tostring(timenow) + '"}'

if signal
    alert(msg, alert.freq_once_per_bar_close)

plot(fast, "Fast EMA", color = color.teal)
plot(slow, "Slow EMA", color = color.orange)

Trading involves substantial risk of loss and is not suitable for every investor. Edgoro is a software tool, not a broker or financial adviser: nothing it produces is investment advice, and past or backtested performance does not guarantee future results.

What the webhook alert builder does

When a TradingView alert fires, it can send its message to a URL: your own server, a Telegram relay or a broker bridge. The message is plain text that you type in the alert dialog, with placeholders such as {{ticker}} and {{close}} that TradingView fills in at that moment. Most receivers expect JSON, and one missing quote is enough to turn a JSON message into plain text that the receiver rejects.

This builder starts from a template for your destination, lets you edit it, and renders it the way TradingView would, with example values in place of the placeholders. It tells you whether the result is valid JSON, which content type TradingView will send, and which placeholders are misspelled or won't be filled for the kind of alert you chose. For an indicator you write yourself, it also gives the Pine Script v6 code that sends the same message with alert().

How to use it

  1. Pick where the alert goes: your own server, Edgoro Copilot, TradersPost or PickMyTrade. The templates use the field names from each service's own documentation. PickMyTrade generates its message, token included, in its own dashboard and advises against editing it by hand, so for that one, paste the generated message to check it.
  2. Choose what the alert is created on. Indicator or price covers alerts on an indicator, a drawing or a price level. Strategy order fills covers alerts created on a strategy, which can use the {{strategy.order...}} placeholders.
  3. Edit the message. Click a placeholder to insert it at the cursor; text placeholders get their quotes automatically inside JSON.
  4. Fix anything listed in red, then copy the message into the alert's Message box and your URL into its Webhook URL field.

Placeholders: which ones need quotes

A placeholder is replaced by its value before the message is sent, so what matters is the value. Text needs double quotes in JSON; a number doesn't.

PlaceholderRendersIn JSON
{{ticker}}, {{exchange}}, {{interval}}Text such as BTCUSDT, BINANCE, 60"{{ticker}}"
{{close}}, {{open}}, {{high}}, {{low}}, {{volume}}A number{{close}} or "{{close}}"
{{time}}, {{timenow}}A UTC date such as 2026-11-11T14:00:00Z"{{timenow}}"
{{plot_0}} to {{plot_19}}, {{plot("Name")}}The value of an indicator plot{{plot_0}}
{{strategy.order.action}}buy or sell (strategy alerts only)"{{strategy.order.action}}"
{{strategy.order.contracts}}, {{strategy.order.price}}A number (strategy alerts only){{strategy.order.contracts}}
{{strategy.market_position}}long, flat or short (strategy alerts only)"{{strategy.market_position}}"

A number in quotes is still valid JSON; it simply arrives as text, which some services ask for. {{interval}} is the trap: on an hourly chart it renders 60, which looks fine unquoted, but daily and weekly timeframes contain letters, so always quote it.

Worked example

A message for your own server, on an indicator alert:

{
  "secret": "replace-with-a-long-random-string",
  "ticker": "{{ticker}}",
  "action": "buy",
  "price": {{close}},
  "time": "{{timenow}}"
}

TradingView fills it in and posts something like {"secret": "...", "ticker": "BTCUSDT", "action": "buy", "price": 89250.5, "time": "2026-11-11T14:03:27Z"}, with an application/json content type because it parses as JSON. Now remove the quotes around {{ticker}}: the body becomes "ticker": BTCUSDT, which isn't JSON, so TradingView sends it as text/plain and a receiver that parses JSON fails. The builder flags that before you save the alert.

Strategy alerts and alert_message

On a strategy, one alert covers every order fill, and the {{strategy.order...}} placeholders describe the order that just filled. If you'd rather build the message inside the script, pass alert_message to strategy.entry(), strategy.exit() or strategy.close() and put {{strategy.order.alert_message}} alone in the Message box. TradingView's documentation is explicit that placeholders can't be used inside the alert_message argument itself, so build that text with Pine values such as syminfo.ticker and str.tostring(close).

What TradingView requires for webhooks

From TradingView's help page on webhooks, checked in November 2026:

  • Two-factor authentication must be on for your TradingView account, and webhooks need a paid plan.
  • Only ports 80 and 443 are accepted, so https://your-server.com/hook works and http://your-server.com:5000/hook doesn't.
  • The request is cancelled if your server takes more than three seconds to answer. Reply first, then do the slow work.
  • IPv6 isn't supported. If you filter by IP, TradingView sends from 52.89.214.238, 34.212.75.30, 54.218.53.128 and 52.32.178.7.
  • Don't put login credentials or passwords in the message. A random token that only your receiver knows is enough to reject strangers.

The full walk-through, with a Python receiver that checks the token, answers within the time limit and ignores duplicates, is in how to send TradingView alerts to a webhook. To check the Pine code itself, paste it into the free Pine Script checker.

Common mistakes

  • Curly quotes. Notes apps and some chat apps turn " into “ ”, which JSON doesn't accept.
  • A comma after the last field. {"a": 1,} is invalid JSON.
  • Editing the script without recreating the alert. An alert keeps a copy of the script and its settings from the moment you created it.
  • Strategy placeholders on an indicator alert. {{strategy.order.action}} is only filled on a strategy's order fills.
  • Treating "delivered" as "traded". A successful webhook only means your server answered. Log what it did with the message, and test on a demo account first.

Frequently asked questions

How do I send a TradingView alert as JSON?

Type a valid JSON object in the alert's Message box, with text placeholders such as {{ticker}} inside double quotes, and add your URL in the Webhook URL field. When the filled-in message parses as JSON, TradingView sends it with an application/json content type.

Why does my webhook receive text/plain instead of JSON?

Because the message TradingView rendered is not valid JSON. The usual causes are a text placeholder without quotes ("ticker": {{ticker}}), curly quotes, single quotes or a trailing comma. Paste the message in the builder above to see which one.

Can I use {{close}} or {{ticker}} inside Pine Script alert()?

TradingView documents placeholders for the alert dialog and for alertcondition() messages. alert() takes a message built while the script runs, so build it from Pine values: syminfo.ticker, str.tostring(close), timeframe.period. For strategies, placeholders can't be used inside the alert_message argument.

What port does a TradingView webhook URL need?

Port 80 or 443 only, so a normal http:// or https:// address without a custom port. Your server must also answer within three seconds, and two-factor authentication must be enabled on the TradingView account.

Is it safe to put my exchange API key in an alert message?

No. TradingView advises against putting credentials or passwords in the webhook body. Keep exchange keys on your server and put only a random token in the message, which your receiver checks before acting.

Related guides

All guides
All free tools

Let AI build the indicator behind your numbers.

Turn the rules you just calculated into a TradingView indicator, an MT5 bot or a crypto bot. Instant access, with a 7-day money-back guarantee.