Overview
Webhooks allow you to receive HTTP POST requests to your server whenever specific events occur in your Hostwares account. This enables real-time integrations with Slack, Discord, PagerDuty, custom dashboards, or any system that can receive HTTP requests.
Setting Up Webhooks
Via Dashboard
- Go to Dashboard → Settings → Webhooks
- Click Add Webhook Endpoint
- Enter your endpoint URL (must be HTTPS)
- Select which events to subscribe to
- Save — we'll send a test ping to verify connectivity
Via API
POST /api/webhooks
{
"url": "https://your-app.com/webhooks/hostwares",
"events": ["deployment.started", "deployment.completed", "deployment.failed", "site.status_changed"],
"secret": "your_webhook_signing_secret"
}Event Types
| Event | Description | When |
|---|---|---|
deployment.started | A new deployment has started | Build begins |
deployment.completed | Deployment succeeded | Container is running |
deployment.failed | Deployment failed | Build or start error |
site.status_changed | Site status changed | Start/stop/crash |
site.created | New site created | Via dashboard or API |
site.deleted | Site was deleted | Via dashboard or API |
domain.configured | Domain DNS verified | After DNS propagation |
ssl.issued | SSL certificate issued | Let's Encrypt issuance |
database.created | Database provisioned | After creation |
service.deployed | One-click service deployed | Service is running |
credits.low | AI credits running low | Below 10% remaining |
alert.triggered | Monitoring alert fired | Threshold exceeded |
Payload Format
Every webhook delivery includes these standard fields:
{
"id": "evt_abc123def456",
"event": "deployment.completed",
"timestamp": "2026-05-23T14:30:00.000Z",
"account_id": "user_xyz",
"data": {
"site_id": "cm1234abcd",
"site_name": "my-nextjs-app",
"status": "RUNNING",
"deployment_id": "dep_789",
"duration_seconds": 12.5,
"commit_message": "feat: add user profiles",
"commit_sha": "abc1234",
"domain": "app.example.com"
}
}Verifying Webhook Signatures
Every webhook request includes a signature header for verification:
X-Hostwares-Signature: sha256=abc123...
X-Hostwares-Timestamp: 1716477000Verify the signature to ensure the request came from Hostwares:
import crypto from 'crypto';
function verifyWebhook(payload: string, signature: string, secret: string) {
const expected = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(`sha256=${expected}`)
);
}Retry Policy
- Webhooks are retried up to 5 times on failure
- Retry intervals: 10s, 60s, 5min, 30min, 2 hours
- A response with HTTP status 2xx is considered successful
- After 5 failures, the webhook endpoint is disabled and you'll receive an email notification
- View delivery logs in Dashboard → Settings → Webhooks → Deliveries
Integration Examples
Express.js Handler
app.post('/webhooks/hostwares', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.headers['x-hostwares-signature'];
if (!verifyWebhook(req.body.toString(), signature, WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
const event = JSON.parse(req.body);
switch (event.event) {
case 'deployment.completed':
notifySlack(`Deployed ${event.data.site_name} successfully!`);
break;
case 'deployment.failed':
notifyPagerDuty(`Deployment failed for ${event.data.site_name}`);
break;
}
res.status(200).send('OK');
});Discord Notification
// Send deployment notifications to Discord
async function notifyDiscord(event) {
await fetch(DISCORD_WEBHOOK_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
embeds: [{
title: event.event === 'deployment.completed' ? 'Deployment Successful' : 'Deployment Failed',
color: event.event === 'deployment.completed' ? 0x22c55e : 0xef4444,
fields: [
{ name: 'Site', value: event.data.site_name, inline: true },
{ name: 'Duration', value: `${event.data.duration_seconds}s`, inline: true },
{ name: 'Commit', value: event.data.commit_message || 'N/A' },
],
timestamp: event.timestamp
}]
})
});
}