TradingView Webhooks: Send Alerts to Discord, Slack or an API
Set up TradingView webhook alerts for Discord, Slack or any API. Includes JSON payloads, JavaScript transforms, fan-out and troubleshooting.
TradingView can POST an alert to any HTTPS webhook URL. To send that alert to Discord, Slack or an API, put a Webhook Relay input between TradingView and the destination, then reshape the payload for each output.
The important constraints are easy to miss: TradingView only accepts destination ports 80 and 443, cancels requests that take longer than three seconds, requires two-factor authentication for webhook alerts, and chooses application/json only when the alert message is valid JSON. These requirements are documented in TradingView's webhook alert guide.
What you will build
TradingView alert
|
v
Webhook Relay input
|
+--> transform to Discord --> Discord channel
+--> transform to Slack --> Slack channel
+--> preserve JSON --> your API
One stable input URL receives the alert. Each output can use its own JavaScript transformation, so Discord and Slack do not need to agree on a payload format.
1. Create the Webhook Relay input
Open the new public destination page, add your first destination URL, and copy the generated input URL.
For Discord, create an incoming webhook under Server Settings > Integrations > Webhooks and use its URL as the destination. Discord's webhook API accepts a content string or an embeds array.
For Slack, create an incoming webhook for the target channel and use that URL. Slack's incoming webhook guide accepts JSON with text or Block Kit blocks. Treat both Discord and Slack webhook URLs as secrets.
2. Send structured JSON from TradingView
In TradingView, create an alert, enable Webhook URL, and paste the Webhook Relay input URL. Use valid JSON in the Message field:
{
"ticker": "{{ticker}}",
"exchange": "{{exchange}}",
"price": {{close}},
"action": "{{strategy.order.action}}",
"time": "{{time}}"
}
TradingView replaces the placeholders when the alert fires. Its placeholder reference lists the values available for indicators and strategies.
Keep numeric placeholders such as {{close}} unquoted only when they always resolve to a number. If a value can be blank or textual, quote it so the result remains valid JSON.
3. Transform the alert for Discord
Attach this function to the Discord output:
let alert
try {
alert = JSON.parse(r.body)
} catch (error) {
alert = { ticker: "TradingView", action: "alert", price: r.body }
}
const message = {
embeds: [{
title: `${alert.ticker} ${alert.action || "alert"}`,
description: `Price: ${alert.price}`,
fields: [
{ name: "Exchange", value: String(alert.exchange || "unknown"), inline: true },
{ name: "Time", value: String(alert.time || "unknown"), inline: true }
]
}]
}
r.setMethod("POST")
r.setHeader("Content-Type", "application/json")
r.setBody(JSON.stringify(message))
The try block also handles an older plain-text alert without dropping it.
4. Transform the same alert for Slack
Add a second output with the Slack incoming webhook URL and attach a Slack-specific function:
const alert = JSON.parse(r.body)
const message = {
text: `${alert.ticker} ${alert.action || "alert"} at ${alert.price}`,
blocks: [
{
type: "section",
text: {
type: "mrkdwn",
text: `*${alert.ticker}* ${alert.action || "alert"}\nPrice: *${alert.price}*`
}
},
{
type: "context",
elements: [{
type: "mrkdwn",
text: `${alert.exchange || "Unknown exchange"} | ${alert.time || "No timestamp"}`
}]
}
]
}
r.setHeader("Content-Type", "application/json")
r.setBody(JSON.stringify(message))
If you prefer plain messages, use { "text": "..." }. The blocks example is useful when you want the ticker and price to remain scannable in a busy channel.
Forward TradingView alerts to your own API
Your API may already accept the JSON from TradingView. In that case, add it as another output without a body transform. You can still add authentication without placing secrets in the TradingView alert:
r.setHeader("Authorization", "Bearer " + cfg.get("DESTINATION_API_TOKEN"))
r.setHeader("Content-Type", "application/json")
Store DESTINATION_API_TOKEN in the function's configuration variables. TradingView explicitly warns against putting credentials in the webhook body.
For private APIs on localhost, a private VM, or a cluster service, follow the localhost webhook forwarding guide and run the relay agent inside the network.
Safety for broker and trading APIs
A webhook can technically call a broker or exchange endpoint, but a chat notification and a trade execution are not the same risk class. Before enabling live orders:
- Use a paper-trading account.
- Allowlist symbols, actions and maximum position size.
- Reject malformed or duplicate alerts.
- Keep API credentials in configuration variables.
- Put work that may exceed three seconds behind a queue.
- Alert on rejected and failed deliveries.
Do not rely on a human-readable alert string as an order instruction. Send explicit JSON fields and validate every one.
Troubleshooting TradingView webhooks
TradingView sends text/plain
The alert message is not valid JSON. Paste the final message into a JSON validator and check quoting around placeholders. TradingView sets application/json only when the rendered message parses as JSON.
The request times out
TradingView cancels requests after three seconds. Check the Webhook Relay delivery duration and destination response. A slow downstream API should accept the event quickly and process it asynchronously.
Discord returns 400
Discord expects at least one supported field such as content or embeds. Confirm the function is attached to the Discord output and that it sets Content-Type: application/json.
Slack returns an invalid-payload error
Slack expects JSON with a text string or valid Block Kit. Inspect the transformed request body in the delivery log, not only the original TradingView message.
The webhook option is unavailable
Confirm that two-factor authentication is enabled and that your TradingView plan supports webhook alerts. Use an HTTPS URL on port 443.
Next steps
Use the webhook transformation cookbook to add routing and validation, or start with the free Webhook Bin to inspect the exact TradingView request before connecting a real destination.
