Skip to main content

Webhooks

Webhooks enable Anava to send detection data to your custom applications, automation platforms, or third-party services via HTTP POST requests.

Use Cases

IntegrationExample
Custom ApplicationsSend detection data to your security dashboard
AutomationTrigger IFTTT, Zapier, or n8n workflows
Access ControlLock doors when threats detected
LightingActivate lights on person detection
MessagingPost to Slack, Teams, or Discord

Webhook Payload

When a detection occurs, Anava sends a JSON payload to your endpoint:

{
"eventType": "detection",
"version": "1.0",
"timestamp": "2024-12-23T10:30:00.000Z",
"device": {
"id": "B8A44F45D624",
"name": "Warehouse-Cam-01",
"groupId": "warehouse-north"
},
"profile": {
"id": "intrusion-detection",
"name": "Intrusion Detection"
},
"skill": {
"id": "weapon-detection",
"name": "Weapon Detection"
},
"session": {
"id": "ses_abc123def456",
"url": "https://anava.ai/sessions/ses_abc123def456"
},
"analysis": {
"objects": [
{
"name": "Person",
"detected": true,
"confidence": 0.95,
"boundingBox": {"x": 100, "y": 200, "width": 150, "height": 300}
}
],
"questions": [
{
"id": 1,
"name": "is_authorized",
"text": "Is the person authorized?",
"answer": false,
"type": "bool"
},
{
"id": 2,
"name": "description",
"text": "Describe what you see",
"answer": "Adult male in dark clothing near the emergency exit",
"type": "string"
}
],
"summary": "Unauthorized person detected near emergency exit"
},
"imageUrl": "https://storage.googleapis.com/anava-frames/ses_abc123/frame.jpg"
}

Configuring Webhooks

Step 1: Create Webhook Endpoint

In your application, create an endpoint to receive POST requests:

// Example: Express.js endpoint
app.post('/anava-webhook', (req, res) => {
const detection = req.body;

console.log('Detection received:', detection);

// Process the detection
if (detection.analysis.objects.some(o => o.name === 'Weapon')) {
triggerEmergencyResponse(detection);
}

// Return 200 to acknowledge receipt
res.status(200).send('OK');
});

Step 2: Configure in Anava

  1. Navigate to SettingsIntegrationsWebhooks
  2. Click + Add Webhook
  3. Enter your endpoint URL
  4. Configure options (below)
  5. Save and test

Webhook Configuration Options

OptionDescriptionDefault
URLYour HTTPS endpointRequired
MethodHTTP methodPOST
HeadersCustom headersNone
SecretSigning key for verificationNone
RetryRetry on failure3 attempts
TimeoutRequest timeout10 seconds

Step 3: Test Webhook

  1. Click Test Webhook in configuration
  2. Verify your endpoint receives the test payload
  3. Check for 200 OK response

Security

HTTPS Required

Webhooks must use HTTPS endpoints. HTTP endpoints are rejected for security.

Signature Verification

When a secret is configured, Anava signs requests using HMAC-SHA256:

X-Anava-Signature: sha256=abc123...
X-Anava-Timestamp: 1703325000

Verify the signature in your endpoint:

const crypto = require('crypto');

function verifySignature(body, signature, timestamp, secret) {
const payload = `${timestamp}.${JSON.stringify(body)}`;
const expected = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');

return `sha256=${expected}` === signature;
}

app.post('/anava-webhook', (req, res) => {
const signature = req.headers['x-anava-signature'];
const timestamp = req.headers['x-anava-timestamp'];

if (!verifySignature(req.body, signature, timestamp, SECRET)) {
return res.status(401).send('Invalid signature');
}

// Process verified request
// ...
});

IP Allowlisting

Anava webhook requests originate from these IP ranges:

  • GCP Cloud Functions IPs (varies by region)
  • Check current IPs in your Anava dashboard

Retry Policy

Failed webhook deliveries are retried automatically:

AttemptDelay
1Immediate
230 seconds
32 minutes
410 minutes
Final1 hour

After all retries fail, the event is logged for manual review.

Filtering Webhooks

Configure which events trigger webhooks:

By Detection Type

{
"filter": {
"objects": ["Person", "Weapon"],
"minConfidence": 0.9
}
}

By Group/Device

{
"filter": {
"groups": ["high-security", "entrances"],
"devices": ["B8A44F45D624"]
}
}

By Time

{
"filter": {
"schedule": "outside_business_hours"
}
}

Integration Examples

Slack Notification

const axios = require('axios');

app.post('/anava-webhook', async (req, res) => {
const detection = req.body;

await axios.post(SLACK_WEBHOOK_URL, {
text: `*Alert:* ${detection.analysis.summary}`,
attachments: [{
color: 'danger',
fields: [
{ title: 'Camera', value: detection.device.name },
{ title: 'Time', value: new Date(detection.timestamp).toLocaleString() }
],
image_url: detection.imageUrl
}]
});

res.status(200).send('OK');
});

Home Assistant

# configuration.yaml
automation:
- alias: "Anava Person Detection"
trigger:
platform: webhook
webhook_id: anava_detection
condition:
- condition: template
value_template: "{{ trigger.json.analysis.objects | selectattr('name', 'eq', 'Person') | list | length > 0 }}"
action:
- service: light.turn_on
target:
entity_id: light.outdoor_lights

IFTTT

  1. Create IFTTT Webhooks applet
  2. Use your IFTTT webhook URL as Anava endpoint
  3. Configure IFTTT to trigger desired actions

Zapier

  1. Create Zap with Webhooks by Zapier trigger
  2. Use custom webhook URL from Zapier
  3. Configure actions (email, SMS, sheets, etc.)

Troubleshooting

Webhook Not Received

  1. Check endpoint is reachable

    • Test with curl: curl -X POST https://your-endpoint.com/webhook
    • Verify SSL certificate is valid
  2. Check firewall rules

    • Allow inbound HTTPS from Anava IPs
    • Check any WAF rules
  3. Check Anava logs

    • View webhook delivery status in dashboard
    • Check for error responses

Signature Verification Failing

  1. Check secret configuration

    • Ensure same secret on both sides
    • Check for whitespace issues
  2. Check timestamp

    • Ensure server clock is synchronized
    • Allow some timestamp tolerance

Timeout Issues

  1. Optimize endpoint

    • Return 200 immediately
    • Process async if needed
  2. Check network latency

    • Consider endpoint closer to GCP region

Best Practices

Respond Quickly

Return 200 immediately, process async:

app.post('/anava-webhook', (req, res) => {
// Acknowledge immediately
res.status(200).send('OK');

// Process async
processDetection(req.body).catch(console.error);
});

Handle Duplicates

Use session ID for idempotency:

const processed = new Set();

app.post('/anava-webhook', (req, res) => {
const sessionId = req.body.session.id;

if (processed.has(sessionId)) {
return res.status(200).send('Already processed');
}

processed.add(sessionId);
// Process...
});

Monitor Webhook Health

  • Track success/failure rates
  • Alert on repeated failures
  • Log payloads for debugging