Webhook payload reference
Every field Nyria accepts on the webhook. Send plain text or JSON, with no required template. With Pine Script, Discord and curl examples.
A Nyria webhook needs a POST to the strategy's own URL with a body that names a ticker and an action, as JSON like {"ticker": "SPY", "action": "buy"} or as the words SPY long entry. The token at the end of the URL is the only authentication, and the bot's settings set the size. Everything else, from direction and order_type to option legs, is optional.
Endpoint
POST https://trades.nyria.io/webhooks/{your_strategy_token}Copy the full URL from the strategy's Integration tab. The token at its end is a 64-character lowercase hexadecimal string with no prefix, and each strategy has its own. Keep it private. Anyone who has it can send alerts to your strategy.
Paste a payload into the alert tester to see how Nyria would read it before you send a real one.
Minimum payload
Two fields are enough:
{
"ticker": "SPY",
"action": "buy"
}Nyria finds the strategy from the token in the URL and reads buy or sell
against that strategy's settings. The bot's settings set the size, and the
order goes to the connected broker.
How buy and sell are read depends on the strategy:
- On a strategy that trades one side, there is only one reading. On a
long-only strategy,
buyopens a long andsellcloses it. - On a strategy that trades both sides, Nyria reads the alert against the open
position, the way a broker reads an order side.
buycovers an open short and otherwise opens a long.sellcloses an open long and otherwise opens a short.
A buy while you are short closes the short and stops there. To reverse in a
single alert, or to state the side explicitly, send action (OPEN or
CLOSE) together with direction (LONG or SHORT).
Plain text works too:
SPY long entryNyria reads SPY as the ticker, long as the direction and entry as the
action. There is no fixed schema to follow.
Full payload reference
Apart from the ticker and the action, every field is optional. Send one only to state what the strategy can't work out, or to override its settings for one alert.
Top-level fields
| Field | Type | Description |
|---|---|---|
instrument / ticker / symbol | string | The ticker, such as SPY or BTCUSD. All three keys mean the same thing. |
action | string | OPEN or CLOSE for entries and exits, or MODIFY or CANCEL for order management (below). Nyria also accepts and maps buy, sell, entry and exit. |
direction | string | LONG or SHORT. Send it with OPEN and CLOSE. |
price | number | Limit price as a decimal, used when order_type is limit or the strategy's limit target is Alert price. Nyria places market and limit orders only, on every broker. |
order_type | string | market or limit. Overrides the strategy's order type for this one alert, on the alert shapes listed under when Nyria reads order_type. Send "limit" with a price to place a resting limit order regardless of the strategy setting. Leave it out to use the strategy's order type. |
marketPosition / prevMarketPosition | string | TradingView's {{strategy.market_position}} and {{strategy.prev_market_position}}, which are long, short or flat. Send both and Nyria works out the action and direction from the change. No other fields are needed. |
An alert can't set the entry size. Size always comes from the bot's
settings, and Nyria ignores a quantity or notional key on an entry
alert. The one exception is MODIFY, which can re-size an order that is
already working.
Option leg fields
On a strategy whose contract selection is Provided in alert, include a
legs array, with one entry per leg. On a From my rules strategy, leave it
out. Nyria picks the strike and expiration from the strategy's leg rules, and
the webhook has no field for delta or days to expiry.
Each leg accepts these fields:
| Field | Type | Description |
|---|---|---|
symbol | string | OCC option symbol, such as SPY261120C00780000. |
side | string | CALL or PUT. |
action | string | buy_to_open, sell_to_open, buy_to_close or sell_to_close. |
strike | number | Strike price, such as 780. |
expiration | string | YYYY-MM-DD. Give it, or the leg's symbol, on every entry leg. A leg with neither has no contract to trade. |
price | number | Limit price for this leg. For a limit spread, the leg prices add up to the spread price. |
live_price | number | Live bid or ask price for this leg. |
Order management: limit orders, modify and cancel
Besides opening and closing positions, the webhook can place a resting limit
order and later modify or cancel it. OPEN, CLOSE and CANCEL
behave the same on every broker. MODIFY works on Tradier and Alpaca. Nyria
passes each action to every bot on the strategy.
Internally, Nyria turns every alert into the same four fields: action,
instrument, direction and price. The strategy decides whether SPY
trades as stock or options, and whether BTCUSD trades as spot or a perpetual.
Place a resting limit order
Add "order_type": "limit" and a price to an OPEN or CLOSE that names
its direction. At a broker, the order rests at your price until it fills or
is canceled, whatever order type the strategy uses. Nyria Paper fills it
or refuses it outright.
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": 64000
}'The size still comes from the bot's budget per entry. price only sets the limit.
When Nyria reads order_type
Nyria reads order_type on two alert shapes:
- An alert that names
action(OPENorCLOSE) anddirection(LONGorSHORT), like the one above. - A
buyorsellalert on a stock, ETF or crypto strategy, for a ticker in the strategy's ticker list, with nothing beside the ticker andactionbutprice,order_typeand a timestamp.
On any other alert, Nyria ignores order_type and uses the strategy's order
type. That includes a TradingView position change (marketPosition and
prevMarketPosition), Discord and Telegram messages, and any alert to an
options strategy set to Provided in alert. To choose the
order type alert by alert from a TradingView strategy, send action and
direction. A strategy that reverses on a position change keeps the position
fields, so set its order type on the strategy.
Modify a working order
MODIFY changes the limit price, the quantity, or both, on the order working
on that side. That can be a resting entry or a resting exit placed by
an earlier alert. Some brokers cancel and replace the order, which gives it a
new id. Nyria follows the new id.
MODIFY works on Tradier and Alpaca. Schwab and tastytrade refuse it, and the
bot log says the broker does not support order modification. To re-price a
resting entry at those brokers, send CANCEL and then a new OPEN.
Nyria Paper fills or refuses every order at once, so it never has a working order to modify.
curl -X POST https://trades.nyria.io/webhooks/YOUR_STRATEGY_TOKEN \
-H "Content-Type: application/json" \
-d '{
"action": "MODIFY",
"instrument": "BTCUSD",
"direction": "LONG",
"price": 64500
}'Cancel a working order
CANCEL cancels the working entry orders for that ticker and direction.
Use it to pull a resting limit entry before it fills. To exit a position that
has already filled, send CLOSE instead.
curl -X POST https://trades.nyria.io/webhooks/YOUR_STRATEGY_TOKEN \
-H "Content-Type: application/json" \
-d '{
"action": "CANCEL",
"instrument": "BTCUSD",
"direction": "LONG"
}'MODIFY and CANCEL only touch working orders (pending or open), and
never open a trade. A market order that filled is a position, so close it
with CLOSE. While the market is closed, a broker may reject a modify or
cancel until it reopens.
| Action | Acts on | Use it to |
|---|---|---|
OPEN | n/a | Enter a position, at market or resting with "order_type": "limit". |
CLOSE | the open position | Exit a filled position. |
MODIFY | the working order on that side (entry or exit) | Re-price a resting limit order on Tradier or Alpaca. |
CANCEL | the working entry orders | Pull a resting entry before it fills. |
Examples by alert source
TradingView Pine: equity entry
In the TradingView alert, set the webhook URL to your Nyria endpoint and the message to:
{{strategy.order.action}} {{ticker}} @ {{close}}Or send JSON:
{
"ticker": "{{ticker}}",
"action": "{{strategy.order.action}}",
"marketPosition": "{{strategy.market_position}}",
"prevMarketPosition": "{{strategy.prev_market_position}}",
"price": {{close}}
}The strategy.* placeholders exist only in a strategy() script. An
indicator() has none, so convert it to a strategy
or use the per-side messages in TradingView alert messages.
TradingView Pine: option spread
{
"ticker": "SPY",
"action": "OPEN",
"direction": "LONG",
"order_type": "limit",
"price": 1.50
}The alert carries no legs. Nyria builds both legs from the strategy's leg
rules and 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 trades SPX under the
SPXW root, which settles at the PM close.
Discord: plain text
With the Nyria Discord bot in your server, post any of these in the strategy's channel:
SPY long entryBTO 1 SPY 12/18 $780 CALL @ 14.50Close SPY longTrendSpider
TrendSpider sends webhooks from two places: account-level Alerts and
per-bot Strategy Bots. Only Strategy Bots can drive more than one Nyria
strategy. The payloads use TrendSpider's %alert_symbol% and %bot_symbol%
variables. See the TrendSpider setup guide.
curl
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
You send the same payload whatever the broker, and Nyria converts it into that
broker's order format. The option examples are for Provided in alert
strategies, which take their order type from the strategy, so they carry no
order_type. With the strategy's limit target set to Alert price, the
alert's price is the limit.
Schwab: option buy-to-open
{
"ticker": "SPY",
"action": "open",
"direction": "long",
"legs": [{ "side": "CALL", "strike": 780, "expiration": "2026-11-20" }]
}tastytrade: vertical credit spread
{
"ticker": "SPY",
"action": "OPEN",
"direction": "SHORT",
"price": 1.00,
"legs": [
{ "side": "CALL", "strike": 800, "expiration": "2026-11-20" },
{ "side": "CALL", "strike": 810, "expiration": "2026-11-20" }
]
}Alpaca: single-leg option
{
"ticker": "SPY",
"action": "open",
"direction": "long",
"legs": [{ "side": "PUT", "strike": 740, "expiration": "2026-11-20" }]
}Alpaca: crypto spot
{
"ticker": "BTCUSD",
"action": "OPEN",
"direction": "LONG",
"order_type": "limit",
"price": 64000
}Nyria sends this to Alpaca as BTC/USD, sized from the bot's budget per entry.
It converts the pair into each exchange's own format, so send the pair in
whatever form your alert source produces.
Duplicates and retries
Nyria drops duplicate alert bodies. If the same body arrives again
within 30 seconds, or within 5 minutes with no other alert in between,
the second copy is dropped and the webhook answers 200 with {"status": "duplicate"}.
This matters when your strategy scales in. If it sends the same fixed alert text twice, the second entry is dropped as a duplicate and never trades. Add a value that changes on every alert, such as the bar time:
{
"ticker": "SPY",
"action": "OPEN",
"direction": "LONG",
"metadata": { "message_id": "{{timenow}}" }
}If the body has a metadata.message_id, Nyria compares that value to spot
duplicates. Otherwise it compares a hash of the whole body.
Errors
This table lists every response the webhook can return. A structured error is
a JSON body with class, code and userMessage. The strategy's Logs tab
records failures too.
| Status | Body | Meaning |
|---|---|---|
200 | "status": "processed" | Nyria read the alert and handed it to your bots. |
200 | "rejected": true + message | The strategy isn't Active. It is a draft, paused or archived. |
200 | "status": "rejected" + reason | The ticker isn't in the strategy's list, that direction is turned off, or there is no open position to close. |
200 | "status": "duplicate" | The body repeats an earlier one. See duplicates. |
400 | structured error | The body is empty, or the token in the URL is malformed. |
404 | structured error | No strategy has that token. |
413 | structured error | The payload is larger than 256 KB. |
422 | structured error | Nyria couldn't use the alert, for example a missing field, unreadable text, an unknown symbol, no matching strike or DTE range, or more than 4 option legs. |
429 | structured error | The alert exceeded this webhook's rate limit of 10 alerts at once, then 1 a second. Nyria dropped it, and Retry-After says how long to wait. |
503 | structured error | Reading the alert or fetching market data failed temporarily. Sending the same alert again can succeed. |
500 | structured error | Any other failure, such as a missing price when the strategy takes its limit price from the alert. userMessage is generic; the strategy's Logs tab has the reason. |
A 200 means Nyria read the alert and passed it to your bots. It doesn't mean
the broker filled anything. The bot's Logs tab shows what the broker did.
For fixes to common failures, see troubleshooting.
Security
- Treat the webhook URL like an API key. The token in the path is the endpoint's only authentication. There is no signature header and no IP allowlist.
- If the URL leaks, select Rotate token on the strategy's Integration tab. The old URL stops working immediately, so update every alert source that used it.
- Nyria can place and cancel orders, but it can't move money. See security.
Next steps
- Quick start: send a first webhook, end to end
- Custom webhook setup: the full response-code table
- Alert sources: TradingView, Discord, Telegram and TrendSpider
- What you can trade: multi-leg options and crypto
- When an order fails: what happens after a rejection
- Troubleshooting: fixes listed by log message
Sell your strategies with Stripe
Sell access to your strategies through your own Stripe account. Nyria bills you at the end of each month, by member and tier.
Pricing and limits
What Nyria costs for traders and for creators, what the free plan covers, how total entry allocation sets your price, and the limits you meet on each plan.