Skip to main content

Overview

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

Setup

  1. Go to your Stover Dashboard
  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

EventDescription
contact.createdNew contact added
contact.updatedContact information modified
contact.deletedContact removed
deal.createdNew deal created
deal.updatedDeal information modified
deal.stage_changedDeal moved to different stage
deal.closed_wonDeal marked as won
deal.closed_lostDeal marked as lost
company.createdNew company added
company.updatedCompany information modified

Social Media Events

EventDescription
post.publishedPost successfully published
post.scheduledPost scheduled for later
post.failedPost failed to publish

Attribution Events

EventDescription
attribution.trackedNew attribution event recorded

Payload Format

{
  "id": "evt_abc123",
  "type": "contact.created",
  "created_at": "2024-01-15T10:30:00Z",
  "data": {
    "id": "...",
    "first_name": "Jane",
    "last_name": "Doe",
    "email": "[email protected]"
  }
}

Signature Verification

Every webhook includes a signature header for verification:
X-Stover-Signature: sha256=abc123...

Verify in Node.js

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:
AttemptDelay
1Immediate
21 minute
35 minutes
430 minutes
52 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