BOTS & TRADINGVIEW

TradingView Webhook JSON Alert Messages: The Exact QATS Format

Every field QATS reads from a TradingView alert, with copy-ready messages for entries, exits and protection, and the fixes for common refusals.

By the QATS team7 min read9 sections

A TradingView webhook JSON alert message is the text TradingView posts to a URL when an alert fires, and on a prop account it is the whole order: symbol, side, size, order type and protection. TradingView does not check that text, so a missing quote or a misspelled field only shows up as a refused signal after the market has moved.

Below is the format QATS accepts, field by field, with examples for entries, exits, protection and Pine strategies, then the alert log and the most common errors.

01/ 09

How an alert reaches your QATS account

In QATS, open Profile → External connections → Trade from charts → TradingView alerts (or Keys & connections on the sandbox) and choose Create webhook. Each webhook belongs to one account, expires after the period you pick and by default accepts only TradingView’s servers. Your personal URL is shown once and ends with your key, so treat it like a password.

In TradingView, tick Webhook URL under Notifications, paste that URL and replace everything under Message with a QATS JSON message. TradingView requires two-factor authentication and a plan with webhooks.

Help CenterTradingView and QATS step by step

02/ 09

TradingView webhook JSON alert message fields QATS reads

The message must be a single JSON object with case-sensitive field names. Numbers may be sent as numbers or quoted strings, which matters because TradingView placeholders such as {{close}} arrive as text. An entry needs exactly one size field.

FieldValuesWhat it does
symbol{{ticker}} on a supported chartBINANCE:BTCUSDT.P becomes BTCUSDT; a TradFi chart such as OANDA:XAUUSD maps only if that perpetual is in the QATS catalogue and your plan
actionbuy, sell, close, flatten, cancel_alllong and short also work for buy and sell; leave it out for a Pine strategy sync
typemarket (default), limit, stoplimit and stop need price
priceA number or {{close}}Entry price for limit and stop; the price-check reference on a market entry
notionalUsd, quantity, lotsExactly oneUS dollars, coins of the base asset, or QATS lots
stopLoss, takeProfitPricesProtective levels; stopLossPercent and takeProfitPercent set them as a distance instead
maxDeviationPct0.01 to 2Price-check tolerance in percent on a market entry; 0.25% when omitted
reduceOnlytrue or falseOn buy or sell, only reduce an open position
idTextLets QATS ignore a repeated delivery of the same event
position, positionSizelong, short or flat, plus a sizePine strategy sync: QATS trades the difference
Fields accepted in a QATS TradingView alert message
03/ 09

Entry examples: market, limit and stop

A market buy of $1,000 with a 1% stop and a 2% target. For a short, change "buy" to "sell":

{"symbol": "{{ticker}}", "action": "buy", "notionalUsd": 1000, "price": "{{close}}", "stopLossPercent": 1, "takeProfitPercent": 2}

With price on a market entry, QATS refuses the fill with PRICE_REFERENCE_MISMATCH if its own price is more than 0.25% away, which catches a chart of another market or a price that ran while the alert was queued. maxDeviationPct changes the tolerance.

A limit buy that rests with its stop and target attached (the price is only an example):

{"symbol": "{{ticker}}", "action": "buy", "type": "limit", "price": 80000, "notionalUsd": 1000, "stopLossPercent": 1, "takeProfitPercent": 2}

A stop entry that sells a breakdown, with protective levels as prices:

{"symbol": "{{ticker}}", "action": "sell", "type": "stop", "price": 76000, "quantity": 0.01, "stopLoss": 77500, "takeProfit": 73000}

notionalUsd is converted into lots at the current price (or at the order price for a limit or stop) and rounded down to the instrument step, so the filled size can be slightly smaller than the dollars you sent.

04/ 09

Stop loss and take profit in the same message

Use stopLoss and takeProfit for prices, or stopLossPercent and takeProfitPercent for a distance from the entry. Send one form per leg; both forms for the same leg are refused as AMBIGUOUS_PROTECTION.

On a market entry, QATS submits the stop and target after the fill, from the fill price, and the log shows a result for each. A limit or stop entry rests with both attached as a bracket, so one with only a stop or only a target is refused (BRACKET_NEEDS_BOTH). A stop on the wrong side of the entry gets INVALID_STOP_LOSS.

Each instrument holds one net position. A market sell against an open long reduces it; a larger one closes it and opens the rest as a short. An alert that only reduces a position sets no new stop or target.

05/ 09

Exit examples: close, partial close, flatten and cancel

A close never carries the price check, so a late exit alert still closes. If there is no position, the log says Nothing to do.

  • Close the whole position on the chart symbol: {"symbol": "{{ticker}}", "action": "close"}
  • Reduce it by $500 without reversing, as a reduce-only order: {"symbol": "{{ticker}}", "action": "close", "notionalUsd": 500}
  • Close every position and cancel every order on the account: {"action": "flatten"}
  • Cancel working entry orders only: {"action": "cancel_all"}. Stops and targets on open positions stay in place.
06/ 09

Pine strategy alerts: sync the position, not the signal

For a Pine strategy, create one alert on the strategy with the Order fills condition and this message:

{"symbol": "{{ticker}}", "position": "{{strategy.market_position}}", "positionSize": "{{strategy.market_position_size}}", "id": "{{strategy.order.id}}-{{timenow}}"}

TradingView fills in the target state (long, short or flat) and its size; QATS trades only the difference from the account’s position, so flat closes the instrument. The id stops a repeated delivery from trading twice. Strategy size units can differ from QATS lots, so check the first fills on the sandbox.

07/ 09

Read the alert log after every signal

In QATS, open TradingView alerts → Alerts → Refresh. Each signal shows its time, symbol and outcome: Done, Nothing to do (the account was already in that state) or Refused with a code and a reason. A Done row can hold several results, such as the entry, stop and target; read each, then check positions and working orders in the terminal.

No row can mean TradingView never sent the webhook, or QATS rejected an invalid key before logging: check TradingView’s alert history, the URL, the webhook’s expiry and its account. Recreating an alert can send another command, so check the log before resending.

08/ 09

Common errors and how to fix them

CodeUsual causeFix
ALERT_NOT_JSONTradingView’s default text left in Message, or a missing quote or commaPaste a complete QATS message and check its brackets and quotes
PLACEHOLDER_NOT_REPLACEDA strategy placeholder in an alert that is not on a strategyCreate the alert on the strategy with Order fills, or use fixed values
UNKNOWN_SYMBOLThe chart symbol is not a QATS instrumentChart the perpetual, such as BINANCE:BTCUSDT.P, and send {{ticker}}
INVALID_ALERT_ACTIONaction missing or misspelledUse buy, sell, close, flatten or cancel_all
SIZE_REQUIRED, AMBIGUOUS_SIZENo size field, or more than oneSend exactly one of notionalUsd, quantity or lots
SIZE_BELOW_ONE_LOTThe size rounds down to less than one lotIncrease the size to at least one instrument step
PRICE_REQUIREDA limit or stop entry without priceAdd a valid price for the instrument
BRACKET_NEEDS_BOTHA resting entry with only a stop or only a targetSend both levels, or use a market entry
PRICE_REFERENCE_MISMATCHThe QATS price is too far from the alert’s priceCheck the chart shows the same perpetual, then wait for a fresh signal
Refusal codes in the QATS TradingView alert log
09/ 09

Risk rules still apply to every alert

A webhook order goes through the same server-side checks as one placed in the terminal. On a QATS Crypto evaluation that means a 10% profit target, a 4% daily loss limit, a 6% end-of-day trailing maximum loss that stops trailing at the starting balance, a 40% consistency rule and 2 minimum trading days, with up to 20× on BTC and ETH, 10× on large caps and 5× on other coins. Margin, risk and plan refusals appear in the log; check Risk center rather than resending.

QATS evaluations and initial funded accounts are simulated. An account in Bybit native / Bybit Demo mode trades directly through Bybit and does not receive a QATS webhook. Test every alert on the free sandbox, which applies the same risk rules, before a paid evaluation.

Related guideTradingView prop firm trading: the three options

FAQ4 questions

Frequently asked questions

01What should a TradingView webhook message contain for QATS?

A JSON object with symbol (usually {{ticker}}), action and, for entries, exactly one size field: notionalUsd, quantity or lots. Optional fields set the order type, price, stop loss, take profit and price-check tolerance.

02Do I need to put my key in the alert message?

No. The personal webhook URL ends with your key, so the message carries only the order. Older webhooks with a token field in the message still work, but a URL and message with different keys are refused.

03Why did my alert fire but no trade appear?

A fired alert is only a delivery. In the QATS alert log, Refused gives the code and reason, Nothing to do means the account was already in that state, and no row points to the URL, expiry or key.

04Can a TradingView alert set a stop loss and take profit?

Yes. Add stopLoss and takeProfit as prices, or stopLossPercent and takeProfitPercent as distances. A market entry receives them after it fills; a limit or stop entry needs both and rests with them as a bracket.

Written by the QATS team

The team behind QATS Prop. Every QATS figure comes from the published plan lineup; spotted something outdated? Email support@qats.us.

Published Updated

Educational content, not investment advice. QATS evaluations and initial funded accounts are simulated; payouts depend on eligibility, verification and the applicable agreement.