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 createdtask.updated
- A task has been modifiedtask.completed
- A task has been marked as completetask.deleted
- A task has been removed
Project Events
project.created
- A new project has been createdproject.updated
- Project settings have been changedproject.archived
- A project has been archived
CI/CD Events
deployment.started
- A deployment has begundeployment.completed
- A deployment has finisheddeployment.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
- Navigate to Project Settings > Webhooks
- Click "Add Webhook"
- Enter your endpoint URL
- Select the events you want to receive
- 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
- Always verify signatures to prevent unauthorized requests
- Use HTTPS endpoints to encrypt data in transit
- Process asynchronously to avoid timeouts
- Implement idempotency using the event ID
- 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