Webhook Event Structure

Webhook Event Structure

All webhook events follow a consistent structure, making it easy to parse and handle events in your application.

Event Payload

Every webhook request contains a JSON payload with the following structure:

{
  "event": "CONVERSATION_STARTED",
  "eventId": "abc123-def456-ghi789",
  "eventTimestamp": "2024-01-15T10:30:00.000Z",
  "data": {
    "recordId": "conv_abc123",
    "organizationId": "org_xyz789"
    // Additional event-specific data
  }
}

Payload Fields

FieldTypeDescription
eventstringThe event type (e.g., CONVERSATION_STARTED)
eventIdstringUnique identifier for this event
eventTimestampstringISO 8601 timestamp when the event occurred
dataobjectEvent-specific data payload
data.recordIdstringID of the primary resource (conversation, candidate, etc.)
data.organizationIdstringYour organization ID

HTTP Headers

Each webhook request includes the following headers:

HeaderDescription
Content-Typeapplication/json
x-signatureHMAC-SHA256 signature for verification (see Authentication)

Example: Handling a Webhook

import express from 'express';

const app = express();
app.use(express.json());

app.post('/webhooks/popp', (req, res) => {
  const { event, eventId, eventTimestamp, data } = req.body;

  console.log(`Received event: ${event}`);
  console.log(`Event ID: ${eventId}`);
  console.log(`Timestamp: ${eventTimestamp}`);
  console.log(`Record ID: ${data.recordId}`);
  console.log(`Organization ID: ${data.organizationId}`);

  // Handle the event based on type
  switch (event) {
    case 'CONVERSATION_STARTED':
      handleConversationStarted(data);
      break;
    case 'CONVERSATION_COMPLETED':
      handleConversationCompleted(data);
      break;
    // ... handle other events
  }

  // Always respond with 200 to acknowledge receipt
  res.status(200).send('OK');
});

Best Practices

  1. Respond quickly: Return a 200 response as soon as possible, then process the event asynchronously
  2. Handle duplicates: Events may be delivered more than once; use eventId for idempotency
  3. Verify signatures: Always verify the x-signature header before processing
  4. Log events: Store incoming events for debugging and audit purposes

Next Steps