Webhooks
BirdNET-NG can send HTTP notifications to external services when events occur.
Setup
Create webhooks in the web UI under Tenant Settings > Webhooks, or via the API:
curl -X POST https://birdnet.example.com/api/webhooks \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"tenantId": "<uuid>",
"name": "Slack Notifications",
"url": "https://hooks.slack.com/services/...",
"secret": "my-webhook-secret",
"eventTypes": ["detection.rare", "satellite.offline"]
}'
Event Types
| Event | Trigger |
|---|---|
detection.new |
Any new bird detection |
detection.rare |
Rare species detected (watchlist or frequency-based) |
satellite.offline |
Satellite goes offline |
Payload
{
"event": "detection.rare",
"timestamp": "2026-03-22T10:30:00Z",
"tenantId": "uuid",
"data": {
"detectionId": "uuid",
"species": "Loxia curvirostra",
"commonName": "Red Crossbill",
"confidence": 0.82,
"satelliteName": "Garden Pi",
"satelliteId": "uuid",
"isRare": true,
"rareReason": "First detection at this location"
}
}
HMAC Verification
If a secret is configured, the payload is signed with HMAC-SHA256. The signature is sent in the X-Webhook-Signature header:
X-Webhook-Signature: sha256=<hex-encoded-hmac>
To verify in your receiver:
import hmac, hashlib
expected = hmac.new(
secret.encode(),
request.body,
hashlib.sha256
).hexdigest()
assert hmac.compare_digest(f"sha256={expected}", request.headers["X-Webhook-Signature"])
Management
| Action | API | UI |
|---|---|---|
| List webhooks | GET /api/webhooks?tenantId=<id> |
Tenant Settings page |
| Create | POST /api/webhooks |
Tenant Settings page |
| Delete | DELETE /api/webhooks/:id |
Tenant Settings page |
| Test | POST /api/webhooks/:id/test |
Tenant Settings page |
Testing sends a sample payload to verify the URL is reachable and returns the HTTP status code.