Verk

Webhook Configuration

Setting up webhooks, event types, payload examples

Webhooks

Configure webhooks to receive real-time notifications when events occur in Verk. Build event-driven integrations and automate workflows.

Overview

Webhooks send HTTP POST requests to your server when specific events happen:

  • Task created, updated, or completed
  • Project changes
  • Member actions
  • Comment activity
  • File uploads

Use webhooks to:

  • Sync data with external systems
  • Trigger automation workflows
  • Send notifications to other tools
  • Update dashboards in real-time

Prerequisites

Requirements:

  • Public HTTPS endpoint to receive webhooks
  • API key with webhooks:write permission
  • Ability to verify webhook signatures

Plan availability:

  • Free: 2 webhooks
  • Pro: 50 webhooks
  • Enterprise: Unlimited

Creating Webhooks

Via API

POST /webhooks

curl -X POST "https://api.verk.com/v1/webhooks" \
 -H "Authorization: Bearer YOUR_API_KEY" \
 -H "Content-Type: application/json" \
 -d '{
 "url": "https://your-server.com/webhook",
 "events": ["task.created", "task.updated"],
 "secret": "your_webhook_secret_12345"
 }'

Via Dashboard

  1. Navigate to Settings → Integrations → Webhooks
  2. Click "+ Create Webhook"
  3. Configure:
  • URL: Your endpoint URL (must be HTTPS)
  • Events: Select which events to receive
  • Secret: Generate or provide signing secret
  • Description: Optional notes
  1. Click "Create"
  2. Test webhook with sample payload

Event Types

Task Events

task.created Triggered when a new task is created.

{
  "event": "task.created",
  "timestamp": "2024-01-15T10:30:00Z",
  "data": {
    "id": "task_123",
    "title": "Implement login feature",
    "status": "todo",
    "priority": "high",
    "projectId": "proj_456",
    "creatorId": "user_789",
    "createdAt": "2024-01-15T10:30:00Z"
  }
}

task.updated Triggered when task is modified.

task.deleted Triggered when task is deleted.

task.completed Triggered when task status changes to "done".

Project Events

project.created New project created.

project.updated Project details modified.

project.deleted Project deleted.

Member Events

member.added User joined organization.

member.removed User left or was removed.

member.role_changed User role updated.

Comment Events

comment.created New comment on task.

comment.updated Comment edited.

comment.deleted Comment removed.

File Events

file.uploaded New file uploaded.

file.deleted File deleted.

Webhook Payload

All webhooks follow this structure:

{
 "event": "event.type",
 "timestamp": "ISO8601 timestamp",
 "webhookId": "webhook_123",
 "deliveryId": "delivery_456",
 "data": {
 ...event-specific data...
 },
 "organization": {
 "id": "org_789",
 "name": "Acme Inc"
 }
}

Verifying Webhooks

Signature Verification

Verk signs all webhooks with your secret:

Header:

X-Verk-Signature: sha256=abc123...

Verify signature (Node.js):

const crypto = require('crypto')

function verifyWebhook(payload, signature, secret) {
  const expectedSignature =
    'sha256=' +
    crypto.createHmac('sha256', secret).update(payload).digest('hex')

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

// Express.js example
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const signature = req.headers['x-verk-signature']
  const payload = req.body.toString()

  if (!verifyWebhook(payload, signature, process.env.WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature')
  }

  // Process webhook...
  res.status(200).send('OK')
})

Verify signature (Python):

import hmac
import hashlib

def verify_webhook(payload, signature, secret):
 expected = 'sha256=' + hmac.new(
  secret.encode(),
  payload.encode(),
  hashlib.sha256
 ).hexdigest()

 return hmac.compare_digest(signature, expected)

Handling Webhooks

Responding to Webhooks

Requirements:

  • Return 200 OK within 5 seconds
  • Process asynchronously if needed
  • Don't perform long-running operations

Example handler:

app.post('/webhook', async (req, res) => {
  // Verify signature first
  if (!verifyWebhook(req.body, req.headers['x-verk-signature'])) {
    return res.status(401).send('Unauthorized')
  }

  // Acknowledge receipt immediately
  res.status(200).send('OK')

  // Process asynchronously
  processWebhookAsync(req.body)
})

async function processWebhookAsync(payload) {
  const { event, data } = payload

  switch (event) {
    case 'task.created':
      await handleTaskCreated(data)
      break
    case 'task.updated':
      await handleTaskUpdated(data)
      break
    // ... other events
  }
}

Retry Logic

Verk retry policy:

  • Initial attempt: Immediate
  • Retry 1: After 1 minute
  • Retry 2: After 5 minutes
  • Retry 3: After 15 minutes
  • Retry 4: After 1 hour
  • Retry 5: After 3 hours
  • Retry 6: After 6 hours

Webhook disabled after:

  • 6 failed attempts
  • Manual re-enable required
  • Check webhook logs for errors

Idempotency

Handle duplicate webhooks gracefully:

const processedDeliveries = new Set()

async function handleWebhook(payload) {
  const { deliveryId } = payload

  // Check if already processed
  if (processedDeliveries.has(deliveryId)) {
    console.log('Duplicate delivery, skipping')
    return
  }

  // Process webhook
  await processEvent(payload)

  // Mark as processed
  processedDeliveries.add(deliveryId)
}

Webhook Management

List Webhooks

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

Update Webhook

curl -X PATCH "https://api.verk.com/v1/webhooks/webhook_123" \
 -H "Authorization: Bearer YOUR_API_KEY" \
 -H "Content-Type: application/json" \
 -d '{
 "events": ["task.created", "task.completed"]
 }'

Delete Webhook

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

Webhook Logs

View delivery history:

  1. Settings → Integrations → Webhooks
  2. Click webhook
  3. View "Delivery Log"

See:

  • Timestamp
  • Event type
  • Response status
  • Response time
  • Retry attempts

Use Cases

Slack Notifications

Send task updates to Slack:

async function handleTaskCreated(task) {
  await fetch(process.env.SLACK_WEBHOOK_URL, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      text: `New task created: ${task.title}`,
      attachments: [
        {
          color: task.priority === 'high' ? 'danger' : 'good',
          fields: [
            { title: 'Project', value: task.projectName },
            { title: 'Assignee', value: task.assigneeName },
            { title: 'Due Date', value: task.dueDate },
          ],
        },
      ],
    }),
  })
}

Database Sync

Sync Verk tasks to your database:

async function syncTaskToDatabase(task) {
  await db.tasks.upsert({
    where: { verkId: task.id },
    update: {
      title: task.title,
      status: task.status,
      updatedAt: task.updatedAt,
    },
    create: {
      verkId: task.id,
      title: task.title,
      status: task.status,
      createdAt: task.createdAt,
    },
  })
}

Email Notifications

Send custom email notifications:

async function handleTaskAssigned(task) {
  const assignee = await getUser(task.assigneeId)

  await sendEmail({
    to: assignee.email,
    subject: `New task assigned: ${task.title}`,
    body: `You've been assigned a new ${task.priority} priority task.`,
  })
}

Troubleshooting

Webhook Not Receiving Events

Check:

  • Webhook is active (not disabled)
  • Events are selected
  • URL is publicly accessible
  • Firewall allows Verk IPs
  • SSL certificate is valid

Test: Click "Send Test" in webhook settings to verify endpoint.

Webhook Disabled

Causes:

  • 6 consecutive failures
  • Endpoint returning errors
  • Timeout (>5 seconds)

Fix:

  1. Review delivery logs
  2. Fix endpoint issues
  3. Re-enable webhook
  4. Monitor for success

Signature Verification Fails

Check:

  • Using correct secret
  • Comparing raw request body
  • Using timing-safe comparison
  • Secret hasn't been rotated

Best Practices

Verify Signatures Always verify webhook signatures to ensure authenticity.

Respond Quickly Return 200 OK within 5 seconds. Process asynchronously if needed.

Handle Duplicates Use deliveryId to implement idempotency.

Monitor Failures Set up alerts for webhook failures.

Use HTTPS Always use HTTPS endpoints for security.

Rotate Secrets Change webhook secrets periodically (quarterly).

Log Everything Keep detailed logs of all webhook deliveries for debugging.

Graceful Degradation Have fallback mechanisms if webhooks fail.


Need webhook help? Contact developer support for assistance.