Skip to main content

Ticketing Webhooks

Webhooks enable your applications to receive real-time notifications when events occur in your ticketing and issue tracking systems. This eliminates the need for polling and ensures your systems stay synchronized with ticket updates, status changes, and comments across all integrated platforms.

Unizo normalizes webhook events from Jira, ServiceNow, Zendesk, GitHub Issues, and other ticketing providers into a consistent format. This means you write your webhook handler once and it works with all supported platforms.

Webhook Configuration

To set up webhooks for your integration, visit the Unizo Console Webhooks section for step-by-step configuration guide.

Supported Event Types

These are the event types currently supported by Unizo's Ticketing webhooks. The list keeps growing as we add support for more events across different platforms.

Event TypeDescriptionTrigger Conditions
ticket:createdA new ticket has been createdTicket creation via UI, API, email, or automation
ticket:updatedTicket information has been modifiedTitle, description, status, priority, or assignee changes
ticket:deletedA ticket has been deletedTicket deletion or permanent removal

Webhook Security

All webhooks from Unizo include security headers to verify authenticity:

Headers

HeaderDescription
x-unizo-event-typeThe type of event that triggered the webhook
x-unizo-signatureHMAC SHA-256 signature for request validation
x-unizo-timestampUnix timestamp when the event was sent
x-unizo-delivery-idUnique identifier for this webhook delivery

Signature Verification

Verify the authenticity of incoming webhooks using HMAC SHA-256:

const crypto = require('crypto');

function verifyWebhookSignature(payload, signature, secret) {
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');
  
  return crypto.timingSafeEqual(
    Buffer.from(signature, 'hex'),
    Buffer.from(expectedSignature, 'hex')
  );
}

Ticket Events

Ticket Created

ticket:created

Triggered when a new ticket is created in the ticketing system
POSThttps://api.yourapp.com/webhooks/unizo/ticketing
Best Practice: Use a dedicated webhook endpoint that can handle multiple event types. You have two architectural options:
• Single endpoint: https://api.yourapp.com/webhooks/unizo - Route all events to one handler
• Category-based endpoints: https://api.yourapp.com/webhooks/unizo/ticketing - Route by category (ticketing, ticketing, etc.) for microservices architecture
Headers
NameTypeRequiredDescription
x-unizo-event-typestringYesEvent type: ticket:created
x-unizo-signaturestringYesHMAC SHA-256 signature
Request Body Schema
PropertyTypeRequiredDescription
typestringYesEvent type identifier
versionstringYesWebhook payload version
contentTypestringYesBranch name/identifier
collectionstringYesCollection name
collection.idstringYesCollection ID
collection.namestringYesCollection Display Name
organizationstringYesOrganization name
organization.idstringYesOrganization ID
organization.namestringYesOrganization Display Name
ticketstringYesTicket Name
ticket.idstringYesTicket Id
ticket.statestringNoTicket key or number
ticket.summarystringYesTicket title or summary
ticket.createdDateTimestringNoTicket Creation Timestamp
integrationstringYesIntegration Name
integration.typestringNoIntegration type
integration.idstringYesIntegration id
integration.namestringYesIntegration Display Name
Example Payload
{
"type": "ticket:created",
"version": "1.0.0",
"contentType": "application/json",
"collection": {
"id": "169133028",
"name": "GH-DemoOrg411"
},
"organization": {
"id": "797087929",
"name": "DemoRepo1"
},
"ticket": {
"id": "78",
"state": "open",
"summary": "New issue",
"createdDateTime": "May 5, 2025 2:50 PM",
"createdBy": "Shruthi089"
},
"integration": {
"type": "TICKETING",
"id": "13348832-e545-4b33-aa32-51ad1b92afdf",
"name": "Gi_Secu_1746456420866"
}
}
Response
200 OKWebhook processed successfully
400 Bad RequestInvalid webhook payload
401 UnauthorizedInvalid or missing signature

Ticket Updated

ticket:updated

Triggered when ticket information is modified
POSThttps://api.yourapp.com/webhooks/unizo/scm
Best Practice: Use a dedicated webhook endpoint that can handle multiple event types. You have two architectural options:
• Single endpoint: https://api.yourapp.com/webhooks/unizo - Route all events to one handler
• Category-based endpoints: https://api.yourapp.com/webhooks/unizo/scm - Route by category (scm, ticketing, etc.) for microservices architecture
Headers
NameTypeRequiredDescription
x-unizo-event-typestringYesEvent type: ticket:created
x-unizo-signaturestringYesHMAC SHA-256 signature
Request Body Schema
PropertyTypeRequiredDescription
typestringYesEvent type identifier
versionstringYesWebhook payload version
contentTypestringYesBranch name/identifier
collectionstringYesCollection name
collection.idstringYesCollection ID
collection.namestringYesCollection Display Name
organizationstringYesOrganization name
organization.idstringYesOrganization ID
organization.namestringYesOrganization Display Name
ticketstringYesTicket Name
ticket.idstringYesTicket Id
ticket.statestringNoTicket key or number
ticket.summarystringYesTicket title or summary
ticket.createdDateTimestringNoTicket Creation Timestamp
ticket.changeLogstringYesTicket Change Log
ticket.changeLog.updatedDateTimestringYesTicket Change Log Updated Timestamp
ticket.changeLog.itemsstringYesTicket Change Log Items
integrationstringYesIntegration Name
integration.typestringNoIntegration type
integration.idstringYesIntegration id
integration.namestringYesIntegration Display Name
Example Payload
{
"type": "ticket:updated",
"version": "1.0.0",
"contentType": "application/json",
"collection": {
"id": "169133028",
"name": "GH-DemoOrg411"
},
"organization": {
"id": "797087929",
"name": "DemoRepo1"
},
"ticket": {
"id": "78",
"state": "open",
"summary": "New issue123",
"createdDateTime": "May 5, 2025 2:50 PM",
"changeLog": {
"updatedDateTime": "May 5, 2025 2:50 PM",
"items": [
{
"field": "body",
"fieldId": "body",
"from": ""
},
{
"field": "title",
"fieldId": "title",
"from": "New issue"
}
]
}
}
}
Response
200 OKWebhook processed successfully
400 Bad RequestInvalid webhook payload
401 UnauthorizedInvalid or missing signature

Ticket Deleted

ticket:deleted

Triggered when a ticket is deleted from the system
POSThttps://api.yourapp.com/webhooks/unizo/scm
Best Practice: Use a dedicated webhook endpoint that can handle multiple event types. You have two architectural options:
• Single endpoint: https://api.yourapp.com/webhooks/unizo - Route all events to one handler
• Category-based endpoints: https://api.yourapp.com/webhooks/unizo/scm - Route by category (scm, ticketing, etc.) for microservices architecture
Headers
NameTypeRequiredDescription
x-unizo-event-typestringYesEvent type: ticket:created
x-unizo-signaturestringYesHMAC SHA-256 signature
Request Body Schema
PropertyTypeRequiredDescription
typestringYesEvent type identifier
versionstringYesWebhook payload version
contentTypestringYesBranch name/identifier
collectionstringYesCollection name
collection.idstringYesCollection ID
collection.namestringYesCollection Display Name
organizationstringYesOrganization name
organization.idstringYesOrganization ID
organization.namestringYesOrganization Display Name
ticketstringYesTicket Name
ticket.idstringYesTicket Id
ticket.statestringNoTicket key or number
ticket.summarystringYesTicket title or summary
ticket.createdDateTimestringNoTicket Creation Timestamp
integrationstringYesIntegration Name
integration.typestringNoIntegration type
integration.idstringYesIntegration id
integration.namestringYesIntegration Display Name
Example Payload
{
"type": "ticket:deleted",
"version": "1.0.0",
"contentType": "application/json",
"collection": {
"id": "169133028",
"name": "GH-DemoOrg411"
},
"organization": {
"id": "797087929",
"name": "DemoRepo1"
},
"ticket": {
"id": "78",
"state": "open",
"summary": "New issue123",
"createdDateTime": "May 5, 2025 2:50 PM"
},
"integration": {
"type": "TICKETING",
"id": "13348832-e545-4b33-aa32-51ad1b92afdf",
"name": "Gi_Secu_1746456420866"
}
}
Response
200 OKWebhook processed successfully
400 Bad RequestInvalid webhook payload
401 UnauthorizedInvalid or missing signature

Webhook Delivery & Retries

Unizo implements automatic retry logic for failed webhook deliveries:

  1. Initial Delivery: Immediate
  2. First Retry: After 1 minute
  3. Second Retry: After 5 minutes
  4. Third Retry: After 15 minutes
  5. Final Retry: After 1 hour

Webhooks are considered failed if:

  • Your endpoint returns a non-2xx status code
  • Connection timeout (30 seconds)
  • SSL/TLS errors

Best Practices

1. Idempotency

Idempotent Webhook Handler

async function handleWebhook(request) {
const deliveryId = request.headers['x-unizo-delivery-id'];

// Check if already processed
if (await isProcessed(deliveryId)) {
  return { status: 200, message: 'Already processed' };
}

// Process webhook
await processWebhook(request.body);

// Mark as processed
await markProcessed(deliveryId);

return { status: 200 };
}

2. Async Processing

Asynchronous Processing

app.post('/webhooks/ticketing', (req, res) => {
// Validate signature
if (!verifySignature(req)) {
  return res.status(401).send('Invalid signature');
}

// Queue for processing
ticketQueue.add(req.body);

// Return immediately
res.status(200).send('OK');
});

3. Error Handling

Comprehensive Error Handling

async function processWebhook(payload) {
try {
  switch (payload.type) {
    case 'ticket:created':
      await handleTicketCreated(payload);
      break;
    case 'ticket:status_changed':
      await handleStatusChange(payload);
      break;
    case 'ticket:comment_added':
      await handleNewComment(payload);
      break;
    default:
      logger.warn(`Unknown webhook type: ${payload.type}`);
  }
} catch (error) {
  logger.error('Webhook processing failed', {
    error: error.message,
    payload,
    stack: error.stack
  });
  throw error;
}
}

Need Help?

For webhook-related support: