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 entryNyria 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
| Field | Type | Description |
|---|---|---|
instrument / ticker / symbol | string | Underlying instrument (SPY, BTCUSD). All three keys are accepted interchangeably. |
action | string | OPEN / CLOSE (the canonical entry/exit actions), or MODIFY / CANCEL (order management, see below). buy/sell/entry/exit are also accepted and mapped. |
direction | string | LONG or SHORT. With the canonical OPEN/CLOSE actions, include it explicitly. |
price | number | Limit/stop price (decimal). With order_type: "limit" this is the limit price. |
order_type | string | market 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 / prevMarketPosition | string | TradingView'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:
| Field | Type | Description |
|---|---|---|
symbol | string | OCC option symbol (e.g. SPY260619C00500000). |
side | string | CALL or PUT. |
action | string | buy_to_open / sell_to_open / buy_to_close / sell_to_close. |
strike | number | Strike price (e.g. 500). |
expiration | string | YYYY-MM-DD. Omit it on an entry and Nyria uses the next expiration allowed by the strategy. |
price | number | Per-leg limit price (for limit spreads, sum across legs). |
live_price | number | Live 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.
| Action | Acts on | Use it to |
|---|---|---|
OPEN | n/a | Enter a position (market, or order_type: "limit" to rest). |
CLOSE | the open position | Exit a filled position. |
MODIFY | the working order on that side (entry or exit) | Re-price a resting limit order. |
CANCEL | the 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 SPX →
SPXW 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 entryBTO 1 SPY 6/19 $500 CALL @ 1.50Close SPY longTrendSpider
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.
| Status | Body | Meaning |
|---|---|---|
200 | "status": "processed" | Parsed and handed to your bots. |
200 | "rejected": true | The strategy is not Active (draft, paused or archived). |
200 | "status": "rejected" + reason | Instrument 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. |
400 | structured error | The token in the URL is not a valid token. |
404 | structured error | No strategy matches that token. |
413 | structured error | Payload is over 256KB. |
422 | structured error | The 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?
- Quick Start: first webhook end-to-end
- Custom webhook setup: the full response-code table
- Alert Sources: TradingView, Discord, TrendSpider (Telegram coming soon)
- What You Can Trade: multi-leg + crypto specifics
- When an Order Fails: what happens after a rejection
- Troubleshooting: error codes mapped to fixes
Unlock a Creator's Strategy
Use a Whop or Stripe subscription you already pay for to unlock a creator's paywalled Nyria strategy, then run it on your own broker account.
Pricing & Limits
What Nyria costs and every cap it enforces, in one place: the price of each plan, plus the limits on strategies, bots, option legs, DTE and allocation.