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
- 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.
- 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. - Edit the message. Click a placeholder to insert it at the cursor; text placeholders get their quotes automatically inside JSON.
- 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.
| Placeholder | Renders | In 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/hookworks andhttp://your-server.com:5000/hookdoesn'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.