Webhooks

Not yet shipped

Webhooks are a planned capability — this page describes the intended design, but there is no webhook configuration surface or delivery pipeline on the platform today (verified 2026-07-12). For reacting to platform activity now, use the audit log in the console or the Comms API's messaging primitives.

Webhooks let your systems react to events on Kapable in real time. Instead of polling the API, Kapable sends an HTTP POST to your endpoint whenever something happens.

Event Types

EventFires when
app.deployedA deployment completes successfully
app.failedA deployment fails
app.pausedAn app is paused
app.resumedAn app is resumed
app.deletedAn app is deleted
member.invitedA new member is invited to the org
member.joinedAn invited member accepts and joins
member.deactivatedA member is deactivated
billing.subscription_changedSubscription plan changes (upgrade, downgrade, cancel)
billing.payment_failedA payment attempt fails
auth.login_anomalyAn unusual login is detected (new device, new location)

Payload Format

Every webhook POST sends a JSON body:

{
  "id": "evt_01J5K...",
  "type": "app.deployed",
  "created_at": "2026-05-21T10:30:00Z",
  "org_id": "d3f1a2b4-...",
  "data": {
    "app_id": "a1b2c3d4-...",
    "app_name": "my-app",
    "version": "v1.4.2",
    "deployed_by": "alice@example.com"
  }
}

The data object varies by event type. See the API Reference for the full schema of each event.

Setting Up an Endpoint

Your webhook endpoint must:

  1. Accept POST requests with a JSON body
  2. Return a 2xx status within 10 seconds to acknowledge receipt
  3. Be publicly reachable via HTTPS (plain HTTP is rejected)

Example endpoint in Node.js:

app.post('/webhooks/kapable', (req, res) => {
  const event = req.body;
  console.log(`Received ${event.type}`, event.data);

  // Process the event asynchronously
  processEvent(event).catch(console.error);

  // Acknowledge immediately
  res.status(200).json({ received: true });
});

Verifying Signatures

Every webhook includes an X-Kapable-Signature header containing an HMAC-SHA256 signature of the request body, signed with your webhook secret.

Always verify the signature before processing:

import hmac
import hashlib

def verify_signature(payload_body, signature_header, secret):
    expected = hmac.new(
        secret.encode('utf-8'),
        payload_body,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(f"sha256={expected}", signature_header)
const crypto = require('crypto');

function verifySignature(body, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(body, 'utf8')
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(`sha256=${expected}`),
    Buffer.from(signature)
  );
}

Retry Policy

If your endpoint doesn't return a 2xx response, Kapable retries with exponential backoff:

AttemptDelay
1st retry1 minute
2nd retry10 minutes
3rd retry1 hour

After 3 failed retries, the event is marked as failed. You can view failed deliveries in the Send Audit page.

Testing

During development, use a tunnel or request-inspection tool:

  1. ngrok — expose your local server: ngrok http 3000
  2. webhook.site — inspect payloads without any code
  3. Kapable test events — use the "Send Test" button in webhook configuration to fire a sample event

Best Practices

Console Configuration

Coming soon

Webhook configuration is coming soon to the console. In the meantime, contact support@kapable.ai for early access to the webhook API.

Next Steps

Next

Getting Started · Authentication