View Categories

Webhooks API

2 min read

Webhooks API #

Set up webhooks to receive real-time notifications when events occur in your VoxPria account.

Create Webhook #

Endpoint: POST /api/v1/webhooks

curl -X POST "https://app.voxpria.com/api/v1/webhooks" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://yourapp.com/webhooks/voxpria",
    "events": [
      "call.completed",
      "campaign.finished"
    ],
    "active": true
  }'

Response #

{
  "success": true,
  "data": {
    "webhookId": "webhook_abc123",
    "url": "https://yourapp.com/webhooks/voxpria",
    "events": ["call.completed", "campaign.finished"],
    "secret": "whsec_xyz789...",
    "active": true
  }
}
⚠️ Important: Save the webhook secret – you’ll need it to verify webhook signatures!

List Webhooks #

Endpoint: GET /api/v1/webhooks

curl -X GET "https://app.voxpria.com/api/v1/webhooks" \
  -H "Authorization: Bearer YOUR_API_KEY"

Available Events #

Event Triggered When
call.started Call begins
call.completed Call finishes successfully
call.failed Call fails
campaign.started Campaign begins
campaign.finished Campaign completes
campaign.paused Campaign is paused

Webhook Payload #

Example call.completed payload:

{
  "event": "call.completed",
  "timestamp": "2025-02-09T12:00:00Z",
  "data": {
    "callId": "call_xyz789",
    "status": "completed",
    "duration": 127,
    "toNumber": "+14155551234",
    "recording": "https://...",
    "transcript": "..."
  }
}

Verifying Webhook Signatures #

Verify webhooks are from VoxPria using the signature:

Node.js #

const crypto = require('crypto');

function verifyWebhookSignature(payload, signature, secret) {
  const hmac = crypto
    .createHmac('sha256', secret)
    .update(JSON.stringify(payload))
    .digest('hex');
  
  return `sha256=${hmac}` === signature;
}

// In your webhook handler
app.post('/webhooks/voxpria', (req, res) => {
  const signature = req.headers['x-voxpria-signature'];
  const isValid = verifyWebhookSignature(
    req.body,
    signature,
    process.env.WEBHOOK_SECRET
  );
  
  if (!isValid) {
    return res.status(401).send('Invalid signature');
  }
  
  // Process webhook
  console.log('Event:', req.body.event);
  res.status(200).send('OK');
});

Python #

import hmac
import hashlib
import json

def verify_webhook_signature(payload, signature, secret):
    computed = hmac.new(
        secret.encode(),
        json.dumps(payload).encode(),
        hashlib.sha256
    ).hexdigest()
    
    return f"sha256={computed}" == signature

# In your webhook handler
@app.route('/webhooks/voxpria', methods=['POST'])
def webhook_handler():
    signature = request.headers.get('X-Voxpria-Signature')
    
    if not verify_webhook_signature(
        request.json,
        signature,
        os.getenv('WEBHOOK_SECRET')
    ):
        return 'Invalid signature', 401
    
    # Process webhook
    print('Event:', request.json['event'])
    return 'OK', 200

Best Practices #

  • ✅ Always verify webhook signatures
  • ✅ Respond with 200 status quickly
  • ✅ Process webhooks asynchronously
  • ✅ Implement idempotency (webhooks may be sent multiple times)
  • ✅ Use HTTPS URLs only
  • ✅ Handle webhook retries gracefully
💡 Pro Tip: Use webhooks instead of polling the API for real-time updates. It’s more efficient and reduces API calls.

Leave A Comment

Go to Top