Receive real-time HTTP notifications when events occur in your account
Webhooks allow your application to receive real-time notifications when certain events occur in your StockAlert.pro account. Instead of polling the API for changes, webhooks push data to your endpoint as soon as an event happens.
Tip: You can have up to 5 webhook endpoints per account, allowing you to send different events to different services.
| Event | Description | Status |
|---|---|---|
alert.triggered | Alert condition has been met and notification sent | Available |
alert.created | New alert created via API or dashboard | Coming Soon |
alert.updated | Alert settings changed (paused/reactivated) | Coming Soon |
alert.deleted | Alert permanently removed | Coming Soon |
Note: Additional events will be added based on user demand. Let us know which events you'd like to see!
{
"event": "alert.triggered",
"timestamp": "2025-01-01T12:00:00.000Z",
"data": {
"alert": {
"id": "a5d7e3f0-1234-4d8a-9c2b-111111111111",
"symbol": "AAPL",
"condition": "price_above",
"threshold": 200,
"status": "triggered"
},
"stock": {
"symbol": "AAPL",
"price": 201.5,
"change": 2.3,
"change_percent": 1.15
}
}
}/api/v1/webhooksGet a list of all configured webhooks.
{
"success": true,
"data": [
{
"id": "wh_1234567890",
"url": "https://your-app.com/webhook",
"events": ["alert.triggered"],
"is_active": true,
"created_at": "2024-01-01T00:00:00Z"
}
],
"meta": {
"rate_limit": { "limit": 1000, "remaining": 999, "reset": 1736180400000 }
}
}/api/v1/webhooks/{id}Get a single webhook by its id.
curl -X GET https://stockalert.pro/api/v1/webhooks/wh_1234567890 \
-H "X-API-Key: sk_your_api_key"{
"success": true,
"data": {
"id": "wh_1234567890",
"url": "https://example.com/webhook",
"events": ["alert.triggered"],
"is_active": true,
"created_at": "2024-01-01T00:00:00Z"
},
"meta": {
"rate_limit": { "limit": 1000, "remaining": 999, "reset": 1736180400000 }
}
}/api/v1/webhooksRegister a new webhook endpoint.
{
"url": "https://your-app.com/webhook",
"events": ["alert.triggered"] // Currently the only available event
}url - The HTTPS endpoint that will receive webhook eventsevents - Array of event types to subscribe to/api/v1/webhooks/{id}Remove a webhook endpoint.
curl -X DELETE https://stockalert.pro/api/v1/webhooks/wh_1234567890 \
-H "X-API-Key: sk_your_api_key"/api/v1/webhooks/testSend a test event to your webhook URL. Slack URLs get a Slack-formatted payload without signature.
{
"url": "https://example.com/webhook",
"secret": "your-webhook-secret"
}curl -X POST https://stockalert.pro/api/v1/webhooks/test \
-H "X-API-Key: sk_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/webhook",
"secret": "your-webhook-secret"
}'{
"success": true,
"data": {
"status": 200,
"statusText": "OK",
"response": "ok"
},
"meta": {
"rate_limit": { "limit": 5, "remaining": 4, "reset": 1736180400000 }
}
}Every webhook request includes a signature that you should verify to ensure the request came from StockAlert.pro.
X-StockAlert-Signature: a1b2c3d4e5f6...
X-StockAlert-Event: alert.triggered
X-StockAlert-Timestamp: 2024-01-05T10:30:00ZThe signature is the lowercase hex digest of the JSON payload, calculated with HMAC‑SHA256 using your webhook secret.
const crypto = require('crypto');
function verifyWebhookSignature(payload, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(payload, 'utf8')
.digest('hex');
return signature && crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}
// Express.js example
app.post('/webhook', express.raw({type: 'application/json'}), (req, res) => {
const signature = req.headers['x-stockalert-signature'];
const payload = req.body;
if (!verifyWebhookSignature(payload, signature, process.env.WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
// Process webhook...
res.status(200).send('OK');
});import hmac
import hashlib
def verify_webhook_signature(payload, signature, secret):
expected = hmac.new(
secret.encode('utf-8'),
payload.encode('utf-8'),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature or '', expected)
# Flask example
@app.route('/webhook', methods=['POST'])
def webhook():
signature = request.headers.get('X-StockAlert-Signature')
payload = request.get_data(as_text=True)
if not verify_webhook_signature(payload, signature, os.environ['WEBHOOK_SECRET']):
return 'Invalid signature', 401
# Process webhook...
return 'OK', 200During development, you can use services like ngrok or webhook.site to test webhook deliveries:
# 1. Start your local server
npm run dev # Runs on http://localhost:3000
# 2. Expose it with ngrok
ngrok http 3000
# 3. Use the HTTPS URL from ngrok as your webhook endpoint
https://abc123.ngrok.io/api/webhookNote: Webhook endpoints must use HTTPS. HTTP URLs will be rejected for security reasons.