Webhooks

Receive real-time notifications when events occur in Retake. Use webhooks to trigger your own logic, update analytics, or sync with other systems.

Delivery: All webhooks are delivered with automatic retry (3 attempts, exponential backoff) for reliability.

Setup

  1. 1

    Go to Dashboard → Settings → API Keys

    Find the webhook configuration section

  2. 2

    Enter your webhook URL

    e.g., https://yoursite.com/api/retake/webhook

  3. 3

    Copy the webhook secret (optional but recommended)

    Use this to verify incoming webhooks are from Retake

Webhook Events

EventDescriptionData Fields
intent.trackedRecovery sequence started for an intent (confirms intent was queued)intentId, userId, type, value, items
intent.convertedUser converted after receiving recovery sequenceintentId, transactionId, value, recoveredAt
intent.expiredIntent expired without conversion (7 days default)intentId, userId, value, expiredAt
payment.recoveredFailed payment was successfully recoveredintentId, userId, value, recoveredAt
trial.expiredTrial period ended without conversionuserId, email, expiredAt
email.sentRecovery email successfully sentintentId, email, sentAt, templateId, step
email.openedUser opened the recovery emailintentId, openedAt
email.clickedUser clicked the recovery link in the emailintentId, clickedAt, userAgent
email.unsubscribedUser unsubscribed from marketing emailsprojectId, email, userId, reason, unsubscribedAt

Example Payload

Webhook Payload Structure
json
{
  "event": "intent.tracked",
  "timestamp": "2024-01-15T10:30:00Z",
  "data": {
    "intentId": "int_abc123",
    "userId": "user_456",
    "type": "cart",
    "value": 149.99,
    "currency": "USD",
    "items": [
      {
        "id": "sku_123",
        "name": "Premium Widget",
        "price": 149.99,
        "quantity": 1
      }
    ],
    "metadata": {
      "source": "checkout_page"
    }
  }
}

Handler Example

Here's a complete example of how to handle webhooks in Next.js:

Next.js Webhook Handler
typescript
// app/api/retake/webhook/route.ts
import { NextRequest, NextResponse } from 'next/server';
import crypto from 'crypto';

// Verify webhook signature (recommended)
function verifySignature(payload: string, signature: string, secret: string): boolean {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');
  return signature === `sha256=${expected}`;
}

export async function POST(request: NextRequest) {
  const body = await request.text();
  const signature = request.headers.get('X-Webhook-Signature');

  // Verify if you have a webhook secret configured
  if (process.env.RETAKE_WEBHOOK_SECRET && signature) {
    if (!verifySignature(body, signature, process.env.RETAKE_WEBHOOK_SECRET)) {
      return NextResponse.json({ error: 'Invalid signature' }, { status: 401 });
    }
  }

  const payload = JSON.parse(body);
  
  switch (payload.event) {
    case 'intent.tracked':
      // Triggered when a new intent is tracked
      console.log('New intent:', payload.data.intentId);
      break;

    case 'intent.converted':
      // Triggered when user clicks recovery link and converts
      console.log('Revenue recovered:', payload.data.value);
      break;

    case 'payment.failed':
       // Urgent: Payment failed!
       console.log('Payment failed for user:', payload.data.userId);
       break;

    case 'email.sent':
      // Triggered when a recovery email is successfully sent
      console.log('Recovery email sent to:', payload.data.email);
      break;
  }

  return NextResponse.json({ received: true });
}

Best Practices

Always verify signatures

Use the webhook secret to verify requests are from Retake.

Return 200 quickly

Process webhooks async. Return 200 immediately to avoid timeouts.

Handle duplicates

Webhooks may be retried. Use intentId as idempotency key.

Log everything

Log webhook payloads for debugging and audit trails.