TradingView webhooks9 min readPublished Aug 30, 2026

Pine Script Webhook JSON Templates for Futures

A practical library of valid TradingView webhook JSON patterns for futures entries, dynamic Pine messages, dry runs, sizing guardrails, and tick-based protection.

By HexTrade1,933 wordsSources reviewed Aug 30, 2026
Layered Pine Script, JSON validation, webhook routing, and futures broker order cards

What JSON should a futures TradingView webhook send?

Send one valid JSON object containing the documented route and order intent: `platformType`, exact `accountId`, `ticker` or `symbol`, `action` or `side`, and `quantity`. Add optional controls only after the minimal message passes a dry run. Keep credentials out of both the webhook URL parameters and message body, and treat the private endpoint itself as a secret.

A useful template is deliberately boring. Stable keys make failures easy to compare, while TradingView placeholders supply values that truly change at alert time. HexTrade documents lowercase platform slugs, an account ID copied from Accounts, a destination instrument, quantity, and a buy or sell instruction. The chart can generate the decision, but the payload must describe the instrument understood by the connected broker. Do not infer the destination from a chart label when the account trades a different naming convention.

TradingView determines the request content type from the final alert message. A syntactically valid JSON message is sent as `application/json`; anything else is sent as `text/plain`. That distinction is operational, not cosmetic, because a JSON-only receiver can reject an otherwise sensible-looking message. Validate the rendered alert, not merely the Pine source string. Quotes introduced by dynamic text, missing commas, and unresolved assumptions about numeric formatting can all change the document that actually leaves TradingView.

  • Route fields answer where the instruction goes: platform and exact account.
  • Intent fields answer what the receiver should attempt: symbol, side, and quantity.
  • Guardrail fields constrain the attempt; they do not prove that a broker accepted or filled it.
  • Labels such as `strategyName`, `alertName`, `note`, or `tags` help later correlation without carrying secrets.
A futures webhook message has four contractsPine eventChoose the realtime condition or strategy order…JSON documentProduce one syntactically valid object with sta…RouteName the documented platform, exact account ID,…Execution evidenceCompare sender status, receiver result, and the…
A futures webhook message has four contracts. Validate each layer independently before interpreting an accepted request as a broker fill.

What is the safest minimal alert-dialog template?

Start with the smallest documented HexTrade contract and keep placeholder output inside JSON strings. Replace the account and platform literals yourself; let TradingView replace only market or strategy values. This pattern minimizes dynamic string construction, makes the final body easy to inspect, and gives every failure a small number of possible causes before optional risk fields are introduced.

Paste the template into the TradingView alert Message field after selecting the intended strategy condition. The documented strategy placeholders resolve the simulated order action and contracts at the event. Quoting those placeholders preserves valid JSON whether the rendered value is text or a numeric-looking string; the downstream contract can interpret quantity according to its documented schema. Set `ticker` to the symbol the connected account trades rather than assuming the chart's full symbol is accepted by the broker.

Use a test account or `dryRun` before removing the validation flag. HexTrade documents that `dryRun: true` returns the planned trade without sending an order and without advancing its in-memory cooldown or daily-trade counters. A successful dry run therefore verifies parsing and planning, not live authorization, exchange hours, margin, prop-firm policy, or fill behavior. Preserve that distinction in your test notes so a clean payload test is not mistaken for end-to-end execution proof.

Minimal strategy order-fill message with validation enabled
{
  "ticker": "MNQ",
  "action": "{{strategy.order.action}}",
  "quantity": "{{strategy.order.contracts}}",
  "platformType": "tradovate",
  "accountId": "replace_with_exact_account_id",
  "strategyName": "opening-range-v1",
  "dryRun": true
}

The account ID is not a broker password

Use the exact account identifier documented in HexTrade, but never add broker usernames, passwords, API secrets, or other credentials to the payload. Regenerate the private webhook URL if it is exposed.

How do you build valid dynamic JSON inside Pine Script?

Build a complete JSON string with double-quoted keys and escaped quotes, convert every calculated value explicitly, and call `alert()` only inside the condition that should emit. Prefer `str.tostring()` with an appropriate format for Pine values. Use a bar-close frequency when the strategy requires confirmed bars, then inspect a rendered sample for every long, short, and edge-case branch.

Dynamic construction is useful when the message includes values that cannot be represented by alert-dialog placeholders alone. It is also easier to break. Pine does not provide a dedicated JSON serializer, so your script owns commas, quotes, escaping, boolean literals, and conversion of `na` values. Keep free-form user text out of the payload unless you also control escaping. A strategy name with an unexpected quote can invalidate an entire message even though every trading field is correct.

The example emits a compact object only when a confirmed crossover occurs. It uses a literal destination and a calculated quantity, then adds `dryRun` during commissioning. It is an educational pattern, not a complete strategy: the signal and sizing rules must be independently tested. If you instead customize strategy order-fill messages through the `alert_message` parameter, put `{{strategy.order.alert_message}}` in the alert dialog so TradingView sends that generated string when the broker emulator fills the simulated order.

  • Exercise every conditional branch; one valid long payload does not prove the short payload.
  • Decide how `na`, empty strings, and unexpected decimals should behave before alert creation.
  • After editing Pine or inputs, delete and recreate the running alert because TradingView stores a snapshot.
Dynamic JSON built by an indicator-style alert call
//@version=6
indicator("Webhook JSON example", overlay = true)
fast = ta.ema(close, 9)
slow = ta.ema(close, 21)
longSignal = ta.crossover(fast, slow) and barstate.isconfirmed

if longSignal
    payload = '{"ticker":"MNQ","action":"buy","quantity":"1",' +
      '"platformType":"projectx",' +
      '"accountId":"replace_with_exact_account_id",' +
      '"price":"' + str.tostring(close, format.mintick) + '",' +
      '"dryRun":true}'
    alert(payload, alert.freq_once_per_bar_close)

How should take-profit and stop-loss ticks be added?

Add `tp` and `sl` only after confirming the instrument's tick size and the destination's supported behavior. HexTrade documents both values as ticks, not dollars or raw price offsets. A value of 20 therefore means twenty minimum price increments for that instrument; it does not mean twenty currency units, twenty points, or a universal amount of risk.

Tick semantics make a payload portable in shape but not in economic effect. Different futures contracts have different tick sizes and tick values, and the same tick count can represent materially different price distance and money exposure. Verify the current contract specification from the exchange and the exact contract selected at the broker. Then calculate risk using actual quantity rather than copying a protective count from another symbol or from a full-size contract to its micro counterpart.

Keep the payload explicit during review. A reviewer should be able to see the route, instrument, size, and tick distances without reverse-engineering a compressed Pine expression. `maxQty` can place a documented hard cap on size, while `allowedSymbols` can restrict instruments. Those controls reduce configuration risk but do not replace strategy-side sizing, broker limits, or account-level risk rules. A protective request can still be rejected, unsupported, or behave differently across execution rails.

Documented payload fields and the question each must answer
FieldMeaningReview question
tpTake-profit distance in ticksWas the tick distance calculated for this exact destination contract?
slStop-loss distance in ticksDoes quantity times tick exposure fit the account's approved risk?
maxQtyHard quantity capWill an unexpectedly large placeholder be constrained?
allowedSymbolsInstrument whitelistWill a chart or mapping mistake be rejected before routing?
Protective tick fields added to the validated core
{
  "ticker": "MES",
  "action": "{{strategy.order.action}}",
  "quantity": "{{strategy.order.contracts}}",
  "platformType": "rithmic",
  "accountId": "replace_with_exact_account_id",
  "tp": "40",
  "sl": "16",
  "maxQty": 1,
  "allowedSymbols": ["MES"],
  "dryRun": true
}

When should a template use order fills instead of `alert()`?

Use strategy order-fill alerts when the webhook should correspond to the TradingView broker emulator's simulated fill event; use `alert()` when your code must emit on a programmable condition. Do not treat either event as confirmation from the real destination broker. The webhook begins a separate external request whose accepted, rejected, and filled states must be observed independently.

An order can be created by Pine before the broker emulator fills it. TradingView's order-fill alert exists at that emulated execution moment and can carry a per-order dynamic `alert_message`. That is often a cleaner trigger for a strategy whose external route is intended to follow simulated fills. By contrast, `alert()` can describe indicator conditions, warnings, or pre-order logic and can create fully dynamic strings, but it cannot directly fire in response to an emulator fill that occurs after the script hands the order over.

`alertcondition()` serves a different use case. It defines selectable triggers in indicators, requires a constant message at compile time, and relies on placeholders for changing values. It has no effect as an alert trigger in strategies. Choose the event primitive first, then choose a JSON construction technique. Trying to repair the wrong event model with payload fields usually produces timing confusion, repeated messages, or an external order that does not correspond to the intended strategy transition.

  • Indicator with named selectable conditions: consider `alertcondition()` and a validated dialog template.
  • Indicator or strategy with runtime-computed JSON: consider a guarded `alert()` call.
  • Strategy synchronized to emulator executions: consider order-fill events and `alert_message`.
  • Any external route: reconcile the receiver and broker state; a TradingView event is not a live fill.

What validation sequence should every template pass?

Validate syntax, route, semantics, and live outcome in separate gates. First render and parse the exact JSON. Next use `dryRun` to verify the planned route. Then test the smallest permitted order in an appropriate account and session. Finally reconcile TradingView's alert log, the receiver's execution record, and the broker's order state before increasing size or account count.

Begin with deterministic examples. Trigger one long, one short, one exit, one unexpected quantity, and one disallowed symbol. Confirm that malformed or unsafe messages fail visibly rather than being silently coerced. Keep the TradingView alert active and remember that changing the chart, script, or inputs does not update an existing server-side alert snapshot. Recreate it deliberately, then record the new version in `strategyName`, `alertName`, `note`, or another documented label.

TradingView webhooks require two-factor authentication and only target ports 80 or 443. The receiver must answer within three seconds or TradingView cancels the request. These transport facts should shape testing: inspect the Webhook status column in the alert log and avoid endpoints that perform slow work before acknowledging safely. If a private HexTrade URL leaks, regenerate it. Never post the URL or a credential-bearing message in chat while asking for help.

  1. 1

    Parse the rendered body

    Capture a non-sensitive sample from each branch and verify it is valid JSON with the intended types and values.

  2. 2

    Plan without ordering

    Set `dryRun: true`, confirm the account, platform, symbol, side, quantity, and optional controls, then save the result.

  3. 3

    Prove one live path

    Use the smallest approved size and reconcile the alert event, receiver result, and destination account.

  4. 4

    Introduce one option at a time

    Add protection, time windows, mappings, or fan-out separately so a failed test still has a narrow cause.

Sources and methodology

HexTrade Research uses official product, exchange, regulator, and vendor documentation. Policies and platform behavior can change; follow the linked source and verify current terms before trading.

  1. 1.How to configure webhook alerts TradingView, accessed Aug 30, 2026
  2. 2.Pine Script alerts TradingView, accessed Aug 30, 2026
  3. 3.Pine Script alerts FAQ TradingView, accessed Aug 30, 2026
  4. 4.Using credentials for webhooks TradingView, accessed Aug 30, 2026
  5. 5.TradingView webhook automation HexTrade Docs, accessed Aug 30, 2026
  6. 6.Pine Script webhook payloads HexTrade Docs, accessed Aug 30, 2026
  7. 7.Micro E-mini S&P 500 contract specifications CME Group, accessed Aug 30, 2026

Frequently asked questions

Does TradingView automatically send JSON for every alert?

No. TradingView sends `application/json` only when the final alert message is valid JSON. Otherwise it sends the body as `text/plain`. The receiver may reject that request. Validate the rendered message after placeholders or Pine string construction, not just the template's appearance in the editor.

Can broker credentials go in a Pine webhook template?

No. TradingView explicitly warns against putting passwords, logins, or sensitive credentials in either the webhook URL or message. Use the receiver's private authenticated endpoint and documented account reference. Keep the HexTrade webhook URL private and regenerate it from Accounts if it is exposed.

Are `tp` and `sl` dollar amounts?

No. HexTrade documents them as tick counts. Convert the desired price distance using the exact instrument's minimum tick and evaluate money exposure using current contract specifications and quantity. Never copy the same number across contracts while assuming it represents the same risk.

Does a successful dry run prove the broker will fill?

No. It proves that HexTrade can validate and plan the documented request without placing an order. It does not exercise live broker authorization, market state, margin, prop rules, order support, price, or fill. Follow with a controlled smallest-size test and reconcile the broker.

Why did an edited Pine template keep sending the old payload?

TradingView stores a snapshot of the script, inputs, chart symbol, and timeframe when an alert is created. Later edits do not mutate that running alert. Delete and recreate it after a reviewed change, then verify the new rendered payload before enabling live execution.

Next step

Put the research into a controlled workflow

Start small, verify the broker and account rules, and keep risk controls between every signal and live order.

Explore webhook automation

Continue reading

Educational content only. Futures are leveraged products and can produce losses greater than the amount you expected to risk. This article is not financial, legal, or prop-firm compliance advice.