Troubleshooting · Webhook

TradingView Webhook Not Working?
A complete debugging flowchart

2026-07-08·9 min read

You set the alert, the condition clearly fired on the chart, and nothing happens downstream — or something happens, but no order shows up on the exchange. A TradingView webhook not working problem can break at five different layers, and guessing which one it is wastes hours.

This post is a layer-by-layer diagnostic flow: plan eligibility, whether the alert actually triggered, whether TradingView actually sent the request, whether your server actually received it, and whether the exchange actually accepted the order. Work through them in order from the top — most people are stuck on layer 0 or layer 1 and don't know it yet.

Where most people actually get stuck
In practice, the two most common failure points are the ones people check last: an expired alert (layer 0) and a misunderstood trigger frequency (layer 1). Both look identical from the outside — "I set it up and it just doesn't fire" — but neither has anything to do with your server or your exchange account.

The five-layer diagnostic flow

Follow this top to bottom. Each step tells you whether to keep going or where the fix is.

1
Layer 0a — Does your TradingView plan even support webhook notifications?
Free (Basic) planBasic doesn't include webhook notifications at all — it's not a bug, the plan simply doesn't have the feature. You need Essential or above.
Essential / Plus / Premium / UltimateWebhook is available on your plan. Continue to the next check.
2
Layer 0b — What does Alert Manager show for this alert's status?
Red “Stopped — Expired”Alerts expire after a maximum lifetime (2 months by default, or open-ended on Premium/Ultimate if you enabled that option). An expired alert simply stops — delete it and create a new one; editing an expired alert does not revive it.
Green “Active”Continue to the next check.
3
Layer 1 — Does the chart clearly meet your condition, but Alert Manager shows zero trigger history at all?
Never triggered, everCheck your Frequency setting and repainting — see the Layer 1 section below before touching anything else.
It has triggered at least once (check the log)Good — the alert itself works. Continue to the delivery layer.
4
Layer 2 — Does the alert show a webhook send error?
Yes — there is an error messageRead the exact error text — it usually names the cause directly (bad port, private IP, non-HTTPS, oversized message). See the Layer 2 checklist below.
No error message shownNothing on TradingView's side is flagging a failure — the problem is most likely on your server or your network.
5
Layer 3 — Can you reach your own webhook URL from outside your network?
curl from another machine can't connect at allThis is a network problem, not a TradingView problem — firewall, dead tunnel, wrong port, or DNS. Fix that first.
curl works fine, but TradingView's requests specifically never arriveLikely an IP allowlist blocking TradingView's sending IPs, or your server took longer than 3 seconds to respond and TradingView cancelled the request.
Your server logs show the request arriving with a 200 responseDelivery is confirmed end to end. The remaining problem is on the exchange side.
6
Layer 4 — Your server received the signal, but no order appears on the exchange
Exchange rejects or silently ignores the orderCheck API key trading permission, quantity precision/step size, minimum order size, and position mode (hedge vs. one-way) — see the Layer 4 section below.
3 sec
Server must respond within
80 / 443
Only ports accepted
2 months
Default alert lifetime
15 / 3 min
Trigger cap before auto-stop

Layer 0 — Can this alert even send a webhook?

Before you touch your server or your Pine script, confirm the alert is structurally capable of sending a webhook at all. Two separate gates apply here, and either one alone is enough to explain "nothing ever happens."

Plan eligibility

Webhook notifications are gated by subscription tier. The free Basic plan does not include webhook notifications — it's absent from the feature entirely, not limited. As of July 2026, TradingView's plan comparison shows:

PlanWebhookPrice + technical alertsAlert lifetime
Basic (free)No3 + 01 month
EssentialYes20 + 202 months
PlusYes100 + 1002 months
PremiumYes400 + 400 (+2 watchlist)Open-ended option
UltimateYes1,000 + 1,000 (+15 watchlist)Open-ended option

TradingView pricing comparison table, as verified July 2026 — check tradingview.com/pricing for current figures.

A separate account-level gate
Webhook alerts also require two-factor authentication enabled on your TradingView account — this is independent of your plan. It won't unlock webhook on a Basic plan (the plan itself doesn't offer it), but on a paid plan, forgetting to enable 2FA is a separate reason webhook alerts can be blocked.

Alert expiration and dormancy

Alerts are not permanent. The default maximum lifetime is two months; Premium and Ultimate plans can enable an "open-ended" option so the alert never expires. An expired alert shows a red Stopped — Expired status in Alert Manager and simply won't fire again — you have to delete it and create a new one.

There's a second, separate rule worth knowing: an alert gets automatically deactivated if all three of these are true at once — it was created more than a year ago, it hasn't triggered in over a year, and it hasn't been edited in over a year. If your alert has been quietly sitting untouched for a long time, check this before assuming the problem is technical.

  • Confirmed your plan is Essential or above (Basic has no webhook notifications)
  • Checked Alert Manager and confirmed the status is green Active, not red Stopped — Expired
  • 2FA is enabled on your TradingView account
  • If the alert is over a year old, confirmed it hasn't been auto-deactivated from a year of inactivity

Layer 1 — Did the alert actually trigger?

This is the layer with the most confusion, because TradingView uses two different frequency systems that people constantly mix up: the Frequency dropdown in the alert creation dialog, and the freq parameter of Pine's alert() function. They are not the same options.

SettingWhere it livesWhat it means
Once onlyUI dropdown onlyFires exactly once, ever, when conditions exactly match
Once per barUI dropdown, or alert.freq_once_per_bar in codeChecks every bar, fires as soon as the condition is met — does not wait for the bar to close
Once per bar closeUI dropdown, or alert.freq_once_per_bar_close in codeSame check, but only fires after the bar has actually closed
Once per minute / every timeUI dropdown onlyRe-checks the condition every minute
alert.freq_allalert() function onlyFires every time the alert() call runs, no per-bar limit

The alert() function's freq argument only accepts three values (once_per_bar, once_per_bar_close, all) — there is no code-level equivalent of 'Once only' or 'Once per minute'.

If your Pine script uses the alert() function, the frequency is decided in code and only has three possible values. There is no way to make an alert() call behave like "Once only" or "Once per minute" — those two only exist for the UI-configured alert dialog on alertcondition()-based indicator alerts. Mixing the two mental models up is one of the most common reasons a webhook "should have fired but didn't."

Repainting can make a working alert look broken

Scripts that depend on the current bar's high, low, or close — or that pull data from another timeframe — can have values that shift while the realtime bar is still forming. If your frequency isn't set to Once Per Bar Close, the alert can fire on a value that later changes, which either looks like a false trigger or like a trigger that "should have happened" but didn't match what you see after the fact. Setting the frequency to Once Per Bar Close is the standard fix for this class of problem.

Strategy alerts have their own rules

If the alert is attached to a strategy rather than an indicator, a few extra rules apply. By default, a strategy only recalculates at the bar's close — so even if alert() is called with alert.freq_all or alert.freq_once_per_bar inside a strategy, it still only actually fires once per bar close, unless you explicitly enable calc_on_every_tick = true. Separately, strategy order-fill alerts only notify on realtime order fills — orders that would have filled on historical bars never generate a notification, so testing against historical data alone will never show you a live alert firing.

One more easy mistake: alertcondition() only works inside indicators. Put it in a strategy and it compiles fine — it just silently does nothing, with no error to tell you why.

  • Alert Manager's trigger log shows at least one past trigger for this alert
  • Frequency setting matches what you actually want (Once Per Bar vs. Once Per Bar Close vs. Once Per Minute)
  • If using alert() in code, confirmed the freq value is one of the three valid options
  • If it's a strategy alert, confirmed calc_on_every_tick is set correctly for your intended timing
  • Ruled out repainting by testing with Once Per Bar Close

Layer 2 — Did the request actually leave TradingView's servers?

If Alert Manager confirms the alert triggered, the next question is whether TradingView successfully sent the webhook request at all. A few strict technical requirements apply to the URL and payload:

RequirementDetail
PortsOnly 80 and 443 are accepted — any other port is rejected outright
ProtocolNon-HTTPS / broken TLS is listed as an explicit send failure
IPv6Not currently supported for webhook URLs
Message size4,000 characters max typed into the Message field; 40,960 characters max via alert() or alert_message — the same limit applies to request body size
Content-TypeAuto-detected: application/json if the message is valid JSON, otherwise text/plain

Delivery isn't retried the way people often assume. If your server returns a 5xx error, TradingView resends after 5 seconds, up to 3 times (4 attempts total). But a 4xx response or a timeout is treated as delivered and simply discarded — there's no automatic retry for either of those cases. There's also a hard rate limit: an alert that triggers more than 15 times within 3 minutes gets automatically stopped.

  • Webhook URL uses port 80 or 443 (no custom ports)
  • URL is HTTPS with a valid certificate
  • URL is a public IPv4 hostname, not IPv6
  • Alert message is under the size limit for how it was set (4,000 or 40,960 characters)
  • Not accidentally triggering more than 15 times in 3 minutes

Layer 3 — Did your server actually receive it?

This is where most genuine "webhook not working" reports actually live: the alert fired, TradingView sent the request, and it never reached your application. Two TradingView-side constraints matter here.

First, your server must respond within 3 seconds or the request is cancelled — and per the delivery rules above, a timeout is not retried. If your endpoint does slow synchronous work (placing an order, waiting on an exchange API response) before responding, that's a common way to silently lose signals under load. The fix is to acknowledge the webhook immediately and process the actual order asynchronously in the background.

Second, if you use an IP allowlist, TradingView's webhook requests currently come from a fixed list of IPs — as verified July 2026:

text
52.89.214.238
34.212.75.30
54.218.53.128
52.32.178.7
Don't treat this list as permanent
TradingView has not published any commitment that these four IPs will never change. A more durable check is the SSL certificate TradingView attaches to every HTTPS webhook request, which identifies the sender as CN = webhook-server@tradingview.com. If your framework can inspect the client certificate, that's a sturdier signal than hardcoding IPs.

A URL that resolves to localhost or any private/internal IP address is an explicit, documented failure case — TradingView's servers can't reach your laptop directly. During local development you need a public tunnel (like ngrok) in front of your server.

How to actually test this

Isolate "is my server even listening" from "is TradingView's request arriving" by hitting your own endpoint directly first:

bash
curl -X POST https://your-domain.com/webhook/your-token \
  -H "Content-Type: application/json" \
  -d '{"secret":"your-secret","symbol":"BTCUSDT","side":"buy"}'

If that curl call gets a fast 200, your server is fine and the problem is upstream (IP allowlist, timeout, or TradingView-side). If curl itself can't connect, it's a network or firewall issue that has nothing to do with TradingView at all.

  • Server responds (any status code) in well under 3 seconds — heavy work happens after responding, not before
  • Firewall or security group allows inbound traffic from TradingView's sending IPs, or authentication uses the SSL certificate instead of an IP allowlist
  • Webhook URL resolves to a public address, not localhost or a private IP
  • A direct curl test to your own endpoint returns 200

Layer 4 — It arrived, but no order shows up on the exchange

If your server logs confirm the payload arrived and your code processed it, the last layer is the exchange itself rejecting or ignoring the resulting order. TradingView doesn't control this part at all — it's entirely between your server and the exchange's API. Without a specific error code in front of you, the usual suspects are:

CauseWhat to check
API key permissionsThe key needs trading permission enabled; a read-only key or one missing futures trading access will reject every order
Quantity precisionExchanges require order size in specific step increments per symbol — a raw signal quantity that doesn't match the symbol's precision gets rejected
Minimum order sizeEvery symbol has a minimum notional or minimum quantity; small test signals often fall below it
Position mode mismatchAn account set to hedge mode when your automation assumes one-way (or vice versa) can cause close/reduce orders to behave unexpectedly
Exchange-side IP allowlistIf you've restricted the API key to specific IPs on the exchange itself, your automation server's IP has to be on that list too — separate from anything TradingView-related

If your order sizing produces a different notional than you expected rather than a flat rejection, that's usually not this layer at all — see the qty_type semantic trap for that specific and very common case. And if the API key itself is the suspect, our Binance API key security guide covers exactly which permissions to enable and which to leave off.

How TVSBot narrows this down for you
TVSBot acknowledges every webhook immediately and processes the actual order asynchronously in the background, specifically so a slow exchange round-trip never risks hitting TradingView's 3-second timeout. Every signal — raw payload, processing log, and the exchange's own response — is recorded and replayable from the dashboard, so you can see exactly which layer a given signal died at instead of guessing. Dry-run mode lets you test the whole chain with simulated fills before risking real capital.
  • API key has trading permission enabled (not read-only)
  • Order quantity matches the exchange's precision/step size for that symbol
  • Order size is above the exchange's minimum notional/quantity for that symbol
  • Account position mode (one-way vs. hedge) matches what your automation expects
  • Exchange-side API key IP restrictions (if any) include your server's IP

If you're still stuck

Once you've worked through all five layers, you've at minimum narrowed the problem down to one specific side — TradingView's alert configuration, the network path, or the exchange account. That alone turns "it just doesn't work" into a concrete, fixable problem. For the full setup walkthrough from scratch, see our TradingView webhook tutorial.

My TradingView alert fired on the chart but my server got nothing — where do I start?
Start at Layer 2: check whether the alert is showing a webhook send error of its own. If there's no error, move to Layer 3 and test your endpoint directly with curl to see whether the request is reaching your server at all.
Why did my webhook stop working after it ran fine for a while?
Check Alert Manager for a red Stopped — Expired status first. Alerts have a default maximum lifetime of two months (open-ended only on Premium and Ultimate), and a separate rule auto-disables alerts that go untriggered and unedited for over a year.
What's the actual difference between Once Per Bar and Once Per Bar Close?
Once Per Bar fires as soon as the condition is met, without waiting for the bar to finish — which makes it prone to repainting on scripts whose values still move before the bar closes. Once Per Bar Close waits for the bar to actually close first, which is the safer default for most trading logic.
Does TradingView automatically retry a failed webhook?
Only for 5xx server errors — it retries after 5 seconds, up to 3 times (4 attempts total). A 4xx response or a timeout is treated as delivered and is not retried at all, so a slow endpoint can silently lose signals.
How do I test whether my webhook URL is actually reachable?
Hit it directly with curl from an external machine using the same method and payload shape TradingView would send. If curl gets a fast 200, your server is fine and any remaining problem is upstream — an IP allowlist, a timeout, or a TradingView-side alert issue.

Get started

Ready to ship what you just learned?

TVSBot turns a working TradingView webhook into live orders across 7 exchanges — non-custodial, with async signal processing, dry-run testing, and a full signal replay log so you can see exactly what happened to every alert.

Start free