You designed a strategy in Pine Script and you want it to trade on its own. But TradingView does not execute orders at your broker directly (except through native integrations). The bridge is the webhook: the alert fires, sends a message to a server of yours, and that server executes the order through the broker's API. This guide builds that entire pipeline — and is honest about where it can break.
01The end-to-end architecture
There are four links. Understanding the flow is essential before writing a single line:
Prerequisite: the webhook feature in alerts requires a paid TradingView plan. Free plans do not send webhooks. And you need a server with a public URL (a VPS, or services like Render/Railway) to receive the POST.
02Step 1: the alert in TradingView
In your Pine Script, you use alert() with a JSON message (so the server can interpret it). Then, when creating the alert in the interface, you paste your webhook URL into the "Webhook URL" field.
// in Pine Script — message structured as JSON if ta.crossover(ma_rapida, ma_lenta) alert('{"segredo":"MEU_SEGREDO","acao":"COMPRA","ativo":"BTCUSDT","qtd":0.01}', alert.freq_once_per_bar_close)
The segredo is vital — it is what stops anyone who discovers your URL from firing fake orders. We will look at the validation on the server side.
03Step 2: the receiving server
A simple Python server with FastAPI that receives the webhook, validates the secret and processes it:
# servidor.py from fastapi import FastAPI, Request, HTTPException import os app = FastAPI() SEGREDO = os.getenv("WEBHOOK_SECRET") # never hardcode it @app.post("/webhook") async def webhook(request: Request): dados = await request.json() # 1. validates the secret — blocks fake requests if dados.get("segredo") != SEGREDO: raise HTTPException(status_code=403, detail="Não autorizado") # 2. parses the signal acao = dados.get("acao") ativo = dados.get("ativo") qtd = dados.get("qtd") # 3. executes at the broker (function from your execution module) if acao == "COMPRA": executar_compra(ativo, qtd) elif acao == "VENDA": executar_venda(ativo, qtd) return {"status": "ok", "acao": acao}
The executar_compra function uses the broker's API — exactly the code we showed in the Binance tutorial or in the MT5 API. The webhook only replaces the part that "decides" — now Pine Script is what decides.
Security is mandatory, not optional: your webhook URL is public. Without secret validation, anyone who discovers the URL can fire orders in your account. Always use: (1) a secret in the message, (2) HTTPS, (3) ideally validate TradingView's source IP as well. Treat this the way you would treat your bank password.
04Step 3: where to host the server
The server needs a public URL and has to be online at all times. Options:
- VPS (the same one as the bot) — full control, a fixed IP so you can filter traffic. See our VPS guide.
- Deploy platforms (Render, Railway, Fly.io) — they get the server up fast and have a limited free tier. Good for testing.
- Local tunnel (ngrok) — for testingonly; it temporarily exposes your local PC. Never for production.
Need a VPS to host it?
See how to choose and set up the VPS that will run your webhook server 24/7.
05Webhook vs. native integration
Before building this whole pipeline, consider the alternative: some brokers have native TradingView integration — you send orders straight from the chart, with no server in between. Pepperstone is one example. Compare:
- Webhook + server: flexible (it works with any broker that has an API), but it adds points of failure (server, latency, security) and requires maintenance.
- Native integration: simpler and more reliable (no server of yours in the middle), but limited to the brokers that offer it and to what the integration allows.
Recommendation: if your broker has a native integration and it covers your strategy, prefer it — fewer things to break. The webhook shines when you need custom logic in the middle (e.g. your own risk management, multiple brokers) or when the broker only offers an API, not a TradingView integration.
06The honest risks of webhook automation
What can go wrong (and will, sooner or later): the server can go down and you lose the signal. The request can get lost on the network. There is latency between the alert and execution (seconds can matter). An alert can fire twice (duplicate order). You need logs, idempotency (never executing the same order twice) and monitoring. Webhook automation is powerful, but it is not "set it and forget it".
Practices that reduce the risk: log every request received and every order sent; implement idempotency (each alert has an ID, ignore repeats); have a "kill switch" (a way to shut everything down fast); and — always — test the whole pipeline on a demo account for weeks before going live.
07Frequently asked questions
What is a TradingView webhook?
It is an HTTP request that TradingView automatically sends to a URL of yours when an alert fires. That request can trigger a server that executes orders at your broker, automating strategies built in Pine Script.
Do I need a paid TradingView plan?
Yes. The webhook feature in alerts requires a paid plan. Free plans do not allow sending webhooks. On top of that, you need a server with a public URL to receive them.
Is automating via webhook safe?
It has risks: the URL is public (it needs secret validation), the server can go down, there is latency, and alerts can duplicate. For time-sensitive strategies, a native integration is more reliable. Always test on demo and use logs, idempotency and a kill switch.
What is the difference from a native integration?
A native integration (e.g. Pepperstone) executes straight from the chart, with no server of yours — simpler and more reliable. A webhook is more flexible (any broker with an API, custom logic in the middle) but adds points of failure. Prefer native when it covers your needs.
Can I use a webhook for Brazil's B3 exchange?
Yes, as long as your broker has an accessible API. The receiving server would call the broker's API (or the MT5-Python bridge) to execute on B3. The flow is the same; only the execution function at the end changes.