Skip to main content

Overview

Webhooks allow you to receive real-time notifications when events occur in your SmartAlex account. Configure webhook endpoints to integrate SmartAlex with your CRM, analytics tools, or custom applications.

Setting Up Webhooks

Create a Webhook Endpoint

curl -X POST "https://api.getsmartalex.com/v1/webhooks" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-server.com/webhooks/smartalex",
    "events": ["call.completed", "campaign.completed"],
    "secret": "your_webhook_secret"
  }'

Parameters

ParameterTypeRequiredDescription
urlstringYesHTTPS endpoint to receive webhooks
eventsarrayYesEvent types to subscribe to
secretstringNoSecret for signature verification
enabledbooleanNoWhether webhook is active (default: true)

Response

{
  "data": {
    "id": "webhook_abc123",
    "url": "https://your-server.com/webhooks/smartalex",
    "events": ["call.completed", "campaign.completed"],
    "enabled": true,
    "created_at": "2024-01-16T10:00:00Z"
  }
}

Event Types

Call Events

EventDescription
call.startedCall has been initiated
call.connectedCall was answered
call.completedCall has ended
call.failedCall could not be completed

Campaign Events

EventDescription
campaign.startedCampaign has begun calling
campaign.pausedCampaign was paused
campaign.resumedCampaign was resumed
campaign.completedCampaign finished all contacts

Contact Events

EventDescription
contact.createdNew contact was added
contact.updatedContact was modified
contact.deletedContact was removed
contact.dncContact marked Do Not Call

Callback Events

EventDescription
callback.scheduledNew callback was scheduled
callback.completedCallback was made
callback.cancelledCallback was cancelled

Webhook Payload

All webhook payloads follow this structure:
{
  "id": "evt_xyz789",
  "type": "call.completed",
  "created_at": "2024-01-16T14:30:00Z",
  "data": {
    // Event-specific data
  }
}

Call Completed Payload

{
  "id": "evt_xyz789",
  "type": "call.completed",
  "created_at": "2024-01-16T14:30:00Z",
  "data": {
    "call": {
      "id": "call_abc123",
      "direction": "inbound",
      "agent_id": "agent_def456",
      "phone_number": "+15551234567",
      "contact_id": "contact_xyz789",
      "status": "completed",
      "duration": 245,
      "sentiment": "positive",
      "cost": 0.45,
      "recording_url": "https://recordings.getsmartalex.com/call_abc123.mp3",
      "summary": "Customer scheduled appointment for next Tuesday.",
      "created_at": "2024-01-16T14:26:00Z",
      "ended_at": "2024-01-16T14:30:05Z"
    }
  }
}

Campaign Completed Payload

{
  "id": "evt_abc456",
  "type": "campaign.completed",
  "created_at": "2024-01-16T18:00:00Z",
  "data": {
    "campaign": {
      "id": "campaign_abc123",
      "name": "January Outreach",
      "contacts_total": 500,
      "contacts_called": 500,
      "contacts_connected": 312,
      "contacts_voicemail": 98,
      "contacts_failed": 90,
      "connect_rate": 0.624,
      "total_cost": 125.50,
      "started_at": "2024-01-15T09:00:00Z",
      "completed_at": "2024-01-16T18:00:00Z"
    }
  }
}

Contact Created Payload

{
  "id": "evt_def789",
  "type": "contact.created",
  "created_at": "2024-01-16T10:00:00Z",
  "data": {
    "contact": {
      "id": "contact_new123",
      "phone": "+15551234567",
      "first_name": "John",
      "last_name": "Smith",
      "email": "john@example.com",
      "created_at": "2024-01-16T10:00:00Z"
    }
  }
}

Signature Verification

If you provide a secret when creating a webhook, SmartAlex will include a signature header for verification.

Headers

HeaderDescription
X-SmartAlex-SignatureHMAC-SHA256 signature
X-SmartAlex-TimestampUnix timestamp of the request

Verification Example

const crypto = require('crypto');

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

  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expectedSignature)
  );
}

// In your webhook handler
app.post('/webhooks/smartalex', (req, res) => {
  const signature = req.headers['x-smartalex-signature'];
  const timestamp = req.headers['x-smartalex-timestamp'];

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

  // Process the webhook
  const event = req.body;
  console.log('Received event:', event.type);

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

Managing Webhooks

List Webhooks

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

Update Webhook

curl -X PUT "https://api.getsmartalex.com/v1/webhooks/webhook_abc123" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "events": ["call.completed", "call.failed"],
    "enabled": true
  }'

Delete Webhook

curl -X DELETE "https://api.getsmartalex.com/v1/webhooks/webhook_abc123" \
  -H "Authorization: Bearer YOUR_API_KEY"

Retry Policy

If your endpoint returns an error (4xx or 5xx) or times out, SmartAlex will retry:
AttemptDelay
1Immediate
21 minute
35 minutes
430 minutes
52 hours
After 5 failed attempts, the webhook delivery is marked as failed. You can view failed deliveries in your dashboard.

Best Practices

Return a 200 response as soon as you receive the webhook. Process the data asynchronously to avoid timeouts.
app.post('/webhooks/smartalex', (req, res) => {
  // Acknowledge immediately
  res.status(200).send('OK');

  // Process asynchronously
  processWebhook(req.body).catch(console.error);
});
Webhooks may be delivered more than once. Use the event id to deduplicate:
const processedEvents = new Set();

async function processWebhook(event) {
  if (processedEvents.has(event.id)) {
    return; // Already processed
  }
  processedEvents.add(event.id);

  // Process the event
}
Webhook endpoints must use HTTPS. HTTP endpoints will be rejected.
Always verify the webhook signature to ensure requests are from SmartAlex.

Testing Webhooks

Use the test endpoint to send a sample webhook to your URL:
curl -X POST "https://api.getsmartalex.com/v1/webhooks/webhook_abc123/test" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "event_type": "call.completed"
  }'
This sends a sample event of the specified type to your webhook endpoint.