> ## Documentation Index
> Fetch the complete documentation index at: https://boltcall.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhooks

> Send real-time HTTP POST requests to any URL when events happen in Boltcall — new leads, missed calls, bookings, and more.

Webhooks let you push Boltcall event data to external systems the moment something happens. Every time a trigger event fires, Boltcall sends an HTTP POST request with a JSON payload to the URL you specify.

Use webhooks to connect Boltcall to Zapier, Make.com, your own server, or any system that accepts HTTP requests.

To manage webhooks, go to **Dashboard → Integrations → Webhooks**.

## Trigger events

| Event              | Value                | When it fires                                     |
| ------------------ | -------------------- | ------------------------------------------------- |
| New lead           | `new_lead`           | A new lead is captured by your AI receptionist    |
| Missed call        | `missed_call`        | A call comes in but is not answered               |
| Appointment booked | `appointment_booked` | An appointment is confirmed                       |
| Call completed     | `call_completed`     | A call ends                                       |
| Review received    | `review_received`    | A new review comes in via Google Business Profile |

## Create a webhook

<Steps>
  <Step title="Open the Webhooks tab">
    Go to **Dashboard → Integrations → Webhooks** and click **Create Webhook**.
  </Step>

  <Step title="Name your webhook">
    Enter an optional name to identify this webhook (e.g. "Zapier Lead Notification"). This is for your reference only.
  </Step>

  <Step title="Choose a trigger event">
    Select the event that should fire this webhook from the dropdown. Each webhook is tied to one event.
  </Step>

  <Step title="Enter your endpoint URL">
    Paste the URL that should receive the POST request (e.g. your Zapier Catch Hook URL or your own server endpoint).
  </Step>

  <Step title="Save">
    Click **Create Webhook**. The webhook is active immediately.
  </Step>
</Steps>

<Tip>
  Before saving, click **Preview payload** to see the exact JSON your endpoint will receive for the selected trigger event.
</Tip>

## Example payloads

<CodeGroup>
  ```json new_lead theme={null}
  {
    "event": "new_lead",
    "timestamp": "2025-03-20T10:00:00Z",
    "data": {
      "id": "lead_001",
      "name": "Jane Smith",
      "phone": "+1555123456",
      "email": "jane@example.com",
      "source": "missed_call",
      "agent_id": "agent_abc123"
    }
  }
  ```

  ```json call_completed theme={null}
  {
    "event": "call_completed",
    "timestamp": "2025-03-20T10:15:00Z",
    "data": {
      "id": "call_002",
      "caller_phone": "+1555123456",
      "duration_seconds": 142,
      "outcome": "lead_captured",
      "agent_id": "agent_abc123",
      "recording_url": "https://storage.boltcall.org/recordings/call_002.mp3"
    }
  }
  ```

  ```json appointment_booked theme={null}
  {
    "event": "appointment_booked",
    "timestamp": "2025-03-20T10:20:00Z",
    "data": {
      "id": "appt_003",
      "lead_id": "lead_001",
      "name": "Jane Smith",
      "phone": "+1555123456",
      "scheduled_at": "2025-03-22T14:00:00Z",
      "duration_minutes": 30,
      "agent_id": "agent_abc123"
    }
  }
  ```
</CodeGroup>

## Webhook security

Each webhook has a **signing secret** generated automatically when you create it. Boltcall includes an HMAC-SHA256 signature in the `X-Boltcall-Signature` header of every request.

You should verify this signature on your server to confirm the request genuinely came from Boltcall.

<CodeGroup>
  ```javascript Node.js theme={null}
  const crypto = require('crypto');

  function verifyWebhookSignature(payload, signature, secret) {
    const expected = crypto
      .createHmac('sha256', secret)
      .update(payload)
      .digest('hex');

    return crypto.timingSafeEqual(
      Buffer.from(signature),
      Buffer.from(expected)
    );
  }

  // Express example
  app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
    const signature = req.headers['x-boltcall-signature'];
    const isValid = verifyWebhookSignature(req.body, signature, process.env.WEBHOOK_SECRET);

    if (!isValid) {
      return res.status(401).send('Invalid signature');
    }

    const event = JSON.parse(req.body);
    console.log('Received event:', event.event);

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

  ```python Python theme={null}
  import hmac
  import hashlib

  def verify_webhook_signature(payload: bytes, signature: str, secret: str) -> bool:
      expected = hmac.new(
          secret.encode('utf-8'),
          payload,
          hashlib.sha256
      ).hexdigest()
      return hmac.compare_digest(signature, expected)

  # Flask example
  from flask import Flask, request, abort

  app = Flask(__name__)

  @app.route('/webhook', methods=['POST'])
  def webhook():
      signature = request.headers.get('X-Boltcall-Signature')
      is_valid = verify_webhook_signature(
          request.data,
          signature,
          os.environ['WEBHOOK_SECRET']
      )

      if not is_valid:
          abort(401)

      event = request.get_json()
      print('Received event:', event['event'])
      return 'OK', 200
  ```
</CodeGroup>

To find your signing secret, go to **Dashboard → Integrations → Webhooks**, expand a webhook row, and click the copy icon next to **Signing Secret**.

<Warning>
  Treat your signing secret like a password. Do not expose it in client-side code or commit it to version control.
</Warning>

## Testing a webhook

Each webhook has a **play button** in its row. Clicking it sends a sample payload to your endpoint immediately, without waiting for a real event.

After a test fires, expand the webhook row to see the result in the **Event Log** — including the HTTP status code, response body, and response time in milliseconds.

<Info>
  The event log shows the last 100 delivery attempts per webhook, including both test events and live events.
</Info>

## Pausing and deleting

To temporarily stop a webhook from firing, click the toggle icon in its row to pause it. Click again to reactivate.

To permanently remove a webhook, click the trash icon in its row. Deletion is immediate and cannot be undone.

## Retries

Boltcall does not automatically retry failed webhook deliveries. If your endpoint returns a non-2xx status code, the delivery is logged as failed in the event log. Use the test/replay feature to manually re-send a payload to your endpoint after resolving the issue.
