Skip to content
Connectivity

Webhooks

Everything that flows in and out over HTTP. TradingView pushes alerts in; our bot engine pushes actionable signals out to Discord.

Incoming webhooks

TradingView alerts

Pro / Ultimate

Route a TradingView alert straight into TradingWizard. The URL is static; the sender is identified by the api_token field inside the JSON body, so the token is the shared secret. Pro/Ultimate accounts immediately kick off AI analysis on the symbol and any matching price alerts fire in-app and via email.

POST https://www.tradingwizard.ai/api/webhooks/tradingview
Content-Type: application/json

Payload shape

{
  "symbol":   "{{ticker}}",
  "exchange": "{{exchange}}",
  "interval": "{{interval}}",
  "action":   "{{strategy.market_position}}",
  "price":    "{{strategy.order.price}}",
  "strategy": "{{strategy.order.id}}",
  "api_token": "YOUR_TRADINGWIZARD_API_TOKEN"
}

Paste this template into the Message field of a TradingView alert. Only symbol, action, price, and api_token are strictly required, strategy is optional and used for dedup and logs. Missing or wrong api_token returns 401 / 403. Starter accounts get an automated upgrade email instead of analysis.

Outgoing webhooks

Discord, bot signals

Community

Each market (crypto / stock / forex) has a dedicated Discord webhook URL for OPEN and CLOSE signals, plus a separate URL for UPDATE events when a bot moves its stop or target. Configuration lives in Vercel env as DISCORD_WEBHOOK_<MARKET>_SIGNALS and DISCORD_WEBHOOK_<MARKET>_UPDATES.

Filtering (from lib/discordWebhooks.ts)

// Only actionable, high-conviction signals leave the server
// 1. Verdict must be BUY or SELL — WAIT / HOLD / NEUTRAL are dropped
// 2. Bot confidence must be >= 60% for OPEN signals
// 3. CLOSE events with |PnL %| < 1.5 are treated as "scratch" and skipped
MATERIALITY = {
  DISCORD_THRESHOLD: 1.5,   // |PnL %| below this is NOT posted
  SCRATCH_BAND:      0.5,   // within this band = scratch trade
}

Payload shape (OPEN)

{
  "symbol":     "BTCUSDT",
  "side":       "BUY",
  "entry":      67840.0,
  "stopLoss":   66200.0,
  "takeProfit": 71500.0,
  "confidence": 74,
  "timeframe":  "4h",
  "botName":    "BTC Momentum",
  "reason":     "Breakout of 4h consolidation with volume confirmation"
}

Every outbound payload passes through a PII scrubber that strips email-like strings and known sensitive keys (email, userId, stripeCustomerId, tokens) before the request is serialised. Per-URL cooldowns honour Discord's 429 retry_after inside the same warm lambda instance.

Pulse and Market Track events

Digest

The hourly Market Pulse cron and the Market Track engine fan out notable moves, fear & greed shifts, regime changes, breakouts, earnings reactions, to the same Discord channels. Scratch-band moves and low-significance events never get posted. Bot backtest results and end-of-run summaries go to DISCORD_WEBHOOK_BOT_RESULTS.

Payload shape (Market Track)

{
  "symbol":       "ETHUSDT",
  "sentiment":    "bullish",
  "explanation":  "ETH reclaimed the 200-day after a 3-day accumulation candle.",
  "triggerSource": "momentum",
  "detectedAt":   "2026-04-20T14:30:00Z"
}

Retries & idempotency

TradingView

TradingView does not retry. We key dedup off the strategy / alert id from the payload combined with symbol + timestamp. If you need guaranteed delivery, trigger the alert Once per bar close rather than Every tick.

Discord (outbound)

Best-effort. On 429 we back off for the duration Discord returns (per-URL cooldown). No automatic replay, a dropped signal is dropped, by design, to prevent stale setups from posting late.

Pulse / Market Track

Events are written to MongoDB first and only then fanned out, so the system-of-record never depends on Discord delivery. Reposting the same event is a no-op.

Security

  • TradingView: authenticated via the api_token field inside the JSON body (a per-user secret). Rotate the token from Settings → API Keys the moment you suspect a leak.
  • Replay protection: TradingView alerts are deduped by the payload's strategy / alert id. Replays are rejected before any side effects.
  • IP allowlists: recommended but optional. TradingView uses a documented fixed set of IPs, whitelist them at the edge if your threat model needs it. Vercel serves our origin from its global edge, so we do not operate a static outbound IP range.
  • Outbound: every payload passes through a PII scrubber that strips email-like strings and known sensitive keys (email, userId, tokens) before the request leaves us.

Testing

TradingView, test webhook

In the TradingView strategy editor, open the alert dialog and click Test webhook. Paste our URL, drop the payload template shown above into the Message field, and fire. A successful request returns 200 with { "success": true, "action_received": "..." }.

Next: REST API

The same API key used for TradingView webhooks also unlocks the programmatic API.

API reference