Skip to main content

Webhook Events Reference

This page documents all webhook events, their triggers, and payload structures.

Event Flow​

Common Payload Structure​

All webhook payloads share a common structure:

Base payload structure
{
"event": "EVENT_TYPE",
"timestamp": "2024-01-15T10:30:00Z",
"webhookId": "wh_abc123",
"departmentId": "dept_xyz789",
"data": { /* Event-specific data */ }
}

Common Fields​

FieldTypeDescription
eventstringThe event type that triggered this webhook
timestampstringISO 8601 timestamp of when the event occurred
webhookIdstringUnique identifier for the webhook configuration
departmentIdstringThe department where the event occurred
dataobjectEvent-specific payload data

SURVEY_COMPLETED​

Triggered when a respondent submits a completed survey response.

When It Fires​

  • Respondent clicks submit on the final page
  • All required questions have been answered
  • Survey response is successfully saved
📦 Full Payload Example (click to expand)
SURVEY_COMPLETED payload
{
"event": "SURVEY_COMPLETED",
"timestamp": "2024-01-15T10:30:00Z",
"webhookId": "wh_abc123",
"departmentId": "dept_xyz789",
"data": {
"surveyId": "survey_123",
"surveyName": "Customer Satisfaction Survey",
"responseId": "resp_456",
"collectorId": "col_789",
"collectorType": "email",
"completedAt": "2024-01-15T10:30:00Z",
"contact": {
"id": "contact_001",
"email": "customer@example.com",
"phone": "+1234567890",
"customFields": {
"firstName": "John",
"lastName": "Doe"
}
},
"responses": [
{
"questionId": "q1",
"questionTitle": "How satisfied are you?",
"questionType": "rating",
"answer": 9
},
{
"questionId": "q2",
"questionTitle": "Would you recommend us?",
"questionType": "boolean",
"answer": true
},
{
"questionId": "q3",
"questionTitle": "Additional comments",
"questionType": "text",
"answer": "Great service!"
}
],
"metadata": {
"ipAddress": "192.168.1.1",
"userAgent": "Mozilla/5.0...",
"duration": 245,
"language": "en"
}
}
}

Data Fields​

FieldTypeDescription
surveyIdstringUnique survey identifier
surveyNamestringName of the survey
responseIdstringUnique response identifier
collectorIdstringCollector that gathered this response
collectorTypestringType: email, sms, whatsapp, web, widget
completedAtstringISO 8601 completion timestamp
contactobjectRespondent contact information (if available)
responsesarrayArray of question-answer pairs
metadataobjectAdditional response metadata

Handler Examples​

server.js
const express = require('express');
const app = express();

app.post('/webhooks/pollarix', express.json(), (req, res) => {
const { event, data } = req.body;

if (event === 'SURVEY_COMPLETED') {
// Extract NPS score
const npsQuestion = data.responses.find(r => r.questionType === 'rating');
const score = npsQuestion?.answer;

console.log(`New response! Score: ${score}, Email: ${data.contact.email}`);

// Sync to your CRM
syncToCRM(data.contact.email, score);
}

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

app.listen(3000);

SURVEY_STATUS_CHANGED​

Triggered when a survey's status is modified.

When It Fires​

  • Survey is activated (draft → active)
  • Survey is deactivated (active → inactive)
  • Survey is closed
  • Survey is reopened
📦 Full Payload Example
SURVEY_STATUS_CHANGED payload
{
"event": "SURVEY_STATUS_CHANGED",
"timestamp": "2024-01-15T14:00:00Z",
"webhookId": "wh_abc123",
"departmentId": "dept_xyz789",
"data": {
"surveyId": "survey_123",
"surveyName": "Customer Satisfaction Survey",
"previousStatus": "draft",
"newStatus": "active",
"changedBy": {
"userId": "user_456",
"email": "admin@company.com"
},
"changedAt": "2024-01-15T14:00:00Z"
}
}

Status Values​

StatusDescription
draftSurvey is being edited, not accepting responses
activeSurvey is live and accepting responses
inactiveSurvey is paused, not accepting responses
closedSurvey is permanently closed

Handler Examples​

Notify on status change
if (event === 'SURVEY_STATUS_CHANGED' && data.newStatus === 'active') {
await slack.postMessage({
channel: '#surveys',
text: `Survey "${data.surveyName}" is now live!`
});
}

// Archive data when survey closes
if (data.newStatus === 'closed') {
await archiveSurveyData(data.surveyId);
}

COUPON_REDEEMED​

Triggered when a coupon is distributed to a survey respondent.

When It Fires​

  • Automation workflow distributes a coupon
  • Coupon is successfully assigned to a contact
  • Coupon delivery method is executed (email or SMS; WhatsApp requires explicit enablement and is not generally available)
📦 Full Payload Example
COUPON_REDEEMED payload
{
"event": "COUPON_REDEEMED",
"timestamp": "2024-01-15T10:35:00Z",
"webhookId": "wh_abc123",
"departmentId": "dept_xyz789",
"data": {
"couponId": "coupon_123",
"couponCode": "SAVE20NOW",
"couponGroupId": "group_456",
"couponGroupName": "January Promotions",
"responseId": "resp_789",
"surveyId": "survey_123",
"contact": {
"id": "contact_001",
"email": "customer@example.com",
"phone": "+1234567890"
},
"deliveryMethod": "email",
"deliveredAt": "2024-01-15T10:35:00Z",
"expiresAt": "2024-02-15T23:59:59Z"
}
}

Data Fields​

FieldTypeDescription
couponIdstringUnique coupon identifier
couponCodestringThe actual coupon code
couponGroupIdstringCoupon group identifier
couponGroupNamestringName of the coupon group
responseIdstringSurvey response that triggered the coupon
surveyIdstringAssociated survey
contactobjectRecipient contact information
deliveryMethodstringHow coupon was sent: email, sms, whatsapp
deliveredAtstringISO 8601 delivery timestamp
expiresAtstringCoupon expiration date

Response Handling​

Important

Always respond quickly (< 5 seconds) to webhook requests. Process data asynchronously.

Response CodeMeaningPollarix Action
2xx✅ SuccessDelivery confirmed
4xx❌ Client errorWill not retry
5xx⚠️ Server errorMay retry
Timeout⏱️ No responseMay retry

Idempotent Handler Pattern​

Idempotent webhook handler
const processedEvents = new Set();

app.post('/webhooks/pollarix', (req, res) => {
// Create unique key to prevent duplicate processing
const eventKey = `${req.body.webhookId}-${req.body.timestamp}`;

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

processedEvents.add(eventKey);

// Process webhook async
processWebhookAsync(req.body);

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

Next Steps​

Was this page helpful?