Webhooks

Receive real-time notifications when events happen in your Hostwares account. Configure HTTP callbacks for deployments, status changes, and more.

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

  1. Go to Dashboard → Settings → Webhooks
  2. Click Add Webhook Endpoint
  3. Enter your endpoint URL (must be HTTPS)
  4. Select which events to subscribe to
  5. 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

EventDescriptionWhen
deployment.startedA new deployment has startedBuild begins
deployment.completedDeployment succeededContainer is running
deployment.failedDeployment failedBuild or start error
site.status_changedSite status changedStart/stop/crash
site.createdNew site createdVia dashboard or API
site.deletedSite was deletedVia dashboard or API
domain.configuredDomain DNS verifiedAfter DNS propagation
ssl.issuedSSL certificate issuedLet's Encrypt issuance
database.createdDatabase provisionedAfter creation
service.deployedOne-click service deployedService is running
credits.lowAI credits running lowBelow 10% remaining
alert.triggeredMonitoring alert firedThreshold 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: 1716477000

Verify 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
      }]
    })
  });
}