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

# Outgoing Webhooks

> Receive events from Stover when things happen

## Overview

Outgoing webhooks send HTTP POST requests to your endpoint when events occur in your Stover account.

## Setup

1. Go to your [Stover Dashboard](https://dashboard.stover.app)
2. Navigate to **Settings** > **Webhooks** > **Outgoing**
3. Click **Create Webhook**
4. Enter your endpoint URL and select events
5. Copy the webhook secret for signature verification

## Available Events

### CRM Events

| Event                | Description                   |
| -------------------- | ----------------------------- |
| `contact.created`    | New contact added             |
| `contact.updated`    | Contact information modified  |
| `contact.deleted`    | Contact removed               |
| `deal.created`       | New deal created              |
| `deal.updated`       | Deal information modified     |
| `deal.stage_changed` | Deal moved to different stage |
| `deal.closed_won`    | Deal marked as won            |
| `deal.closed_lost`   | Deal marked as lost           |
| `company.created`    | New company added             |
| `company.updated`    | Company information modified  |

### Social Media Events

| Event            | Description                 |
| ---------------- | --------------------------- |
| `post.published` | Post successfully published |
| `post.scheduled` | Post scheduled for later    |
| `post.failed`    | Post failed to publish      |

### Attribution Events

| Event                 | Description                    |
| --------------------- | ------------------------------ |
| `attribution.tracked` | New attribution event recorded |

## Payload Format

```json theme={null}
{
  "id": "evt_abc123",
  "type": "contact.created",
  "created_at": "2024-01-15T10:30:00Z",
  "data": {
    "id": "...",
    "first_name": "Jane",
    "last_name": "Doe",
    "email": "jane@example.com"
  }
}
```

## Signature Verification

Every webhook includes a signature header for verification:

```
X-Stover-Signature: sha256=abc123...
```

### Verify in Node.js

```javascript theme={null}
const crypto = require('crypto');

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

  return `sha256=${expected}` === signature;
}

// In your webhook handler
app.post('/webhook', (req, res) => {
  const signature = req.headers['x-stover-signature'];
  const isValid = verifySignature(
    JSON.stringify(req.body),
    signature,
    process.env.WEBHOOK_SECRET
  );

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

  // Process the webhook
  res.status(200).send('OK');
});
```

## Retry Policy

Failed deliveries are retried automatically:

| Attempt | Delay      |
| ------- | ---------- |
| 1       | Immediate  |
| 2       | 1 minute   |
| 3       | 5 minutes  |
| 4       | 30 minutes |
| 5       | 2 hours    |

After 5 failed attempts, the delivery is marked as failed.

## Best Practices

* **Respond quickly** - Return 200 within 30 seconds
* **Process async** - Queue heavy processing for later
* **Verify signatures** - Always validate webhook authenticity
* **Handle duplicates** - Use `id` field for idempotency
