Common TradingView Webhook Errors and How to Fix Them

TradingView reports that your alert fired, not that your order was placed. Here are the webhook failures that break most automations - silent delivery, auth rejections, malformed JSON, symbol mismatches, duplicates - and the specific fix for each.

Common TradingView Webhook Errors and How to Fix Them

Your strategy triggered. The alert log shows it fired. And nothing happened on the exchange. Most common TradingView webhook errors look exactly like this: a chart event that clearly occurred, a receiving endpoint that never heard about it, and no obvious place to look. TradingView does not surface delivery failures in the interface, so a broken automation can run for days looking healthy while every single order quietly dies in transit.

This guide walks through the failures that account for the overwhelming majority of broken webhook automations, in the order you should check them. Each section covers what the failure looks like from your side, what is actually happening underneath, and the specific fix.

Why Webhook Failures Are So Hard to See

A TradingView webhook is a one-way message. When your alert fires, TradingView sends an HTTP POST to the URL you configured and then forgets about it. It does not retry meaningfully, it does not warn you when the response is an error, and it does not show you the response body. If your endpoint returns a 401, TradingView's alert log still says the alert triggered.

That asymmetry is the root of most debugging confusion. The alert firing and the order being placed are two separate events connected by a fragile link, and only one of them is visible in the platform you are watching. The practical consequence: never treat "the alert fired" as evidence that anything downstream worked. You need visibility on the receiving end, which is why the debugging checklist later in this guide starts by capturing the raw request rather than staring at the chart.

Error 1: The Alert Never Sends a Request at All

Before blaming the payload or the exchange, confirm a request left TradingView.

Three causes dominate. First, the Webhook URL checkbox in the alert's Notifications tab is unchecked — the URL is saved but the delivery channel is off. Second, the alert is set to Once Per Bar when you need Once Per Bar Close, or vice versa, so it is firing at a moment you are not watching. Third, the alert expired; TradingView alerts have plan-dependent expiry, and an expired alert silently stops.

There is also a plan requirement here that catches new users: webhook notifications require a paid TradingView plan. On a free plan the field may appear but never deliver.

Fix: open the alert, confirm the webhook checkbox is ticked and the URL is complete including `https://`, verify the trigger condition, and check the expiry date. Then use a request-capture endpoint to confirm bytes actually arrive. Our walkthrough on testing a TradingView webhook locally with ngrok shows how to see the raw request before it ever reaches an exchange.

Error 2: 401 or 403 — Authentication Rejected

The request arrives and is refused. This is the most common failure after setup changes, because TradingView cannot send custom HTTP headers. Anything your receiver needs for authentication has to travel in the URL or in the JSON body.

Typical causes: a token in the body that no longer matches after a key rotation; a secret pasted with a trailing space or a line break; an endpoint expecting an `Authorization` header that TradingView simply cannot send; or an HMAC signature computed over a different string than the one the receiver verifies.

Fix: move authentication into the payload or the URL path, and regenerate the secret cleanly rather than editing it in place. If you use signed requests, confirm both sides sign the exact same raw body bytes — whitespace and key ordering matter. The mechanics are covered in detail in our guide to securing a TradingView webhook with HMAC signing.

Error 3: 400 Bad Request — Malformed JSON

The receiver got the message and could not parse it. TradingView alert messages are plain text; JSON is a convention you impose, and nothing in the alert box validates it.

The usual culprits are smart quotes pasted from a document instead of straight quotes, a trailing comma after the last field, an unquoted string value, or a Pine Script placeholder that expands into something unexpected. `{{strategy.order.comment}}` inserting a comment that itself contains a quote character will break the surrounding JSON instantly.

Fix: paste the message into a JSON validator before saving the alert, type quotes directly rather than pasting them, and keep placeholders in numeric positions unquoted and text positions quoted. If a placeholder can contain free text, either sanitize it in Pine or drop it from the payload. A known-good structure is laid out in our reference on structuring a TradingView webhook JSON payload for orders.

Error 4: The Symbol Does Not Match the Exchange

The payload parses, authentication passes, and the exchange rejects an unknown instrument. TradingView tickers and exchange API symbols are different namespaces. A chart showing `BINANCE:BTCUSDT` is not automatically the string the API expects, and `{{ticker}}` may expand with a venue prefix, a perpetual suffix, or a delimiter the exchange does not recognize.

Spot and derivatives markets compound this. The same underlying pair often has one symbol on the spot API and a different one on the futures API, routed to a different base endpoint entirely.

Fix: hard-code the symbol in the alert message when you run one alert per instrument — it removes an entire failure class. If you need `{{ticker}}` for a multi-symbol strategy, map the value explicitly on the receiving side and reject anything not in the map rather than passing an unknown string through to the exchange.

Error 5: One Alert, Two Orders

Duplicates are more damaging than silence, because they leave your real position out of sync with what your strategy believes it holds.

They arise from repainting intrabar conditions that fire and unfire, from `Once Per Bar` on a condition true across several ticks, from a retry after an ambiguous timeout, or from a duplicated alert left running after you cloned one to edit it.

Fix: use Once Per Bar Close for anything that trades real size, and send a deterministic client order ID with every order so a repeated request is recognized rather than executed twice. Audit your active alert list regularly for forgotten clones.

Error 6: The Exchange Accepts the Request but Rejects the Order

Here the plumbing is fine and the trading parameters are not. Common rejections include quantity below the venue's minimum notional, price or size precision beyond the allowed decimal places, insufficient balance in the specific wallet the order routes to, leverage or margin mode not configured for the contract, and API keys lacking trade permission.

That last one is worth isolating. A key created for read access will authenticate perfectly and refuse every order, which reads like an intermittent bug. It should have trade permission and no withdrawal permission — see why trade-only API keys matter for how to set that up.

Fix: read the exchange's rejection code rather than guessing, round sizes to the venue's step size before submitting, and confirm funds sit in the wallet the order actually draws from.

Error 7: Timeouts, Rate Limits, and Server Errors

Transient failures behave differently from deliberate rejections: the same request would likely succeed a moment later. Rate limiting (HTTP 429), gateway timeouts during volatile periods, and temporary maintenance on a venue all fall here.

Fix: retry with exponential backoff and jitter, cap the attempts, and always send the same client order ID on the retry so a duplicate cannot be created. Treat a timeout as unknown rather than failed — query order status before resubmitting. The distinction between transient and permanent failures is unpacked in our guide to handling failed and rejected orders in a trading bot.

A Debugging Checklist That Finds Most Failures

Work outward from the chart, and stop at the first step that fails:

  • Confirm the alert triggered in TradingView's alert log.
  • Capture the raw request at a test endpoint to prove delivery.
  • Validate the received body parses as JSON.
  • Check the authentication field or signature matches.
  • Verify the symbol string against the exchange's instrument list.
  • Confirm API key permissions include trading.
  • Read the exchange's raw response code, not a summarized one.

Best Practices That Prevent Most Webhook Errors

  • Test every alert against a capture endpoint before pointing it at real funds.
  • Hard-code symbols and sizes where possible; use placeholders only where they earn their place.
  • Use Once Per Bar Close for anything trading real size.
  • Send a deterministic client order ID on every request.
  • Log the full request and the exchange's full response for every signal.
  • Rotate secrets on a schedule and update alerts in the same session.
  • Keep API keys trade-only, with withdrawal permission disabled.

Frequently Asked Questions

Why did my TradingView alert fire but no order was placed?

The alert firing and the order being placed are separate events. TradingView reports the trigger, not the delivery outcome, so a rejected or unparseable request looks identical to a successful one from the chart. Capture the request at your endpoint and read the response code to find where the chain broke.

Can TradingView send custom HTTP headers with a webhook?

No. TradingView sends the alert message as the request body without configurable headers, which is why authentication has to live in the URL or inside the JSON payload. Endpoints that require an `Authorization` header need an alternative scheme such as a token field or a signature over the body.

Why does my webhook work in testing but fail on live markets?

Test conditions are usually calm and single-symbol. Live markets add rate limits during volatility, precision and minimum-notional rules that only bite at certain sizes, and multi-symbol payloads that expose symbol-mapping gaps. Move to live in stages, with small size and full logging, rather than switching everything at once.

How do I stop a retry from creating a duplicate order?

Attach a client order ID derived deterministically from the signal, and send that identical ID on every retry. Exchanges that support client order IDs recognize the repeat and decline to create a second order, which makes an ambiguous timeout safe to retry.

Do webhook alerts require a paid TradingView plan?

Yes. Webhook notifications are a paid-plan feature, and alert count and expiry limits also vary by plan. If the webhook field appears configured but nothing ever arrives at your endpoint, plan level is worth checking early.

Most webhook errors are not strategy problems — they are delivery problems, and they are fixable once you can see where the message stops. If you would rather not maintain that plumbing yourself, SignalToExchange is a non-custodial relay that validates each incoming signal, submits the order with a deterministic client order ID, and returns the exchange's actual response. Your funds stay on your own exchange and connect through trade-only API keys with no withdrawal access. Request access or start your free trial.

Automated trading involves risk. SignalToExchange is execution infrastructure and does not provide financial advice, trading signals, or guarantees of any kind.

Secure Signal Routing Infrastructure

Non-custodial execution. Trade-only API keys. Independent infrastructure built for reliability.

Request Early Access

Trade-only API key enforcement. No withdrawal permissions. No custody.