Setup Webhooks & the Events API

Every armed setup the engine finds can leave the building as a structured event, so you can drive your own bot, spreadsheet or dashboard off the same detections that fire our Discord alerts. This page is the contract.

Treat these as CANDIDATES, not orders. An event says a setup exists and where its trigger, stop and targets sit. It is not a recommendation and nothing here places a trade.

The two events

setup_armed fires when a setup completes and its trigger level is known. You get direction, trigger price, stop, targets and the full-timeframe-continuity count. Nothing has broken yet.

setup_triggered fires when price closes beyond that trigger on a confirmation candle. It adds confirmation_close and confirmation_time. The confirmation candle is the sealed 1-hour close, so a trigger is reported once per hour at most, never on an intrabar poke.

Both stages share one event_id on purpose, because they are two moments in one setup's life. De-duplicate on the PAIR of event_type and event_id, not event_id alone, or you will drop every trigger as a repeat of its own arm.

A real event

This is an actual setup_armed, captured from the live feed:

{ "event_id": "sbux-4h-212bullishreversal-long-202610120930", "event_type": "setup_armed", "ticker": "SBUX", "setup": "2-1-2 Bullish Reversal", "direction": "long", "setup_timeframe": "4H", "confirmation_timeframe": null, "trigger_price": 92.44, "confirmation_close": null, "stop": 91.575, "targets": [94.17], "ftfc": 3, "ftfc_of": 5, "confirmation_time": null, "emitted_at": "2026-10-12T18:27:18.311847+00:00" }

event_id is stable and bar-scoped: the same setup on the same bar always produces the same id, so a replay or a re-send de-duplicates cleanly. Two 4H setups on one ticker on the same day are different bars and therefore different ids. direction is long or short. ftfc and ftfc_of are the continuity count and its denominator, so 3 of 5 timeframes aligned. stop and targets come from the same plan maths the Discord alert prints. Prices are rounded to four decimals; any field that cannot be computed is null rather than absent.

Which timeframes actually fire

Read this before you build. The engine arms Strat setups on the 4-hour and Daily for equities, and on the 1-hour, 4-hour and Daily for futures. Nothing else produces events.

The subscriber filter accepts any timeframe string, including ones the engine never arms. Asking for 5-minute or 6-hour setups is not an error and will not warn you — you will simply receive nothing on those timeframes, forever. If your integration looks silent, check this first.

Option 1: polled feed

GET /api/agent/setup-events?since=0&limit=100 with an X-API-Key header returns { ok, data: { since, cursor, count, events }, meta }. Each event carries a seq. Pass the cursor from the last response back as since on the next call and you get only what is new.

The feed is in-memory and holds the last 500 events, so it survives a poll gap of minutes, not days. A bot restart loses the backlog. Poll every 30 to 60 seconds; there is no benefit to going faster, since arms land on sealed candle closes.

Option 2: signed webhook

We POST the event as JSON to your URL. If you give us a shared secret, the request carries X-WTN2-Signature: sha256=<hex>, an HMAC-SHA256 of the EXACT raw request body using that secret. Verify against the raw bytes before parsing, not against a re-serialised object, or whitespace differences will break the comparison. Compare with a constant-time function.

Delivery is fire and forget and can never block or break the alert engine. We retry up to four times with a short backoff capped at eight seconds, then drop the event and log it. That cap is deliberate: the queue is head-of-line, so one dead endpoint must not stall everyone else's events for minutes. Return 2xx quickly and do your work asynchronously.

Filters are per subscriber: setups, timeframes and min_ftfc. Matching ignores case and spacing and strips the direction, so one entry of "2-1-2 reversal" catches both the bullish and bearish forms. "reversal" in the key is meaningful — it will not match a continuation.

Getting set up

The polled feed needs an API key. The webhook needs your endpoint URL and a secret you generate. Message Rob in the Discord with your URL, and keep the secret to yourself — send it separately, never in a public channel.

Not financial advice. Tools detect and deliver — decisions are yours.