Skip to content
Nyria Docs

Webhook Payload Reference

Every field Nyria accepts on the webhook. Send any text or JSON, with no required template. Includes copy-paste Pine Script, Discord and cURL examples.

Nyria's webhook does not require a fixed payload. The strategy parser reads whatever you send and pairs it with your strategy config. This reference documents every field Nyria will recognize if you choose to include it, plus copy-paste examples for every supported broker and alert source.

Two-field minimum. The smallest valid payload is ticker + action. Everything else is optional. Nyria infers from your strategy config.

Endpoint

POST https://trades.nyria.io/webhooks/{your_strategy_token}

Get your strategy token from the strategy's Integration tab in the app. It is a 64-character lowercase hexadecimal string with no prefix. Each strategy has a unique token; never share it publicly.

Minimum payload (2 fields)

{
  "ticker": "SPY",
  "action": "buy"
}

That's it. Nyria looks up your strategy by the token in the URL, finds the entry rule for BUY, builds the order using your bot's position-sizing config, and sends it to the connected broker.

Plain text also works:

SPY long entry

Nyria reads the instrument (SPY), the direction (long), and the action (entry) without a fixed JSON schema.

Full payload reference

Every field below is optional. Include only what your strategy needs to override defaults.

Top-level fields

FieldTypeDescription
instrument / ticker / symbolstringUnderlying instrument (SPY, BTCUSD). All three keys are accepted interchangeably.
actionstringOPEN / CLOSE (the canonical entry/exit actions), or MODIFY / CANCEL (order management, see below). buy/sell/entry/exit are also accepted and mapped.
directionstringLONG or SHORT. With the canonical OPEN/CLOSE actions, include it explicitly.
pricenumberLimit/stop price (decimal). With order_type: "limit" this is the limit price.
order_typestringmarket or limit. Optional per-alert override of the strategy's configured order type. Send "limit" + price to place a resting limit order regardless of the strategy default. Omit it to use the strategy's configured type.
marketPosition / prevMarketPositionstringTradingView's {{strategy.market_position}} and {{strategy.prev_market_position}}: long, short, flat. Send both and Nyria derives the action and direction from the transition, no other fields needed.

Entry size is never set by the alert. Size always comes from the bot's sizing configuration. A quantity or notional key in an entry alert is ignored. The one exception is MODIFY, which re-sizes an order that is already working.

Option leg fields (single-leg + multi-leg)

For options, include a legs array. Each leg accepts:

FieldTypeDescription
symbolstringOCC option symbol (e.g. SPY260619C00500000).
sidestringCALL or PUT.
actionstringbuy_to_open / sell_to_open / buy_to_close / sell_to_close.
strikenumberStrike price (e.g. 500).
expirationstringYYYY-MM-DD. Omit it on an entry and Nyria uses the next expiration allowed by the strategy.
pricenumberPer-leg limit price (for limit spreads, sum across legs).
live_pricenumberLive bid/ask price for this leg.

Strike selection and expiry come from the strategy, not the alert. On an internal-selection strategy Nyria picks the strikes and expiration from the leg rules you configured. Only an external-selection strategy takes the contract from the alert, and it takes it as strike, side and expiration. There is no delta or days-to-expiry field on the webhook.

Order management: limit orders, modify & cancel

Beyond opening and closing positions, the API can place resting limit orders and then modify or cancel them: the full order lifecycle, all through the same webhook, with no per-broker syntax. Every action runs through the parser and fans out to each bot connected to the strategy.

Canonical format. The base shape Nyria parses everything into is { "action", "instrument", "direction", "price" }. The same four fields drive every equity type. Your strategy decides whether SPY trades as equity or options, BTCUSD as spot or perpetual, etc.

Place a resting limit order

Add order_type: "limit" + a price to an OPEN (or CLOSE). The order rests at your price until filled or cancelled, regardless of the strategy's configured order type:

curl -X POST https://trades.nyria.io/webhooks/YOUR_STRATEGY_TOKEN \
  -H "Content-Type: application/json" \
  -d '{
    "action": "OPEN",
    "instrument": "BTCUSD",
    "direction": "LONG",
    "order_type": "limit",
    "price": 55000
  }'

Position size is still derived from your bot's sizing config; price is used only as the limit price.

Modify a working order

MODIFY changes the limit price (and/or quantity) of the order currently working on the given side, whether it's a resting entry or a resting exit that a previous alert placed. Brokers that cancel-and-replace will assign a new order id internally; Nyria tracks it for you. MODIFY re-prices an order you already sent; it does not attach a bracket, an OCO, or a take-profit leg to anything. Nyria does not support those.

curl -X POST https://trades.nyria.io/webhooks/YOUR_STRATEGY_TOKEN \
  -H "Content-Type: application/json" \
  -d '{
    "action": "MODIFY",
    "instrument": "BTCUSD",
    "direction": "LONG",
    "price": 56000
  }'

Cancel a working order

CANCEL cancels the working entry order(s) for the instrument + direction. Use it to pull a resting limit entry before it fills. (To exit a filled position, send CLOSE, not CANCEL.)

curl -X POST https://trades.nyria.io/webhooks/YOUR_STRATEGY_TOKEN \
  -H "Content-Type: application/json" \
  -d '{
    "action": "CANCEL",
    "instrument": "BTCUSD",
    "direction": "LONG"
  }'

MODIFY/CANCEL act on existing orders. They never open a new trade. They only touch orders in a working state (pending / open). A market order that has already filled is a position: close it with CLOSE. Sent during a closed market, the broker may reject the modify/cancel until it reopens.

ActionActs onUse it to
OPENn/aEnter a position (market, or order_type: "limit" to rest).
CLOSEthe open positionExit a filled position.
MODIFYthe working order on that side (entry or exit)Re-price a resting limit order.
CANCELthe working entry order(s)Pull a resting entry before it fills.

Examples by alert source

TradingView Pine: equity entry

In TradingView, set the alert's webhook URL to your Nyria endpoint and the message to:

{{strategy.order.action}} {{ticker}} @ {{close}}

Or as JSON for explicit control:

{
  "ticker": "{{ticker}}",
  "action": "{{strategy.order.action}}",
  "marketPosition": "{{strategy.market_position}}",
  "prevMarketPosition": "{{strategy.prev_market_position}}",
  "price": {{close}}
}

TradingView Pine: option spread

{
  "ticker": "SPY",
  "action": "OPEN",
  "direction": "LONG",
  "order_type": "limit",
  "price": 1.50
}

The legs are not in the alert. Nyria builds both legs of the spread from the leg rules on the strategy, then prices the spread at your price.

TradingView Pine: SPX iron condor

{
  "ticker": "SPX",
  "action": "OPEN",
  "direction": "SHORT",
  "order_type": "limit",
  "price": 2.00
}

All four legs come from the strategy's leg rules. Nyria rewrites SPXSPXW automatically (PM-settled root).

Discord: natural language

If you're using the Nyria Discord bot, post any of these in the configured channel:

SPY long entry
BTO 1 SPY 6/19 $500 CALL @ 1.50
Close SPY long

TrendSpider

TrendSpider fires webhooks from two different surfaces: account-level Alerts and per-bot Strategy Bots, and only the second can drive more than one Nyria strategy. Payloads use TrendSpider's own %alert_symbol% / %bot_symbol% variables; see the TrendSpider setup guide.

Telegram: coming soon

Telegram alerts are not yet available. When they ship, they will use the same natural-language shapes as Discord. Use TradingView, Discord, TrendSpider, or a custom webhook today.

cURL: generic POST

curl -X POST https://trades.nyria.io/webhooks/YOUR_STRATEGY_TOKEN \
  -H "Content-Type: application/json" \
  -d '{
    "ticker": "AAPL",
    "action": "OPEN",
    "direction": "LONG",
    "order_type": "market"
  }'

Examples by broker

The same payload routes to any connected broker. The broker determines what the order looks like on the wire.

Schwab: option buy-to-open

{
  "ticker": "SPY",
  "action": "open",
  "direction": "long",
  "legs": [{ "side": "CALL", "strike": 500, "expiration": "2026-06-19" }],
  "order_type": "market"
}

→ Schwab receives:

{
  "orderType": "MARKET",
  "session": "NORMAL",
  "duration": "DAY",
  "orderStrategyType": "SINGLE",
  "orderLegCollection": [{
    "instruction": "BUY_TO_OPEN",
    "quantity": 1,
    "instrument": {
      "symbol": "SPY   260619C00500000",
      "assetType": "OPTION"
    }
  }]
}

Note the 6-char padded ticker. Schwab requires this; Nyria pads automatically.

tastytrade: vertical credit spread

{
  "ticker": "SPY",
  "action": "OPEN",
  "direction": "SHORT",
  "order_type": "limit",
  "price": 1.00,
  "legs": [
    { "side": "CALL", "strike": 510, "expiration": "2026-06-19" },
    { "side": "CALL", "strike": 520, "expiration": "2026-06-19" }
  ]
}

→ tastytrade receives a single multi-leg JSON order with legs array, price-effect: Credit, and the OSI-padded option symbols.

Tradier: multileg spread (form-encoded)

Same payload as above. Tradier receives indexed form params: class=multileg, symbol=SPY, option_symbol[0]=..., side[0]=sell_to_open, option_symbol[1]=..., side[1]=buy_to_open, etc.

Alpaca: single-leg option

{
  "ticker": "SPY",
  "action": "open",
  "direction": "long",
  "legs": [{ "side": "PUT", "strike": 495, "expiration": "2026-06-19" }],
  "order_type": "market"
}

Alpaca: crypto spot

{
  "ticker": "BTCUSD",
  "action": "OPEN",
  "direction": "LONG",
  "order_type": "limit",
  "price": 60000
}

→ Alpaca receives symbol=BTC/USD, side=BUY, type=LIMIT, price=60000, and a quantity Nyria works out from the bot's sizing config. Nyria rewrites the pair into each exchange's own shape, so send whichever form your alert source produces.

Idempotency + retries

Nyria deduplicates on the alert body. If the exact same body arrives again within about five minutes, the second one is dropped and the webhook answers 200 with {"status": "duplicate"}.

That matters for scaling in: a strategy that fires the same static alert text twice sends the second entry into the dedup window and it never trades. To make repeat entries distinct, include something that changes each time, such as the bar time:

{
  "ticker": "SPY",
  "action": "OPEN",
  "direction": "LONG",
  "metadata": { "message_id": "{{timenow}}" }
}

metadata.message_id is used as the dedup key when present. Otherwise Nyria hashes the whole raw body.

Errors

Every response the webhook can return. Failures are also recorded in the strategy's Logs tab.

StatusBodyMeaning
200"status": "processed"Parsed and handed to your bots.
200"rejected": trueThe strategy is not Active (draft, paused or archived).
200"status": "rejected" + reasonInstrument not in the strategy's allowed list, direction disabled, or no open position to close.
200"status": "duplicate"The identical body already arrived in the last few minutes.
400structured errorThe token in the URL is not a valid token.
404structured errorNo strategy matches that token.
413structured errorPayload is over 256KB.
422structured errorThe alert defines more option legs than an order supports.
429"error": "rate limit exceeded"More than 60 alerts a minute on this webhook.
500"error": "<reason>"Everything else, including a strike or expiry your strategy's rules cannot fill, an unknown symbol, and market-data or broker trouble. The text says which.

A 200 means Nyria parsed the alert and handed it to your bots. It does not mean the broker filled anything: check the bot's Logs tab for that.

Troubleshooting maps the common failures to fixes.

Security

  • Webhook URLs are secret. The token in the path is the only authentication on the endpoint. There is no signature header and no IP allow-list. Treat the URL like an API key.
  • If it leaks, click Rotate token on the strategy's Integration tab. The old URL stops working immediately, so update every alert source that was pointed at it.
  • Nyria never sees your broker password. Orders are placed with the OAuth token or scoped API key you authorized, which Nyria stores server-side. Nyria can't withdraw, transfer, or modify account settings. See Security for what is encrypted and what is not.

What's next?