Use a Custom Webhook Source
Wire any service that can POST HTTP to Nyria. By the end you will have a working custom webhook firing real orders through your connected broker.
By the end you will have a custom-built script (or third-party service) firing alerts into Nyria, parsed against your strategy, and routed to a connected broker — using the same webhook endpoint that TradingView and Discord use under the hood.
Who this is for. You already have something that emits signals — a Python script, a Node service, a no-code automation tool, a proprietary scanner — and you want it to place orders through your Nyria-connected broker. If you're using TradingView or Discord instead, use those guides: this page covers the raw HTTP integration.
What you need before you start
- A Nyria account with a configured strategy (entry/exit rules, position sizing).
- A connected broker. The walkthrough uses Alpaca but the same payload works for every broker in the catalog.
- Anything that can send an HTTPS
POST—curl, a backend job, a Zapier/Make webhook step, a custom dashboard.
Steps
Copy your strategy webhook URL
In the Nyria app, open your strategy and go to the Integration tab. Copy the webhook URL. It looks like this:
https://trades.nyria.io/webhooks/wh_8f4c2a91b7d34e0fae9c1b6d2e8f0a4cThe path segment after /webhooks/ is your strategy's token
hash (tokenHash). It's the only authentication on the request —
treat it like a password. There is no separate Authorization
header.
Do not commit the URL to a public repo. The token hash is the full authentication. Anyone who has it can fire alerts at your strategy. If it leaks, regenerate it from the Integration tab — that rotates the token and invalidates the old one immediately.
Send the minimum-viable payload
The smallest valid body is two fields: ticker and action. Open
a terminal and run:
curl -X POST https://trades.nyria.io/webhooks/wh_REPLACE_WITH_YOUR_TOKEN \
-H "Content-Type: application/json" \
-d '{
"ticker": "AAPL",
"action": "buy"
}'Replace wh_REPLACE_WITH_YOUR_TOKEN with the token hash you copied
in Step 1. Nyria looks up the strategy by token, matches buy
against your entry rule, builds the order using the strategy's
position-sizing config, and forwards it to the connected broker.
You should see the alert show up in the strategy's Logs tab within a second or two.
Override sizing for a single alert
The strategy controls position sizing by default. To override it for
one alert, add quantity (shares/contracts) or notional (USD):
curl -X POST https://trades.nyria.io/webhooks/wh_REPLACE_WITH_YOUR_TOKEN \
-H "Content-Type: application/json" \
-d '{
"ticker": "AAPL",
"action": "buy",
"quantity": 25,
"order_type": "limit",
"price": 175.50,
"duration": "day"
}'quantity— explicit share count for equities, contract count for options.notional— dollar-based sizing (useful for crypto; e.g."notional": 500).order_type—market,limit,stop, orstop_limit. Default ismarket.price— required whenorder_typeis anything other thanmarket.duration—day,gtc,pre, orpost. Default isday.
Send a plain-text body instead of JSON
JSON is the recommended format, but if your source can only emit free-form text (older alerting platforms, some IFTTT/Zapier steps), Nyria's parser also reads plain text:
curl -X POST https://trades.nyria.io/webhooks/wh_REPLACE_WITH_YOUR_TOKEN \
-H "Content-Type: text/plain" \
--data-binary "AAPL long entry"The parser extracts the instrument (AAPL), the direction (long),
and the action (entry). Set Content-Type: text/plain so Nyria
doesn't try to JSON-decode the body.
JSON is more deterministic. Plain text is convenient, but the
parser has to infer fields. For production setups where every
alert matters, send JSON with explicit ticker + action.
Add idempotency for retry-safe sends
If your script retries on network failures (or your provider delivers the same alert twice), Nyria's default behavior protects you: identical payloads received within 60 seconds are deduplicated by hash and only the first one places an order.
If you actually want to scale into the same position — for example,
firing the same buy payload twice on purpose — add a unique
idempotency_key:
curl -X POST https://trades.nyria.io/webhooks/wh_REPLACE_WITH_YOUR_TOKEN \
-H "Content-Type: application/json" \
-d '{
"ticker": "AAPL",
"action": "buy",
"quantity": 10,
"idempotency_key": "scale-in-2026-06-05-09-31-15"
}'Each distinct idempotency_key value is treated as a new alert.
Reuse a key and Nyria treats it as a duplicate and skips it.
Recommended formats for the key:
- A monotonically increasing counter your script tracks
(
scale-in-1,scale-in-2). - An ISO-8601 timestamp with second precision
(
2026-06-05T09:31:15Z). - A UUID v4 minted per alert.
Handle the response
Nyria responds with an HTTP status code and a JSON body. Wire your sender to log or alert on non-2xx responses.
| Status | Meaning | What to do |
|---|---|---|
200 with accepted: true | Order routed to the broker. | Nothing — success. |
200 with skipped: true | Strategy is paused, instrument filtered out, or duplicate within the 60-second window. | Inspect the response reason field. Usually expected. |
401 | Token hash in URL is invalid or revoked. | Re-copy the URL from the Integration tab. |
422 | A field required by your strategy was missing or malformed. | The response lists the missing fields. Add them and resend. |
429 | Too many alerts in too short a window. | Back off and retry; consider batching upstream. |
A minimal Python sender that surfaces failures:
import requests
WEBHOOK_URL = "https://trades.nyria.io/webhooks/wh_REPLACE_WITH_YOUR_TOKEN"
def fire_alert(payload: dict) -> None:
r = requests.post(WEBHOOK_URL, json=payload, timeout=10)
r.raise_for_status()
body = r.json()
if body.get("skipped"):
print(f"Nyria skipped: {body.get('reason')}")
else:
print(f"Nyria accepted: alert id {body.get('alert_id')}")
fire_alert({"ticker": "AAPL", "action": "buy", "quantity": 10})raise_for_status() turns 4xx/5xx into exceptions so your retry
logic can see them. Always use a finite timeout — Nyria responds
quickly, but a hung socket can wedge your producer.
Confirm the order in the broker
Open your broker dashboard (or the Nyria app's bot view) and verify
the order landed. If you used the curl from Step 2 against a paper
account, you should see an AAPL market buy at the strategy's
default size.
If the order is not there, check the strategy's Logs tab. Every inbound webhook generates a log entry — accepted, skipped, or rejected — with the reason and any parse output.
JSON vs plain text — when to use which
| Use JSON when | Use plain text when |
|---|---|
| You control the source (custom script, backend service). | Your source only emits free-form strings (legacy alert tool). |
You need explicit order_type, price, duration, or option legs. | A two-word signal (AAPL long) is enough. |
| You want the response codes to map cleanly to your retry logic. | You're prototyping and just need something to fire. |
You're sending option spreads (the legs array requires JSON). | — |
For everything beyond the basics — option spreads, multi-leg orders, every accepted field — see the Webhook Payload Reference.
Idempotency rules at a glance
- Same payload within 60 seconds → deduplicated automatically.
No
idempotency_keyneeded for at-least-once retry safety. - Same payload after 60 seconds → treated as a new alert. If you
do not want this, add an
idempotency_keythat you stop reusing after a few minutes. - Distinct
idempotency_keyvalues → always treated as separate alerts, even if every other field matches. This is the scale-in path. - Same
idempotency_keyreused → second send is skipped with a200 skipped: trueresponse.
The dedupe window is per strategy. Two different strategies receiving the same payload at the same second are independent — each will fire its own order. If you fan one signal out to multiple strategies, expect multiple orders.
Sample: full crypto buy via curl
A complete crypto example that exercises notional sizing, a limit order, and an idempotency key:
curl -X POST https://trades.nyria.io/webhooks/wh_REPLACE_WITH_YOUR_TOKEN \
-H "Content-Type: application/json" \
-d '{
"ticker": "BTC/USDT",
"action": "buy",
"notional": 250,
"order_type": "limit",
"price": 65000,
"duration": "gtc",
"idempotency_key": "btc-dca-2026-06-05"
}'For a spot crypto strategy connected to Binance, this places a
$250-notional limit buy at $65,000, good-til-cancelled, and is safe
to retry indefinitely as long as the idempotency_key does not
change.
Sample: full equity exit via curl
curl -X POST https://trades.nyria.io/webhooks/wh_REPLACE_WITH_YOUR_TOKEN \
-H "Content-Type: application/json" \
-d '{
"ticker": "AAPL",
"action": "exit",
"sentiment": "flat"
}'sentiment: flat mirrors TradingView's {{strategy.market_position}}
post-exit value and tells Nyria the strategy is now out of the
market. Use this for full-close alerts from any source.
Troubleshooting
- Nothing happens after the POST. Check the strategy Logs tab.
If there is no row, the request never reached Nyria — verify the
URL and that your sender is hitting
https://(nothttp://). 401 Unauthorized. The token hash is wrong or has been regenerated. Re-copy it from the strategy's Integration tab.422with a field list. Your strategy requires a field your payload did not include — for example, an option strategy needs alegsarray. The response body lists exactly which fields are missing.- Order placed but on the wrong instrument. The parser inferred
a different ticker from your text. Switch to JSON and set
tickerexplicitly. - Duplicates skipped when you meant to scale in. Add an
idempotency_keythat varies per intended order.
For a deeper error-code map, see /troubleshooting.
What's next
- Webhook Payload Reference — every field Nyria accepts, with examples for every broker.
- Alpaca Integration — connect the broker used in this tutorial.
- Alert Sources — TradingView and Discord setups built on the same webhook (Telegram coming soon).
- Strategies — entry/exit rules and sizing config that this webhook flows into.
Connect TrendSpider alerts to Nyria
Send TrendSpider alerts and Strategy Bot signals to Nyria as webhooks so connected brokers execute the trade automatically. Includes copy-paste payloads using TrendSpider's real %alert_symbol% / %bot_symbol% variables.
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.