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
| Field | Type | Description |
|---|---|---|
event | string | The event type (e.g., CONVERSATION_STARTED) |
eventId | string | Unique identifier for this event |
eventTimestamp | string | ISO 8601 timestamp when the event occurred |
data | object | Event-specific data payload |
data.recordId | string | ID of the primary resource (conversation, candidate, etc.) |
data.organizationId | string | Your organization ID |
HTTP Headers
Each webhook request includes the following headers:
| Header | Description |
|---|---|
Content-Type | application/json |
x-signature | HMAC-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
- Respond quickly: Return a 200 response as soon as possible, then process the event asynchronously
- Handle duplicates: Events may be delivered more than once; use
eventIdfor idempotency - Verify signatures: Always verify the
x-signatureheader before processing - Log events: Store incoming events for debugging and audit purposes
Next Steps
- Conversation Events - Events for conversation lifecycle
- Analysis Events - Events for candidate analysis
- Scheduling Events - Events for calendar and meetings
Updated about 14 hours ago