Nyria Docs

Webhook Payload Reference

Complete reference for every field Nyria accepts on the webhook. Send any text or JSON — no required template. Copy-paste Pine + Discord + cURL examples included.

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. 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, /ES). 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.
sentimentstringTradingView {{strategy.market_position}}long, short, flat.
pricenumberLimit/stop price (decimal). With order_type: "limit" this is the limit price.
live_pricenumberLive bid/ask price from your market data provider (used for paper fills + sizing math).
quantitynumberOverride the bot's default position size for this one alert.
notionalnumberDollar-based sizing (crypto).
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.
durationstringday, gtc, pre, post. Default: day.
tagstringFree-text tag (≤64 chars) for tracking in logs.

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 or relative (+7 days, next_friday).
quantitynumberContracts on this leg.
pricenumberPer-leg limit price (for limit spreads, sum across legs).
delta_targetnumberAuto-select strike by delta (0.30, 0.16, etc.).
dte_min / dte_maxnumberDays-to-expiry window for auto-select.

Top-level option fields

FieldTypeDescription
order_effectstringdebit, credit, even (for spreads).
minimum_budgetnumberPer-leg min budget (used for sizing math when no explicit quantity).

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 (e.g. a take-profit). Brokers that cancel-and-replace will assign a new order id internally; Nyria tracks it for you.

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
OPENEnter 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}}",
  "sentiment": "{{strategy.market_position}}",
  "price": {{close}},
  "live_price": {{close}}
}

TradingView Pine — option spread

{
  "ticker": "SPY",
  "action": "open",
  "direction": "{{strategy.market_position}}",
  "order_effect": "debit",
  "order_type": "limit",
  "price": 1.50,
  "legs": [
    {
      "side": "CALL",
      "action": "buy_to_open",
      "delta_target": 0.30,
      "dte_min": 7,
      "dte_max": 45,
      "quantity": 1
    },
    {
      "side": "CALL",
      "action": "sell_to_open",
      "delta_target": 0.20,
      "dte_min": 7,
      "dte_max": 45,
      "quantity": 1
    }
  ]
}

TradingView Pine — SPX iron condor

{
  "ticker": "SPX",
  "action": "open",
  "direction": "long",
  "order_effect": "credit",
  "order_type": "limit",
  "price": 2.00,
  "legs": [
    { "side": "PUT", "action": "buy_to_open", "strikes_away": -10, "dte_min": 0, "dte_max": 0, "quantity": 1 },
    { "side": "PUT", "action": "sell_to_open", "delta_target": 0.16, "dte_min": 0, "dte_max": 0, "quantity": 1 },
    { "side": "CALL", "action": "sell_to_open", "delta_target": 0.16, "dte_min": 0, "dte_max": 0, "quantity": 1 },
    { "side": "CALL", "action": "buy_to_open", "strikes_away": 10, "dte_min": 0, "dte_max": 0, "quantity": 1 }
  ]
}

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

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, 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": "buy",
    "quantity": 10,
    "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", "action": "buy_to_open", "strike": 500, "expiration": "2026-06-19", "quantity": 1 }],
  "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",
  "order_effect": "credit",
  "order_type": "limit",
  "price": 1.00,
  "legs": [
    { "side": "CALL", "action": "sell_to_open", "strike": 510, "expiration": "2026-06-19", "quantity": 1 },
    { "side": "CALL", "action": "buy_to_open", "strike": 520, "expiration": "2026-06-19", "quantity": 1 }
  ]
}

→ 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", "action": "buy_to_open", "delta_target": 0.30, "dte_min": 7, "dte_max": 21, "quantity": 1 }],
  "order_type": "market"
}

Binance — crypto spot

{
  "ticker": "BTC/USDT",
  "action": "buy",
  "quantity": 0.05,
  "order_type": "limit",
  "price": 60000
}

→ Binance receives symbol=BTCUSDT, side=BUY, type=LIMIT, quantity=0.05, price=60000, timeInForce=GTC.

Idempotency + retries

If you send the same alert twice within 60 seconds, Nyria deduplicates by hash. To force a duplicate (e.g., scaling-in), include a unique idempotency_key:

{
  "ticker": "SPY",
  "action": "buy",
  "idempotency_key": "scale-in-2"
}

Errors

If Nyria can't parse the alert, the webhook responds with a 4xx and the strategy log records the failure. Common causes:

  • Token in URL is invalid → 401
  • Strategy is paused → 200 with skipped: true
  • Instrument doesn't match strategy filter → 200 with skipped: true
  • Required field for the order type missing → 422 with field list

The full error format and codes are documented at /troubleshooting.

Security

  • Webhook URLs are secret. Treat them like API keys. Rotate by regenerating the strategy token in the Integration tab.
  • For higher-stakes setups, restrict the webhook to specific IP ranges via the strategy's security settings.
  • Nyria never stores broker credentials. Every order is placed via the OAuth token or scoped API key you authorized — Nyria can't withdraw, transfer, or modify account settings.

What's next?