Skip to main content

Webhooks API

Configure webhooks to receive real-time notifications about your Buildable projects.

Overview

Buildable webhooks allow you to receive HTTP POST requests whenever specific events occur in your projects. This enables real-time integration with your existing tools and workflows.

Webhook Events

Task Events

  • task.created - A new task has been created
  • task.updated - A task has been modified
  • task.completed - A task has been marked as complete
  • task.deleted - A task has been removed

Project Events

  • project.created - A new project has been created
  • project.updated - Project settings have been changed
  • project.archived - A project has been archived

CI/CD Events

  • deployment.started - A deployment has begun
  • deployment.completed - A deployment has finished
  • deployment.failed - A deployment has failed

Setup

1. Create a Webhook Endpoint

Your webhook endpoint should:

  • Accept HTTP POST requests
  • Return a 200 status code
  • Process the payload asynchronously

Example Express.js endpoint:

app.post('/webhooks/buildable', (req, res) => {
const event = req.body;

// Verify webhook signature (recommended)
if (!verifySignature(req)) {
return res.status(401).send('Unauthorized');
}

// Process the event
processWebhookEvent(event);

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

2. Configure in Buildable

  1. Navigate to Project Settings > Webhooks
  2. Click "Add Webhook"
  3. Enter your endpoint URL
  4. Select the events you want to receive
  5. Save the configuration

3. Verify Setup

Buildable will send a test event to verify your endpoint is working correctly.

Payload Structure

All webhook payloads follow this structure:

{
"event": "task.completed",
"timestamp": "2024-01-15T10:30:00Z",
"project_id": "proj_123",
"data": {
"task": {
"id": "task_456",
"title": "Implement user authentication",
"status": "completed",
"assigned_to": "user_789",
"completed_at": "2024-01-15T10:30:00Z"
}
}
}

Event Details

Task Completed Example

{
"event": "task.completed",
"timestamp": "2024-01-15T10:30:00Z",
"project_id": "proj_123",
"data": {
"task": {
"id": "task_456",
"title": "Implement user authentication",
"description": "Add JWT-based authentication system",
"status": "completed",
"priority": "high",
"assigned_to": "user_789",
"created_at": "2024-01-14T09:00:00Z",
"completed_at": "2024-01-15T10:30:00Z",
"tags": ["backend", "security"],
"estimated_hours": 8,
"actual_hours": 6
}
}
}

Deployment Completed Example

{
"event": "deployment.completed",
"timestamp": "2024-01-15T10:35:00Z",
"project_id": "proj_123",
"data": {
"deployment": {
"id": "deploy_789",
"environment": "production",
"status": "success",
"commit_sha": "abc123def456",
"preview_url": "https://preview.example.com",
"started_at": "2024-01-15T10:30:00Z",
"completed_at": "2024-01-15T10:35:00Z"
}
}
}

Security

Webhook Signatures

Buildable signs all webhook payloads using HMAC-SHA256. Verify the signature to ensure the webhook is from Buildable:

const crypto = require('crypto');

function verifySignature(req) {
const signature = req.headers['x-buildable-signature'];
const payload = JSON.stringify(req.body);
const secret = process.env.BUILDABLE_WEBHOOK_SECRET;

const expectedSignature = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');

return signature === `sha256=${expectedSignature}`;
}

Best Practices

  1. Always verify signatures to prevent unauthorized requests
  2. Use HTTPS endpoints to encrypt data in transit
  3. Process asynchronously to avoid timeouts
  4. Implement idempotency using the event ID
  5. Log webhook events for debugging and monitoring

Retry Logic

Buildable will retry failed webhook deliveries:

  • Retry up to 3 times
  • Exponential backoff: 1s, 4s, 16s
  • Consider failed after 404, 410, or 3 consecutive failures

Testing

ngrok for Local Testing

Use ngrok to test webhooks locally:

# Start your local server
node server.js

# In another terminal, expose it with ngrok
ngrok http 3000

# Use the ngrok URL in Buildable webhook settings

Webhook Testing Tools

  • Use webhook.site for quick testing
  • Postman can simulate webhook events
  • curl for manual testing

Common Integrations

Slack Notifications

async function sendSlackNotification(event) {
if (event.event === 'task.completed') {
const message = {
text: `✅ Task completed: ${event.data.task.title}`,
channel: '#development'
};

await fetch(process.env.SLACK_WEBHOOK_URL, {
method: 'POST',
body: JSON.stringify(message)
});
}
}

Jira Integration

async function updateJiraTicket(event) {
if (event.event === 'task.completed') {
const jiraUpdate = {
transition: { id: '31' }, // Transition to "Done"
fields: {
resolution: { name: 'Done' }
}
};

await fetch(`${JIRA_URL}/rest/api/2/issue/${ticketId}/transitions`, {
method: 'POST',
headers: {
'Authorization': `Basic ${jiraAuth}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(jiraUpdate)
});
}
}

Troubleshooting

Common Issues

Webhook Not Receiving Events

  • Check the endpoint URL is correct and accessible
  • Verify the webhook is enabled in project settings
  • Check your server logs for incoming requests

Events Being Marked as Failed

  • Ensure your endpoint returns a 200 status code
  • Check the response time (should be under 30 seconds)
  • Verify the endpoint can handle POST requests

Signature Verification Failing

  • Check the webhook secret is correctly configured
  • Ensure you're using the raw request body for verification
  • Verify the HMAC calculation matches our implementation

Rate Limits

  • Maximum 100 webhook deliveries per minute per project
  • Maximum 10 simultaneous webhook deliveries
  • Payloads limited to 1MB

Getting Help

  • Review webhook delivery logs in the Buildable dashboard
  • Check our API documentation for more details
  • Contact support for webhook-specific issues