← Back to Blog
April 5, 2026programming

From TradingView Alerts to APIndicators Webhooks: The Migration Guide

By APIndicators

TradingView alerts are a great starting point. You write a Pine Script, click "Add Alert", and TradingView emails you or POSTs to a URL when conditions fire. For discretionary traders and hobby bots, this is perfect.

For production automated trading, TradingView alerts hit limits fast: plan-based alert caps, 1-minute minimum polling, no HMAC signing, no built-in retries, and Pine Script's strict sandbox. This guide shows how to migrate common TradingView alert setups to APIndicators' webhook-based API, with side-by-side examples in Pine Script, Python, and Node.

When TradingView Hits Its Limits

You need to migrate when any of these happen:

  • You need more than 400 alerts (Premium plan cap)
  • Your alert fires faster than TradingView's minimum 1-minute resolution
  • You want signed webhooks with HMAC for tamper-proof payloads
  • You need multi-indicator fusion (e.g. your ML model + 3 classical indicators)
  • You are paying for TradingView and an exchange data feed and want to consolidate

APIndicators replaces the signal generation layer: you get RESTful indicator endpoints, scheduled strategy runs, and HMAC-signed webhook delivery on a single API.

Example 1: RSI Oversold Alert

Pine Script on TradingView:

//@version=5
indicator("RSI Oversold Alert", overlay=false)
rsi = ta.rsi(close, 14)
plot(rsi)
alertcondition(ta.crossover(rsi, 30), title="RSI Oversold", message="RSI crossed above 30 on {{ticker}}")

You click "Add Alert", paste a webhook URL, done.

Equivalent APIndicators approach — a Python script runs every minute, or you subscribe to a strategy that auto-fires webhooks:

import requests
import os

API_KEY = os.environ["APINDICATORS_API_KEY"]

def check_rsi_oversold(symbol):
    url = f"https://api.apindicators.com/v1/pairs/{symbol}/indicators"
    headers = {"Authorization": f"Bearer {API_KEY}"}
    r = requests.get(url, headers=headers, params={"interval": "5m"})
    data = r.json()
    return data["rsi_14"] > 30 and data["rsi_14_prev"] <= 30

if check_rsi_oversold("BTCUSDT"):
    print("RSI crossed above 30")

Or — and this is the cleaner pattern — register a persistent strategy with APIndicators that fires a webhook to your server when the condition hits:

curl -X POST https://api.apindicators.com/v1/strategies \
  -H "Authorization: Bearer $APINDICATORS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "rsi-oversold-btc",
    "symbol": "BTCUSDT",
    "interval": "5m",
    "condition": "rsi_14_prev <= 30 AND rsi_14 > 30",
    "webhook_url": "https://my-bot.example.com/webhook"
  }'

No polling. No cron. The APIndicators scheduler evaluates the condition every candle close and fires a signed webhook only when it hits.

Example 2: Multi-Indicator Fusion

Here is where TradingView starts to strain. Say you want to enter long when all three fire: RSI crosses above 40, MACD above zero, ADX above 22. Pine Script handles it, but hitting webhook URLs reliably at scale gets fragile.

With APIndicators:

payload = {
    "name": "btc-momentum-entry",
    "symbol": "BTCUSDT",
    "interval": "1h",
    "condition": "rsi_14 > 40 AND macd > 0 AND adx_14 > 22",
    "webhook_url": "https://my-bot.example.com/webhook",
    "cooldown_minutes": 60
}

requests.post(
    "https://api.apindicators.com/v1/strategies",
    headers={"Authorization": f"Bearer {os.environ['APINDICATORS_API_KEY']}"},
    json=payload
)

The cooldown_minutes field prevents the same alert from firing 60 times when conditions hover at the threshold. TradingView requires you to code this logic into Pine; APIndicators handles it at the infrastructure level.

Receiving the Webhook (Python + Node)

All APIndicators webhooks are HMAC-SHA256 signed. Verify on receipt:

Python (Flask)

from flask import Flask, request, abort
import hmac
import hashlib
import os

app = Flask(__name__)
SECRET = os.environ["APINDICATORS_WEBHOOK_SECRET"].encode()

@app.post("/webhook")
def webhook():
    signature = request.headers.get("X-Signature", "")
    body = request.get_data()
    expected = hmac.new(SECRET, body, hashlib.sha256).hexdigest()

    if not hmac.compare_digest(signature, expected):
        abort(401)

    payload = request.json
    print(f"Signal fired: {payload['strategy_name']} on {payload['symbol']}")
    return {"ok": True}

Node.js (Express)

import express from "express";
import crypto from "crypto";

const app = express();
const SECRET = process.env.APINDICATORS_WEBHOOK_SECRET;

app.post("/webhook", express.raw({type: "application/json"}), (req, res) => {
  const signature = req.headers["x-signature"];
  const expected = crypto.createHmac("sha256", SECRET).update(req.body).digest("hex");

  if (signature !== expected) {
    return res.status(401).end();
  }

  const payload = JSON.parse(req.body.toString());
  console.log(`Signal fired: ${payload.strategy_name} on ${payload.symbol}`);
  res.json({ok: true});
});

app.listen(3000);

Neither example polls. Neither example has to implement indicator math. Signals show up when they fire.

Why Programmatic Beats Alerts for Production Bots

Four specific reasons:

  1. Deterministic delivery. APIndicators retries failed webhook deliveries with exponential backoff. TradingView gives you one shot.
  2. Cryptographic integrity. HMAC signing means you can run your webhook handler on a public URL without worrying about spoofed signals.
  3. No Pine Script sandbox. Any condition expressible via Python or SQL can be a strategy.
  4. Predictable pricing. APIndicators' free tier already allows more webhook traffic than most production bots generate.

Practical Takeaways

  1. Use TradingView alerts for discretionary trading. Use programmatic webhooks for automated execution.
  2. Always verify HMAC signatures. Never accept unsigned webhook POSTs as trading signals.
  3. Add cooldowns at the source, not in your bot, to avoid duplicate fires.
  4. Log every webhook you receive with the full payload and your response.
  5. Start by mirroring your TradingView alerts 1:1, then add cross-indicator conditions that Pine Script cannot express cleanly.

Ready to migrate? Start at apindicators.com/docs for the full webhook schema or apindicators.com/pricing to pick a plan.