Webhooks BETA
Webhooks provide real-time notifications when specific events occur in our system. No more polling required!
⚠️ Beta Feature: The webhook functionality is currently in beta. While fully functional, the API and behavior may change in future releases.
Overview
Webhooks allow you to:
- 📦 Monitor product stock changes
- 💰 Track price updates
- 🔄 Receive real-time notifications
- 🔐 Secure payload verification
Available Events
| Event | Description | Trigger |
|---|---|---|
productOutOfStock | Product stock reaches zero | Stock: >0 → 0 |
productBackInStock | Product becomes available | Stock: 0 → >0 |
productPriceChanged | Product price updated | Any price change |
Webhook Management
Get All Webhooks
GET/api/webhooks
json
{
"betaNotice": "The webhook functionality is currently in beta...",
"webhooks": [
{
"_id": "webhook_id_1",
"customerId": "customer_id",
"url": "https://your-domain.com/webhook",
"events": {
"productOutOfStock": true,
"productBackInStock": true,
"productPriceChanged": false
},
"active": true,
"createdAt": "2023-06-15T12:00:00Z",
"updatedAt": "2023-06-15T12:00:00Z"
}
]
}bash
curl -X GET https://api.attivita.de/api/webhooks \
-H "Authorization: Bearer YOUR_API_ACCESS_TOKEN"Create Webhook
POST/api/webhooks
json
{
"url": "https://your-domain.com/webhook",
"events": {
"productOutOfStock": true,
"productBackInStock": true,
"productPriceChanged": false
}
}json
{
"betaNotice": "The webhook functionality is currently in beta...",
"webhook": {
"_id": "webhook_id",
"customerId": "customer_id",
"url": "https://your-domain.com/webhook",
"events": {
"productOutOfStock": true,
"productBackInStock": true,
"productPriceChanged": false
},
"active": true,
"secret": "whsec_1234567890abcdef",
"createdAt": "2023-06-15T12:00:00Z",
"updatedAt": "2023-06-15T12:00:00Z"
}
}Important
Store the secret securely! It's only shown once and is required for signature verification.
Update Webhook
PATCH/api/webhooks/:id
json
{
"url": "https://new-domain.com/webhook",
"events": {
"productOutOfStock": true,
"productBackInStock": true,
"productPriceChanged": true
},
"active": true
}Delete Webhook
DELETE/api/webhooks/:id
Regenerate Secret
POST/api/webhooks/:id/regenerate-secret
Use this endpoint if you believe your webhook secret has been compromised.
Event Payloads
Product Out of Stock
json
{
"event": "productOutOfStock",
"timestamp": 1623761345123,
"data": {
"productId": "507f1f77bcf86cd799439011",
"name": "Microsoft Office 2021",
"sku": "MS-OFF-2021"
}
}Product Back in Stock
json
{
"event": "productBackInStock",
"timestamp": 1623761345123,
"data": {
"productId": "507f1f77bcf86cd799439011",
"name": "Microsoft Office 2021",
"sku": "MS-OFF-2021",
"availableStock": 50
}
}Product Price Changed
json
{
"event": "productPriceChanged",
"timestamp": 1623761345123,
"data": {
"productId": "507f1f77bcf86cd799439011",
"name": "Microsoft Office 2021",
"sku": "MS-OFF-2021",
"oldPrice": 249.99,
"newPrice": 199.99
}
}Security & Verification
Every webhook request includes a signature in the X-Webhook-Signature header. Always verify this signature!
Signature Verification
javascript
const crypto = require('crypto');
function verifyWebhookSignature(payload, signature, secret) {
const computedSignature = crypto
.createHmac('sha256', secret)
.update(JSON.stringify(payload))
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(computedSignature)
);
}
// Express.js handler
app.post('/webhook', express.raw({type: 'application/json'}), (req, res) => {
const signature = req.headers['x-webhook-signature'];
const payload = JSON.parse(req.body);
if (!signature) {
return res.status(401).send('No signature');
}
if (!verifyWebhookSignature(payload, signature, process.env.WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
// Process webhook
console.log('Event:', payload.event);
console.log('Data:', payload.data);
res.status(200).send('OK');
});python
import hmac
import hashlib
import json
def verify_webhook_signature(payload, signature, secret):
computed_signature = hmac.new(
secret.encode(),
json.dumps(payload).encode(),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature, computed_signature)
# Flask handler
@app.route('/webhook', methods=['POST'])
def webhook():
signature = request.headers.get('X-Webhook-Signature')
if not signature:
return 'No signature', 401
payload = request.get_json()
if not verify_webhook_signature(payload, signature, WEBHOOK_SECRET):
return 'Invalid signature', 401
# Process webhook
print(f"Event: {payload['event']}")
print(f"Data: {payload['data']}")
return 'OK', 200php
function verifyWebhookSignature($payload, $signature, $secret) {
$computedSignature = hash_hmac(
'sha256',
json_encode($payload),
$secret
);
return hash_equals($signature, $computedSignature);
}
// Handler
$signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';
$payload = json_decode(file_get_contents('php://input'), true);
if (!$signature) {
http_response_code(401);
exit('No signature');
}
if (!verifyWebhookSignature($payload, $signature, $_ENV['WEBHOOK_SECRET'])) {
http_response_code(401);
exit('Invalid signature');
}
// Process webhook
error_log('Event: ' . $payload['event']);
error_log('Data: ' . print_r($payload['data'], true));
http_response_code(200);
echo 'OK';Best Practices
1. Respond Quickly
- Acknowledge receipt within 5 seconds
- Process webhooks asynchronously
- Return 2xx status code immediately
2. Handle Failures Gracefully
- Implement idempotency
- Handle duplicate deliveries
- Log all webhook events
3. Security First
- Always verify signatures
- Use HTTPS endpoints only
- Validate payload structure
4. Monitor & Debug
- Log all webhook activity
- Monitor endpoint availability
- Set up alerting for failures
Testing Webhooks
Local Development
Use tools like ngrok to expose your local webhook endpoint:
bash
# Start your local server
npm run dev
# In another terminal
ngrok http 3000
# Use the ngrok URL for webhook registration
https://abc123.ngrok.io/webhookWebhook Testing Tools
- Webhook.site - Instant webhook testing
- RequestBin - Inspect webhook payloads
- Postman - Mock webhook endpoints
Troubleshooting
Common Issues
| Issue | Solution |
|---|---|
| No webhooks received | Check if webhook is active and URL is correct |
| 401 Unauthorized | Verify signature implementation |
| Timeout errors | Respond within 5 seconds |
| Duplicate events | Implement idempotency |
Webhook Delivery
- Maximum retry attempts: 3
- Retry delays: 10s, 30s, 60s
- Webhook disabled after 10 consecutive failures
Next Steps
- Implement Webhook Security
- Set up Telegram Bot as alternative
- Read Best Practices