---
title: "TradingView Webhooks to Discord, Slack or an API"
meta:
  "og:description": "Set up TradingView webhook alerts for Discord, Slack or any API. Includes JSON payloads, JavaScript transforms, fan-out and troubleshooting."
  "og:title": "TradingView Webhooks to Discord, Slack or an API"
  description: "Set up TradingView webhook alerts for Discord, Slack or any API. Includes JSON payloads, JavaScript transforms, fan-out and troubleshooting."
---

![Stripes](https://webhookrelay.com/images/stripes.svg)

# **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](https://www.tradingview.com/support/solutions/43000529348-how-to-configure-webhook-alerts/).

## [What you will build](#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](https://webhookrelay.com/docs/webhooks/functions/), so Discord and Slack do not need to agree on a payload format.

## [1. Create the Webhook Relay input](#_1-create-the-webhook-relay-input)

Open the [new public destination page](https://my.webhookrelay.com/new-public-destination), 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](https://docs.discord.com/developers/resources/webhook) 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](https://api.slack.com/messaging/webhooks) accepts JSON with `text` or Block Kit `blocks`. Treat both Discord and Slack webhook URLs as secrets.

## [2. Send structured JSON from TradingView](#_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](https://www.tradingview.com/support/solutions/43000531021-how-to-use-a-variable-value-in-alert/) 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](#_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](#_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](#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](https://webhookrelay.com/docs/webhooks/internal/localhost/) and run the relay agent inside the network.

## [Safety for broker and trading APIs](#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:

1. Use a paper-trading account.
2. Allowlist symbols, actions and maximum position size.
3. Reject malformed or duplicate alerts.
4. Keep API credentials in configuration variables.
5. Put work that may exceed three seconds behind a queue.
6. 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](#troubleshooting-tradingview-webhooks)

### [TradingView sends `text/plain`](#tradingview-sends-textplain)

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](#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-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-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](#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](#next-steps)

Use the [webhook transformation cookbook](https://webhookrelay.com/blog/auto-transform-webhook/) to add routing and validation, or start with the free [Webhook Bin](https://webhookrelay.com/webhook-bin/) to inspect the exact TradingView request before connecting a real destination.

## **Frequently asked questions**

### **How do I send a TradingView alert to Discord?**

Send the TradingView alert to a Webhook Relay input, attach a JavaScript function that creates Discord's content or embeds payload, and forward the result to the Discord incoming webhook URL.

### **Why does TradingView say my webhook timed out?**

TradingView cancels webhook requests that take more than three seconds. Acknowledge quickly and move slow broker, database or enrichment work behind an asynchronous queue.

### **Does TradingView send JSON webhooks?**

TradingView uses application/json when the alert message is valid JSON. Otherwise it sends text/plain. Put valid JSON in the alert message when your destination needs structured fields.

### **Can one TradingView alert go to several destinations?**

Yes. A Webhook Relay bucket can fan one input out to multiple outputs, with a different transform on each output for Discord, Slack, an internal service or another API.