Webhook Endpoints — Execute Trade Signal
A TVH webhook endpoint accepts a TradeCommand JSON payload and turns it into a trade on an exchange. This page is the wire reference for the two variants — queued and classic. For the URLs to paste into a TradingView alert and the IP whitelist, see Webhook URLs & IP Whitelist.
- Queued (
POST /) is the default. It deduplicates, retries on transient failures, and absorbs exchange rate-limit bursts, at the cost of a small queue-hop delay. Use this unless you have a specific reason not to. - Classic (
POST /api/ExecuteTradeSignalClassic) skips the queue and executes inline — faster, but no retry and no dedup. Use only for scalping when you have confirmed you need the lower latency. - Both variants exist on both base URLs:
alerts.tv-hub.orgfor everything except Binance,binance.tv-hub.orgfor all Binance markets. - The body schema is the full TradeCommand. Most setups use 6–10 fields.
Endpoint variants
| URL | Base | Queue | When to use |
|---|---|---|---|
https://alerts.tv-hub.org/ | alerts | ✅ | Default. All exchanges except Binance. |
https://alerts.tv-hub.org/api/ExecuteTradeSignalClassic | alerts | ❌ | Low latency, scalping. Accept no-retry, no-dedup. |
https://binance.tv-hub.org/ | binance | ✅ | All Binance markets (Spot, USD-M & Coin-M Futures). |
https://binance.tv-hub.org/api/ExecuteTradeSignalClassic | binance | ❌ | Binance, low latency. |
Use the Binance host for Binance, the default host for everything else. The copy-paste URLs and IP whitelist are in Webhook URLs & IP Whitelist.
Request — single trade
| Method | POST |
| Content-Type | application/json or text/plain |
| Body | A single TradeCommand object |
The minimum useful payload requires five fields:
| Field | Purpose |
|---|---|
token | Your Webhook Token (from Account → Settings). Treat it like a password. |
exchange | Exchange identifier (e.g. binance, bybit-futures, kucoin). |
pair | Symbol on that exchange (e.g. BTCUSDT). |
isBuy / isSell / isClose | Direction flag for normal webhook/API commands. Use orderType only for TradingView strategy-alert templates. |
apiKey | The ApiKeyName you set when you added the exchange key in TVH. |
Plus sizing (one of unitsType + value, units, or positionSize). The full 86-field schema is in Trade Command → Parameter Reference.
Quick close
A close needs no sizing — just point it at the open position and set isClose:
{"pair":"ETHUSDT","exchange":"bybit","apiKey":"Key1","token":"YOUR_TOKEN","isClose":true}
This market-closes the current position on that pair and cancels its pending orders (SL, TPs, DCA limits). See Close & Cancel for partial closes and hedge-mode variants.
Request — batch (square-bracket syntax)
Send multiple commands in a single webhook by wrapping them in an array:
[
{"token":"...","exchange":"binance","pair":"BTCUSDT","isBuy":true,"apiKey":"K1","unitsType":"percentBalance","unitsPercent":1},
{"token":"...","exchange":"bybit","pair":"ETHUSDT","isBuy":true,"apiKey":"K2","unitsType":"percentBalance","unitsPercent":1}
]
The queued endpoint enqueues each entry independently. The classic endpoint executes them in parallel. Cross-ref: Features → Batch & Timing.
Code examples — single trade (queued)
- curl
- Python
- Node.js
curl -X POST https://alerts.tv-hub.org/ \
-H "Content-Type: application/json" \
-d '{
"token": "YOUR_TOKEN",
"exchange": "binance",
"pair": "BTCUSDT",
"isBuy": true,
"isMarket": true,
"unitsType": "percentBalance",
"unitsPercent": 1,
"apiKey": "BinanceKey1",
"alertTimestamp": "BTCUSDT-1716364800"
}'import requests
payload = {
"token": "YOUR_TOKEN",
"exchange": "binance",
"pair": "BTCUSDT",
"isBuy": True,
"isMarket": True,
"unitsType": "percentBalance",
"unitsPercent": 1,
"apiKey": "BinanceKey1",
"alertTimestamp": "BTCUSDT-1716364800",
}
r = requests.post("https://alerts.tv-hub.org/", json=payload, timeout=10)
print(r.status_code, r.text)const axios = require('axios');
(async () => {
const payload = {
token: 'YOUR_TOKEN',
exchange: 'binance',
pair: 'BTCUSDT',
isBuy: true,
isMarket: true,
unitsType: 'percentBalance',
unitsPercent: 1,
apiKey: 'BinanceKey1',
alertTimestamp: 'BTCUSDT-1716364800',
};
const { data, status } = await axios.post(
'https://alerts.tv-hub.org/',
payload,
{ headers: { 'Content-Type': 'application/json' }, timeout: 10000 },
);
console.log(status, data);
})();Test with Postman
Any HTTP client works. In Postman: set the method to POST, the URL to a webhook endpoint, the body to raw, and paste your TradeCommand. A 200 OK means the signal was accepted (on the queued endpoint, check the Activity Log for the execution result; the Classic endpoint returns the result directly — see below).

The example above is a minimal close command.
Code examples — classic (low latency)
The body is identical. Only the URL changes.
The Classic endpoint runs synchronously, so its response body carries the actual outcome — a human-readable success string, or the exchange's error message if the trade was rejected. The queued endpoint instead returns immediately with an empty body, and its result only appears in the Activity Log.
- curl
- Python
- Node.js
curl -X POST https://alerts.tv-hub.org/api/ExecuteTradeSignalClassic \
-H "Content-Type: application/json" \
-d '{
"token": "YOUR_TOKEN",
"exchange": "bybit",
"pair": "BTCUSDT",
"isBuy": true,
"isMarket": true,
"unitsType": "percentBalance",
"unitsPercent": 1,
"apiKey": "BybitKey1"
}'import requests
r = requests.post(
"https://alerts.tv-hub.org/api/ExecuteTradeSignalClassic",
json={
"token": "YOUR_TOKEN",
"exchange": "bybit",
"pair": "BTCUSDT",
"isBuy": True,
"isMarket": True,
"unitsType": "percentBalance",
"unitsPercent": 1,
"apiKey": "BybitKey1",
},
timeout=10,
)
print(r.status_code, r.text)const axios = require('axios');
(async () => {
const res = await axios.post(
'https://alerts.tv-hub.org/api/ExecuteTradeSignalClassic',
{
token: 'YOUR_TOKEN',
exchange: 'bybit',
pair: 'BTCUSDT',
isBuy: true,
isMarket: true,
unitsType: 'percentBalance',
unitsPercent: 1,
apiKey: 'BybitKey1',
},
);
console.log(res.status, res.data);
})();