First, what is a webhook?
Webhooks are automated messages sent from applications when something happens. They have a JSON message that can contain a payload of data and are sent to a unique URL.
In the context of automated trading, the webhook JSON message contains all the information about the trade signal like what ticker to buy and at what price. Here is an example simple webhook and JSON message.
POST https://webhooks.traderspost.io/trading/webhook/{uuid}/{password}
{
"ticker": "AMD",
"action": "buy",
"signalPrice": 143.12,
"quantity": 1,
"takeProfit": {
"percent": 10
},
"stopLoss": {
"type": "stop",
"percent": 5
}
}
This example would route to a TradersPost strategy, and then to one or more strategy subscriptions where the trade for AMD would be executed to buy 1 share of AMD with a take profit order at 10 percent above the potential entry price of 143.12 (assuming no slippage) and a stop market order 5 percent below the entry price of 143.12.
Example Payloads
Here are some examples of default JSON payloads that you can use to send alerts from various trading platforms to your webhook URL:
| TradingView Indicator | TradingView Strategy |
|---|---|
| |
| TrendSpider | Custom Code |
|---|---|
| curl -X POST -H 'Content-Type: application/json' -d '{"ticker": "MNQ", "action": "buy"}' https://webhooks.traderspost.io/trading/webhook/98a90567-fac3-42b9-8c5d-97c4ec1710ba/6de6c4a446497f11debba25b90e90462 |
Webhook Reference Documentation
A full, technical reference document is available here and covers every available request body property and possible response bodies.
Webhook Field Reference
Here is a quick reference list of all the supported fields and values for the TradersPost webhook JSON message. These fields are case-sensitive and should be used in the way they are presented here. Fields other than the ones listed here can be sent, but will be ignored by TradersPost. This means you can send extra fields for debugging purposes, but we do recommend using the "extras" field for this purpose.
ticker
REQUIRED FIELD: ticker is required with all JSON messages.
The ticker symbol of the financial instrument (e.g., AAPL, SPY 250624C596, MNQU2025, BTCUSD).
Note: For futures contracts, continuous symbols like NQ1! are automatically mapped to the front-month contract according to our rollover schedule. Since this schedule may differ from other platforms like TradingView, we strongly recommend using explicit futures contract symbols rather than continuous symbols.
action
REQUIRED FIELD: action is required with all JSON messages.
The action or signal type used to determine what type of order to execute.
Possible values: buy, sell, exit, reverse, breakeven, cancel, add
Put options: By default, action=buy buys long puts and action=sell sells short puts. Enable the Invert puts strategy setting to swap this mapping (action=buy → sell short puts, action=sell → buy long puts). Use Invert puts when your strategy runs on the underlying chart and sends buy/sell for the stock's direction but trades puts instead of shares. When option type is Both, put contracts selected from the option chain always use inverted logic regardless of this setting.
Example for ticker and action
{
"ticker": "MSFT",
"action": "buy"
}
You can add to an existing open position by using the add action. This will add to the existing open position regardless of if Allow add to position is checked in your strategy subscription settings.
{
"ticker": "SPY",
"action": "add"
}
Cancelling Open Orders
Cancel all the open orders for the given ticker.
{
"ticker": "SPY",
"action": "cancel"
}
You can also control the open order canceling functionality with the cancel property so you can combine it with other actions. For example, if you want to exit the open position and cancel open orders first, you can use the following.
{
"ticker": "SPY",
"action": "exit",
"cancel": true
}
If you have order canceling enabled in your strategy subscription settings and you want to disable the order canceling for a signal, you can send cancel: false as well.
{
"ticker": "SPY",
"action": "exit",
"cancel": false
}
You can optionally send a cancelOrderType to filter which orders will be canceled by order type. The below example will only cancel open orders with a type of stop.
{
"ticker": "SPY",
"action": "cancel",
"cancelOrderType": "stop"
}
Reverse
The reverse action exits the open position and enters on the opposite side. It overrides strategy side restrictions and side-swapping settings, so you can flip from long to short (or vice versa) in a single signal.
{
"ticker": "SPY",
"action": "reverse"
}
Breakeven
The breakeven action moves your stop loss to the average entry price of the open position. You must have an open position, and orderType must be stop or stop_limit. You do not need to send stopPrice or limitPrice — TradersPost fills them from the position's average entry price. Optionally send breakevenOffset to offset the stop from entry, or configure Exit breakeven offset in your strategy settings.
{
"ticker": "SPY",
"action": "breakeven",
"orderType": "stop"
}
{
"ticker": "SPY",
"action": "breakeven",
"orderType": "stop",
"breakevenOffset": 5
}
sentiment
The sentiment field allows you to specify what the sentiment of the position should be after executing the trade.
Supported values: bullish / long or bearish / short, and flat
You can include the sentiment field with a value of flat to exit a bullish or bearish position without entering the opposite position. This means that it will always exit the full quantity of the open position without entering a new position on the other side.
If you send a JSON message with action set to sell and sentiment set to flat, it will exit a bullish position without entering a bearish position. Similarly, if you send action as buy and sentiment as flat, it will exit a bearish position without entering a bullish position.
You are also able to have a sentiment of bullish or bearish. This is useful whenever you are partially exiting a position and you aren't fully exiting the position and you aren't changing sides. For example, if you are in a bearish short position with a quantity of 10 and you send a JSON message with action set to buy, quantity set to 5 and sentiment set to bearish, this means that after executing the buy, you will still be in a bearish position with a quantity of 5.
signalPrice (price)
Note: signalPrice is optional. price is an alias for signalPrice.
This is the market price at the time your TradingView (or other platform) alert is triggered. You can pass it using the {{close}} placeholder in your alert message. TradersPost uses this value to estimate slippage (the difference between the alert price and the actual fill price) so you can see how much delay or movement occurred between your signal and the trade execution.
You can also send price which is an alias for signalPrice.
It is only necessary when you are using relative take profit or stop losses and the broker does not support fetching quotes to be able to perform the calculation. It is also used to determine the P&L on your trade if the quote or fill price isn't available from your connection.
Here is an example where the price at the time of the signal was $18500 and we specify that we want a $100 take profit. So a take profit order with a limit price of $18600 will be calculated and sent to your broker along with your market entry order.
{
"ticker": "MNQ",
"action": "buy",
"orderType": "market",
"signalPrice": 18500,
"takeProfit": {
"amount": 100
}
}
If you are using limit orders, then the limitPrice you send will be used to calculate your take profit.
{
"ticker": "MNQ",
"action": "buy",
"orderType": "limit",
"limitPrice": 18500,
"takeProfit": {
"amount": 100
}
}
limitPrice
The limit price of the buy or sell action if limit orders are used. If you omit this value and limit orders are used, the current market price will be used when the trade is executed.
stopPrice
The stop price of the buy or sell action if stop_limit orders are used. If you omit this value and stop or stop_limit orders are used, the current market price will be used when the trade is executed.
quantity
The quantity to enter. If you omit this value, the quantity will be dynamically calculated or defaulted to 1.
{
"ticker": "SPY",
"action": "buy",
"quantity": 5
}
The full quantity of the open position in the broker will be exited if you do not send a quantity in the exit signal. TradersPost is only able to partially exit open positions by sending the explicit quantity to exit in the webhook JSON.
quantityType
Supported values: fixed_quantity, dollar_amount, risk_dollar_amount, risk_percent, percent_of_equity, percent_of_position
The type of the value sent in the quantity field documented below. The default value is fixed_quantity when you send a quantity without a quantityType.
You can optionally send a value in the quantityType field to control how the value in the quantity field should be handled. By default the value in the quantity field is used as the quantity for the order directly.
This field is only used if you have Allow signal override checked in the strategy subscription settings in TradersPost.
The supported values for quantityType are the following:
fixed_quantity- A fixed quantity number that is used for the order. This is the default when you send aquantitywithout aquantityType.dollar_amount- Dynamically calculates a quantity for the given dollar amount.risk_dollar_amount- Dynamically calculates a quantity for the given risk dollar amount. This type requires a stop loss.risk_percent- Dynamically calculates a quantity for the given risk percent. This type requires a stop loss.percent_of_equity- Dynamically calculates a quantity for the given percent of equity.percent_of_position- Dynamically calculates a quantity for the given percent of position.
Here are some examples:
Fixed Quantity
This will buy 100 shares of $SPY.
{
"ticker": "SPY",
"action": "buy",
"quantityType": "fixed_quantity",
"quantity": 100
}
Dollar Amount
This will buy $1000 worth of $SPY. If the price of $SPY at the time of executing the trade was $100, then TradersPost would calculate a quantity of 10.
{
"ticker": "SPY",
"action": "buy",
"quantityType": "dollar_amount",
"quantity": 1000
}
Risk Dollar Amount
The risk_dollar_amount quantity in this example means you want to calculate a quantity that would only allow you to lose $100 when the stop loss is hit. In this example, TradersPost would calculate a quantity of 10. If you enter at $100 and get stopped out at $90 and the most you want to lose is $100, then you can only buy a quantity of 10.
{
"ticker": "SPY",
"action": "buy",
"signalPrice": 100,
"quantityType": "risk_dollar_amount",
"quantity": 100,
"stopLoss": {
"type": "stop",
"stopPrice": 90
}
}
Risk Percent
The risk_percent quantity type is similar to risk_dollar_amount but instead of manually specifying the dollar amount, it is dynamically calculated as a percent of your total account equity. If your total account equity were $10000 and you wanted to risk 1% of your account, that would be a risk dollar amount of $100 and we would calculate a quantity of 10 .
{
"ticker": "SPY",
"action": "buy",
"signalPrice": 100,
"quantityType": "risk_percent",
"quantity": 1,
"stopLoss": {
"type": "stop",
"stopPrice": 90
}
}
Percent of Equity
The percent_of_equity quantity type is similar to dollar_amount but instead of manually specifying the dollar amount, it is dynamically calculated as a percent of your total account equity. If your total account equity were $10000 and you wanted to allocate 10% of your account, that would be a dollar amount of $1000. If the current price of $SPY was $100, then we would calculate a quantity of 10.
{
"ticker": "SPY",
"action": "buy",
"quantityType": "percent_of_equity",
"quantity": 10
}
Percent of Position
The percent_of_position quantity type allows you to partially exit a percentage of your open position. So in the below example, if you had an open SPY position with a quantity of 10, then the below would calculate a quantity of 5.
{
"ticker": "SPY",
"action": "exit",
"quantityType": "percent_of_position",
"quantity": 50
}
orderType
Supported values: market, limit, stop, stop_limit, and trailing_stop
The type of order to create. If you send an order type not supported by your broker, it will fallback to the default order type configured in the strategy subscription settings. If that order type is still not supported, the order will be rejected by the broker.
{
"ticker": "SPY",
"action": "buy",
"orderType": "limit",
"limitPrice": 50.50
}
Or if you want to use a stop limit order:
{
"ticker": "SPY",
"action": "buy",
"orderType": "stop_limit",
"stopPrice": 60,
"limitPrice": 50.50
}
trailAmount
When orderType=trailing_stop, you can send a dollar amount in the trailAmount field to create a trailing stop order.
trailPercent
When orderType=trailing_stop, you can send a percentage in the trailPercent field to create a trailing stop order.
interval
The time interval (i.e., timeframe/resolution) of the chart that the alert is created on) used to generate the trading signal. You may use the placeholder {{interval}} on TradingView. This is currently just used for troubleshooting and for our support team to help.
timeInForce
Supported values: day, gtc, opg, cls, ioc and fok
The time in force for your order. If you send a time in force not supported by your broker, it will fallback to the default time in force or the time in force configured in the strategy subscription settings.
Example:
{
"ticker": "SPY",
"action": "buy",
"orderType": "limit",
"limitPrice": 50.50,
"timeInForce": "gtc"
}
Or if you want to send the order with extended hours enabled so that the order can be filled in extended hours, you can use the extendedHours field to send a true or false value.
{
"ticker": "SPY",
"action": "buy",
"orderType": "limit",
"limitPrice": 50.50,
"timeInForce": "gtc",
"extendedHours": true
}
time
The time property is used to keep track of the time the signal was generated and the request to TradersPost was started. It can also be used to calculate the time it takes between the signal source and getting to TradersPost.
extendedHours
Whether or not to send the order as an extended hours order. This is only applicable for stocks and the supported values are true or false.
ignoreTradingWindows
You can use the ignoreTradingWindows property in your JSON to ignore the defined trading windows in the strategy subscription settings and allow the trade to execute even if it is outside of the defined trading windows.
Here is an example where maybe you entered a SPY position while the trading window was open, and you now want to exit the position but the trading window is closed. Simply send the ignoreTradingWindows property with a value of true and the trade will be allowed to execute.
{
"ticker": "SPY",
"action": "exit",
"ignoreTradingWindows": true
}
cancel
Explicitly control whether or not to cancel open orders before submitting new orders to your broker.
{
"ticker": "SPY",
"action": "exit",
"cancel": true
}
Or if you want to disable canceling for a signal:
{
"ticker": "SPY",
"action": "exit",
"cancel": false
}
delay
The delay field postpones trade execution until after a delay. You can pass:
- An integer number of seconds (for example
60) - A relative expression (for example
+5 minutes) - An absolute ISO-8601 datetime with timezone (for example
2026-05-09T14:30:00-04:00)
Scheduled delays are limited to a maximum of 24 hours in the future.
Delay by seconds:
{
"ticker": "QQQ",
"action": "buy",
"delay": 60
}
Delay using a relative expression:
{
"ticker": "QQQ",
"action": "buy",
"delay": "+5 minutes"
}
Delay until a specific datetime:
{
"ticker": "QQQ",
"action": "buy",
"delay": "2026-05-09T14:30:00-04:00"
}
You may want to use delay if:
- You want to space out your entries to work around broker rate limits.
- Your strategy enters and then immediately exits so on the exit you may want to add a delay to give your entry enough time to fully execute.
rejectAfter
The rejectAfter field sets a per-signal maximum signal age in seconds (1–30) for entry or exit staleness checks. TradersPost uses the optional time field as the reference clock when provided; otherwise it uses when the webhook was received.
This field is only used when Allow signal overrides is enabled, or when the matching Allow signal override setting is enabled for Reject entry if signal is older than or Reject exit if signal is older than in your strategy subscription settings.
{
"ticker": "SPY",
"action": "buy",
"orderType": "market",
"time": "2026-04-23 10:00:00",
"rejectAfter": 10
}
bidAskSpreadFilter and bidAskSpreadFilterPercent
You can cap the bid-ask spread for an entry or exit using either a dollar amount (bidAskSpreadFilter) or a percentage (bidAskSpreadFilterPercent). Send one or the other, not both in the same payload.
{
"ticker": "SPY",
"action": "buy",
"bidAskSpreadFilterPercent": 0.5
}
extras
Users can send additional custom JSON properties within an "extras" field, allowing for more detailed information or contextual data to be included with each request. By keeping the properties inside an "extras" property, you avoid conflicting with TradersPost properties defined on this page. This is useful for tracking specific conditions or notes related to a trade. For example:
{
"ticker": "SPY",
"action": "buy",
"extras": {
"message": "RSI Below 30",
"rsi": 23
}
}
Webhook Field Reference - Take Profit and Stop Loss
takeProfit
Supported values: limitPrice, amount, percent, pnlAmount
You can optionally send take profit information with your entry signals.
The following fields are allowed on the takeProfit object, but never together. You can only choose one take profit mode (limitPrice, percent, amount, or pnlAmount).
- limitPrice - Absolute limit price calculated on the webhook sender side.
- percent: Relative percentage take profit to calculate relative to entry price. The entry price for market orders is estimated based on the mid point between the bid and ask on the most recent quote.
- amount - Relative dollar amount (market price offset) take profit to calculate relative to entry price. The entry price for market orders is estimated based on the mid point between the bid and ask on the most recent quote.
- pnlAmount - Portfolio PnL take profit target in dollars. TradersPost converts this to a limit price using the planned entry quantity and the symbol's point value.
Percentage take profit calculated relative to entry price.
When using market orders and you are calculating a relative take profit price, TradersPost will fetch a quote from your broker and use the price from the quote as the entry price in order to calculate the take profit limit price since with market orders, we don't know the price you will be filled at so we have to use the quote price.
{
"ticker": "SPY",
"action": "buy",
"takeProfit": {
"percent": 10
}
}
Dollar amount take profit calculated relative to entry price.
{
"ticker": "SPY",
"action": "buy",
"takeProfit": {
"amount": 10
}
}
Absolute take profit calculated on the webhook sender side.
{
"ticker": "SPY",
"action": "buy",
"takeProfit": {
"limitPrice": 19.99
}
}
stopLoss
Supported values: type, percent, amount, stopPrice, limitPrice, trailAmount, trailPercent, pnlAmount
You can optionally send stop loss information with your entry signals.
The following fields are allowed on the stopLoss object.
- type - Type of stop loss. If a value is provided, it overrides the stop loss type configured in strategy subscription settings. Allowed values are: stop, stop_limit, trailing_stop.
- percent: Relative percentage stop loss to calculate relative to entry price.
- amount - Relative dollar amount stop loss to calculate relative to entry price.
- stopPrice - Absolute stop price calculated on the webhook sender side.
- limitPrice - Absolute limit price calculated on the webhook sender side. type must be set to stop_limit to use this field.
- trailAmount - A dollar value away from the highest water mark. If you set this to 2.00 for a sell trailing stop, the stop price is always hwm - 2.00. type must be set to trailing_stop to use this field.
- trailPercent - A percent value away from the highest water mark. If you set this to 1.0 for a sell trailing stop, the stop price is always hwm * 0.99. type must be set to trailing_stop to use this field.
- pnlAmount - Portfolio PnL stop loss cap in dollars. Use only with stop or stop_limit, not trailing_stop. TradersPost converts this to a stop price using the planned entry quantity and the symbol's point value.
Percentage stop loss calculated relative to entry price.
When using market orders and you are calculating a relative stop loss price, TradersPost will fetch a quote from your broker and use the price from the quote as the entry price in order to calculate the stop loss stop price since with market orders, we don't know the price you will be filled at so we have to use the quote price.
{
"ticker": "SPY",
"action": "buy",
"stopLoss": {
"type": "stop",
"percent": 5
}
}
Dollar amount stop loss calculated relative to entry price.
{
"ticker": "SPY",
"action": "buy",
"stopLoss": {
"type": "stop",
"amount": 5
}
}
Absolute stop price calculated on the webhook sender side.
{
"ticker": "SPY",
"action": "buy",
"stopLoss": {
"type": "stop",
"stopPrice": 10.71
}
}
Or with a stop limit instead of stop market.
{
"ticker": "SPY",
"action": "buy",
"stopLoss": {
"type": "stop_limit",
"stopPrice": 10.71,
"limitPrice": 10.75
}
}
Use a 1% trailing stop trail percent.
{
"ticker": "SPY",
"action": "buy",
"stopLoss": {
"type": "trailing_stop",
"trailPercent": 1
}
}
Use a $1 trailing stop trail price.
{
"ticker": "SPY",
"action": "buy",
"stopLoss": {
"type": "trailing_stop",
"trailAmount": 1
}
}
Options Contracts and Screening
Put options: By default, action=buy buys long puts and action=sell sells short puts. Enable the Invert puts strategy setting to swap this mapping (action=buy → sell short puts, action=sell → buy long puts). Use Invert puts when your strategy runs on the underlying chart and sends buy/sell for the stock's direction but trades puts instead of shares. When option type is Both, put contracts selected from the option chain always use inverted logic regardless of this setting.
You have the ability to control the option chain scanning from the webhook or you can even send a specific contract to trade instead of scanning the option chain dynamically to find a contract to trade. Here is an example that will buy long calls using the contract in the ticker field.
{
"ticker": "SPY 240510C68",
"action": "buy"
}
Or if you want to instead scan the option chain dynamically to find a contract to trade, you can do so like this. This example will scan the option chain and look for an in the money call that is expiring 6 months from now and is 2 strikes away from at the money.
{
"ticker": "SPY",
"action": "buy",
"optionType": "call",
"expiration": "+6 months",
"intrinsicValue": "itm",
"strikesAway": 2
}
You can also specify the specific contract to trade with individual values instead of using the contract symbol in the ticker field. The following is equivalent to sending SPY 240510C68 in the ticker field.
{
"ticker": "SPY",
"action": "buy",
"optionType": "call",
"expiration": "2024-05-10",
"strikePrice": 68
}
optionType
Supported values: both, call and put
Specify the type of option contract for trading: call, put, or both.
intrinsicValue
Supported values: itm, otm
The intrinsic value of the option contract to trade. The only values allowed are itm for in-the-money and otm for out-of-the-money.
expiration
The expiration of the option contract to trade. The value can be a specific date like 2024-05-06 or a relative date expression like +6 months. This should be used to filter the nearest contract after the specified date or date expression. For example, for 0DTE options, you can use +0 days, or omit this field. For options a year out, use +12 months.
strikeCount
How many strikes to ask for from the broker when executing options trades and scanning the option chain to find a contract to trade.
strikesAway
How many strikes away from at the money to select.
strikePrice
Specifies the strike price of the option contract to trade.
Formulas
Any string value that starts with = is evaluated as a formula before the trade is processed. Formulas let you compute field values dynamically from other values in the same webhook payload — for example, offsetting a limit price from signalPrice or choosing quantity based on a condition.
Formulas are supported on top-level fields (except ticker, action, test, and cancel, which must always be literal values) and on sub-fields inside takeProfit and stopLoss. Formulas are not supported in other nested objects or arrays.
Referencing payload fields
Reference other top-level fields in the same payload using the signal. prefix:
{
"ticker": "AAPL",
"action": "buy",
"signalPrice": "195.50",
"limitPrice": "=signal.signalPrice + 0.05"
}
Numeric strings are automatically coerced to numbers, including values with commas (for example "1,234.50"). Field references must use signal.<key> — bare field names like signalPrice are not valid inside a formula.
You cannot reference another formula field. Chained formulas are not supported — if limitPrice starts with =, then signal.limitPrice is not available to a sibling formula. Send literal values for intermediate calculations, or combine the logic into one expression.
Supported operators
- Arithmetic:
+,-,*,/,% - Comparison:
==,!=,<,>,<=,>= - Logical:
and,or,not,&&,|| - Ternary:
condition ? valueIfTrue : valueIfFalse - String concatenation:
~ - Containment:
in,not in - String tests:
contains,starts with,ends with
Exponentiation (**), ranges (..), and regex matching (matches) are not supported.
Math functions
| Function | Description | Example |
|---|---|---|
abs(x) |
Absolute value | =abs(signal.delta) |
ceil(x) |
Round up to nearest integer | =ceil(signal.value) |
floor(x) |
Round down to nearest integer | =floor(signal.value) |
min(a, b, ...) |
Minimum of two or more values, or of an array | =min(signal.a, signal.b) or =min(signal.values) |
max(a, b, ...) |
Maximum of two or more values, or of an array | =max(signal.a, signal.b) or =max(signal.values) |
round(x) |
Round to nearest integer | =round(signal.closePrice) |
round(x, precision) |
Round to a number of decimal places | =round(signal.closePrice, 2) |
round(x, precision, mode) |
Round with a specific rounding mode | =round(signal.value, 0, rounding.halfEven) |
For round(), the optional third argument accepts a rounding mode integer (1–8) or a named mode via rounding.*:
rounding.halfAwayFromZerorounding.halfTowardsZerorounding.halfEvenrounding.halfOddrounding.towardsZerorounding.awayFromZerorounding.negativeInfinityrounding.positiveInfinity
Examples
Limit price offset on buy and sell:
{
"ticker": "AAPL",
"action": "buy",
"orderType": "limit",
"signalPrice": "195.50",
"limitPrice": "=signal.signalPrice + 0.05"
}
{
"ticker": "AAPL",
"action": "sell",
"orderType": "limit",
"signalPrice": "195.50",
"limitPrice": "=signal.signalPrice - 0.05"
}
Stop price from a previous candle low:
{
"ticker": "AAPL",
"action": "buy",
"orderType": "stop",
"prevCandleLow": "194.20",
"stopPrice": "=signal.prevCandleLow - 0.10"
}
Conditional quantity based on sentiment:
{
"ticker": "AAPL",
"action": "buy",
"sentiment": "long",
"quantityType": "percent_of_equity",
"quantity": "=signal.sentiment == \"long\" ? 100 : 25"
}
Multiple formula fields in one signal:
{
"ticker": "TSLA",
"action": "buy",
"closePrice": "450.25",
"limitPrice": "=signal.closePrice + 0.50",
"quantity": "=signal.closePrice > 400 ? 1 : 5"
}
Conditional order type:
{
"ticker": "TSLA",
"action": "buy",
"closePrice": "150.25",
"orderType": "=signal.closePrice > 200 ? \"limit\" : \"market\""
}
Take profit and stop loss with formulas:
{
"ticker": "TSLA",
"action": "buy",
"limitPrice": "100.456",
"takeProfit": {
"limitPrice": "=round(signal.limitPrice + 10, 1)"
},
"stopLoss": {
"type": "stop",
"stopPrice": "=signal.limitPrice - 2.5"
}
}
Using min and max with an array:
{
"ticker": "TSLA",
"action": "buy",
"values": [5, 2, 8],
"quantity": "=min(signal.values)"
}
Rules and limitations
- Formulas must resolve to a string, number, boolean, or
null. Array results are not allowed. - Each formula expression is limited to 500 characters (not counting the leading
=). - Only one layer of formula evaluation is supported per payload.
- See the Webhook Reference for the full OpenAPI specification and formula-related error codes.
JSON Message Examples
Here are some example webhook JSON messages to demonstrate the different use cases.
Enter Bullish
{
"ticker": "SPY",
"action": "buy"
}
Exit Bullish
{
"ticker": "SPY",
"action": "exit"
}
You can also use the sentiment field to exit a bullish position without entering a bearish position on the other side. When you send sentiment=flat, it will always exit the full quantity of the open position.
{
"ticker": "SPY",
"action": "sell",
"sentiment": "flat"
}
When you use the sentiment: flat feature, TradersPost will always exit the full quantity of the open position no matter what quantity is sent in the signal. This is because the sentiment is indicating that the position should be flattened.
Enter Bearish
{
"ticker": "SPY",
"action": "sell"
}
Exit Bearish
{
"ticker": "SPY",
"action": "exit"
}
You can also use the sentiment field to exit a bearish position without entering a bullish position on the other side. When you send sentiment=flat, it will always exit the full quantity of the open position.
{
"ticker": "SPY",
"action": "buy",
"sentiment": "flat"
}
When you use the sentiment: flat feature, TradersPost will always exit the full quantity of the open position no matter what quantity is sent in the signal. This is because the sentiment is indicating that the position should be flattened.
Partial Exits
You can partially exit an open position by using action: exit and sending a quantity in the signal with a value less than the quantity of the open position. So imagine you are long 5 shares and you want to exit 2 of them, you would send a JSON message like this.
{
"ticker": "SPY",
"action": "exit",
"quantity": 2
}
The above JSON would partially exit the open position and exit 2 of the 5 total shares. If you send a quantity that is greater than the quantity of the open position, the full position will be exited.
Trailing Stop
You can easily create trailing stop orders by sending trailing_stop in the orderType field. The following JSON will create a $1 trailing stop order for the open SPY position.
{
"ticker": "SPY",
"action": "exit",
"orderType": "trailing_stop",
"signalPrice": 71,
"trailAmount": "1"
}
Note that if the broker you are using does not support fetching quotes, you will need to be sure to send the current price in the signalPrice field so that we can use that price to calculate your trailing stop price. In the above example, the starting trailing stop price would be $70. If the price moves up to $72, then the trailing stop price would update to $71.
If you want to send a trailing stop with your entry order so that the trailing stop order is active immediately after your entry order fills and your position is open, you can do so by using the stopLoss object. The following example will create a buy limit order with a limit price of $71 and a trailing stop loss order with an initial trailing stop price of $70.
{
"ticker": "SPY",
"action": "buy",
"orderType": "limit",
"limitPrice": 71,
"stopLoss": {
"type": "trailing_stop",
"trailAmount": 1
}
}
Take Profit & Stop Loss
You can use the take profit and stop loss functionality together. Just send us both the takeProfit and stopLoss with your entry signal. Here is an example.
{
"ticker": "SPY",
"action": "buy",
"takeProfit": {
"limitPrice": 19.99
},
"stopLoss": {
"type": "stop",
"stopPrice": 10.71
}
}
400 Bad Request
The JSON that gets sent to TradersPost has to be precisely accurate in order for us to accept it. It is important to pay attention to all the details, all the little characters have meaning and are important. Here are the types of errors you may encounter when sending JSON to TradersPost webhooks.
post-required - HTTP POST method is required.
All webhook HTTP requests must be sent with a request method of POST. All other request methods will not be accepted.
empty-json - Your trade signal was empty.
The request body must contain valid JSON with trade instructions. An empty body is rejected.
malformed-json - Could not parse JSON message.
If you have a parse error in your JSON code, TradersPost will not be able to extract the instructions from the signal. Here are some common mistakes people make.
No trailing comma
Notice the trailing comma on line 3, the JSON specification requires that there be no final trailing comma on the last item in a JSON object.
{
"ticker": "TSLA",
"action": "buy",
}
Here is the corrected JSON.
{
"ticker": "TSLA",
"action": "buy"
}
Invalid double quote character
Some applications will convert a double quote like "quote" to a left and right side double quote like “quote”. Notice the difference between " and “ . JSON parsers don't like it when you use the latter. Here is an example invalid signal.
{
“ticker”: “TSLA”,
“action”: “buy”
}
Here is the corrected JSON.
{
"ticker": "TSLA",
"action": "buy"
}
invalid-payload - Invalid payload. action and ticker are required. Note: payload is another name used for JSON message.
The minimum required fields are an action and ticker. All other fields are optional.
invalid-action - Invalid action provided.
Action must be one of: buy, sell, exit, reverse, breakeven, cancel, or add.
invalid-sentiment - Invalid sentiment provided.
Sentiment must be one of: bullish, bearish, flat. The available sentiments are bullish, bearish and flat. You can optionally use long for bullish and short for bearish. This is for compatibility with TradingView strategies out of the box.
invalid-sentiment-action - Invalid sentiment action provided.
Sentiment can only be used with action buy or sell. You can only pass a sentiment in a webhook request when using action=buy or action=sell.
For example, sending a JSON message with "action": "exit" and "sentiment": "flat" will produce an error since only the "action": "exit" is needed.
// Invalid JSON
{
"ticker": "GOOGL",
"action": "exit",
"sentiment": "flat"
}
// Valid JSON that will exit the entire GOOGL position
{
"ticker": "GOOGL",
"action": "exit"
}
not-trading-view - Request did not come from TradingView.
If you check Limit to TradingView in your webhook configuration, then the only IP addresses that will be allowed to send a request to it will be from TradingView.
not-trend-spider - Request did not come from TrendSpider.
If you check Limit to TrendSpider in your webhook configuration, then the only IP addresses that will be allowed to send a request to it will be from TrendSpider.
invalid-ip-address - Request did not come from configured IP addresses.
If you enter an ip address in Limit to IP Addresses in your webhook configuration, then the only IP addresses that will be allowed to send a request to it will be from the configured IP addresses.
invalid-ip-address-format - The request IP address is not a valid IPv4 or IPv6 address.
ticker-does-not-exist - Ticker does not exist.
If the passed ticker does not exist in our ticker database then the webhook request will be rejected.
invalid-password - Password is invalid.
Every webhook has a password that can be regenerated by clicking the Generate New URL button when viewing a webhook
empty-ticker-name - Empty ticker name provided.
Sending an empty ticker name is not allowed.
{
"ticker": "",
"action": "buy"
}
unsupported-ticker - Ticker is not allowed on this webhook.
If your webhook is restricted to a specific list of tickers and you send a ticker not in that list, then the webhook request will be rejected.
invalid-quantity - Invalid quantity.
Quantities must be a valid numeric value. Any other non-numeric values will cause the webhook request to be rejected.
invalid-asset-class - Invalid asset class.
If you send a ticker for an asset class that the webhook does not support, then the webhook request will be rejected.
Order type and execution
- invalid-order-type —
orderTypemust be one of:market,limit,stop,stop_limit, ortrailing_stop. - invalid-cancel-order-type —
cancelOrderTypemust be one of:market,limit,stop,stop_limit, ortrailing_stop. - invalid-trailing-stop — When
orderTypeistrailing_stop,actionmust bebuy,sell,reverse, orexit, and eithertrailAmountortrailPercentis required. - invalid-time-in-force —
timeInForcemust be one of:day,gtc,gtd,opg,cls,ioc, orfok. - invalid-extended-hours —
extendedHoursmust be a boolean and is only valid for the stocks asset class. - invalid-market-price-type —
marketPriceTypemust be one of:ask_bid,mark,ask,bid, orlast. - invalid-bid-ask-spread-filter-amount-and-percent — You cannot specify both
bidAskSpreadFilterandbidAskSpreadFilterPercent. Use one or the other. - invalid-bid-ask-spread-filter-percent —
bidAskSpreadFilterPercentmust be a number between 0.01 and 99.99.
Quantity
- invalid-quantity-type —
quantityTypemust be one of:fixed_quantity,dollar_amount,risk_dollar_amount,percent_of_equity, orpercent_of_position. - invalid-quantity-type-action —
quantityTypeis only allowed whenactionisbuy,sell,reverse,exit, oradd. - invalid-risk-dollar-amount-action —
quantityTyperisk_dollar_amountis only allowed whenactionisbuy,sell,reverse, oradd. - invalid-risk-percent-action —
quantityTyperisk_percentis only allowed whenactionisbuy,sell,reverse, oradd. - invalid-percent-of-position-action —
quantityTypepercent_of_positionis only allowed whenactionisbuy,sell,reverse, orexit. - quantity-type-requires-quantity — When
quantityTypeis set,quantitymust also be provided as a positive number. - invalid-quantity-type-for-asset-class — Dynamic quantity types (
dollar_amount,risk_dollar_amount,risk_percent,percent_of_equity) cannot be used with the futures asset class.
Options fields
- invalid-option-type —
optionTypemust be one of:both,call, orput. - invalid-intrinsic-value —
intrinsicValuemust beitmorotm. - invalid-expiration —
expirationmust be an absolute date (YYYY-MM-DD) or a relative expression (for example+1 month). - invalid-strike-count —
strikeCountmust be an integer between 2 and 20. - invalid-strikes-away —
strikesAwaycannot be greater than half ofstrikeCount. - invalid-strike-price —
strikePricemust be a positive number and requires a validexpirationandoptionType. - invalid-ticker-and-option-type — The option letter in the
tickercontract symbol must matchoptionType(for example a call ticker withoptionTypeput).
Ticker format
- invalid-stocks-ticker-format — Stocks tickers must use the format
[SYMBOL](for exampleSPY). - invalid-options-ticker-format — Options tickers must use the format
[UNDERLYING] [YYMMDD][C|P][STRIKE](for exampleSPY 241004C571). - invalid-futures-ticker-format — Futures tickers must use the format
[ROOT][LETTER][YEAR](for exampleESZ2024). - invalid-crypto-ticker-format — Crypto tickers must use the format
[BASE]-[QUOTE](for exampleBTC-USD).
Take profit
- invalid-take-profit-percent —
takeProfit.percentmust be a positive number. - invalid-take-profit-amount —
takeProfit.amountmust be a positive number. - invalid-take-profit-limit-price —
takeProfit.limitPricemust be a positive number. - invalid-take-profit-amount-and-percent — You cannot specify both
takeProfit.amountandtakeProfit.percent. - invalid-take-profit-relative-and-absolute — You cannot mix relative (
amountorpercent) and absolute (limitPrice) take profit values. - invalid-take-profit-value-required — A relative (
amountorpercent), absolute (limitPrice), or portfolio PnL (pnlAmount) take profit value is required. - invalid-take-profit-pnl-amount —
takeProfit.pnlAmountmust be a positive number (portfolio PnL target in dollars). - invalid-take-profit-pnl-incompatible —
takeProfit.pnlAmountcannot be combined withtakeProfit.percent,takeProfit.amount, ortakeProfit.limitPrice.
Stop loss
- invalid-stop-loss-type —
stopLoss.typemust be one of:stop,stop_limit, ortrailing_stop. - invalid-stop-loss-percent —
stopLoss.percentmust be a positive number. - invalid-stop-loss-amount —
stopLoss.amountmust be a positive number. - invalid-stop-loss-stop-price —
stopLoss.stopPricemust be a positive number. - invalid-stop-loss-limit-price —
stopLoss.limitPricemust be a positive number. - invalid-stop-loss-trail-price —
stopLoss.trailPricemust be a positive number. - invalid-stop-loss-trail-amount —
stopLoss.trailAmountmust be a positive number. - invalid-stop-loss-trail-percent —
stopLoss.trailPercentmust be a positive number. - invalid-stop-loss-trail-value — You cannot specify both
stopLoss.trailAmountandstopLoss.trailPercent. - invalid-stop-loss-trail-value-required — When
stopLoss.typeistrailing_stop, provide eitherstopLoss.trailAmountorstopLoss.trailPercent, not both. - invalid-stop-loss-amount-and-percent — You cannot specify both
stopLoss.amountandstopLoss.percent. - invalid-stop-loss-relative-and-absolute — You cannot mix relative (
amountorpercent) and absolute (stopPriceorlimitPrice) stop loss values. - invalid-stop-loss-stop-price-required — Without a relative stop loss,
stopLoss.stopPriceis required.stopLoss.limitPricecannot be used alone. - invalid-stop-loss-value-required — A relative (
amountorpercent), absolute (stopPriceorlimitPrice), or portfolio PnL (pnlAmount) stop loss value is required. - invalid-stop-loss-pnl-amount —
stopLoss.pnlAmountmust be a positive number (portfolio PnL stop target in dollars). - invalid-stop-loss-pnl-incompatible —
stopLoss.pnlAmountcannot be combined withstopLoss.percent,stopLoss.amount,stopLoss.stopPrice, orstopLoss.limitPrice. - invalid-stop-loss-pnl-trailing —
stopLoss.pnlAmountcannot be used whenstopLoss.typeistrailing_stop.
Breakeven
- invalid-breakeven-offset — When
actionisbreakevenandbreakevenOffsetis provided, it must be a number between 0.001 and 100. - invalid-breakeven-order-type — For
actionbreakeven,orderTypeis required and must bestoporstop_limit.
Delay, cancel, and reject timing
- invalid-delay —
delaymust be an integer from 1 to 86400 seconds, a parseable relative expression (for example+5 minutes), or an absolute datetime with a timezone (for example2026-01-25 05:30 pm EST). ISO-8601 timestamps without a timezone are not accepted. - invalid-delay-format —
delaycould not be parsed. Use seconds, a relative expression, or an absolute datetime with a timezone. - invalid-delay-past —
delaymust resolve to a future point in time. - invalid-delay-exceeds-max —
delaycannot be more than 86400 seconds (24 hours) in the future. - invalid-delay-missing-timezone — Absolute datetime
delayvalues must include a timezone. - invalid-cancel-after —
cancelAftermust be between 1 and 3600 seconds. - invalid-reject-after —
rejectAftermust be a whole number of seconds between 1 and 30.
Message metadata
- invalid-expires-at —
expiresAtmust be an absolute date (YYYY-MM-DD) or a relative expression (for example+1 month). - invalid-message-length —
messagecannot exceed 255 characters. - invalid-message-tags —
messagecannot contain HTML tags.
Formula errors
If a field value starts with =, TradersPost evaluates it as a formula before processing the trade. Formula-related rejections use these error codes:
- invalid-formula-syntax — The expression could not be parsed. Use only supported operators and
signal.<key>references. - invalid-formula-reference — The formula references a field or rounding mode that does not exist (for example
signal.missingKeyorrounding.unknownMode). - invalid-formula-dependency — The formula references another formula field. Chained formulas are not supported.
- invalid-formula-nested — A formula appeared outside top-level fields or
takeProfit/stopLosssub-fields. - invalid-formula-runtime — The formula parsed but failed at runtime (for example division by zero or invalid
round()arguments). - invalid-formula-length — The expression exceeds the 500-character limit.
- invalid-formula-operator — The expression uses an unsupported operator such as
**,.., ormatches. - invalid-formula-result — The formula did not resolve to a string, number, boolean, or
null. - invalid-formula-blacklisted-field —
ticker,action,test, orcancelwas sent as a formula. These fields must be literal values.
See Formulas for supported syntax, functions, and examples.
Rate Limits
TradersPost is NOT designed to be a high frequency trading platform. The minimum allowed timeframe to trade on is the 1 minute chart. You are allowed to send 60 requests per minute and 500 requests per hour. If you setup a strategy on anything less than the 1 minute chart, your account may be temporarily suspended or permanently banned if the issue is not addressed. Read more about our rate limiting behavior here.
Third Parties
Because TradersPost works using standard webhooks, this enables users to integrate with third party platforms that support sending alerts as webhooks.
Here are some popular platforms that enable you to build strategies and send alerts as webhooks.
- TradingView - TradingView is a social network of 30 million traders and investors using the world's best charts and tools to spot trading opportunities across global markets.
- TrendSpider - TrendSpider provides technical analysis software for retail traders and investors focused on the US equity and foreign exchange markets.
Custom Code
In addition to sending webhooks from third parties, you can send webhooks to TradersPost from custom code using programming languages like PHP or Python.