developers/Webhooks

Webhooks

Webhooks deliver real-time HTTP POST notifications when events occur in your Intufind account — products indexed, chat messages sent, handoff requests, and more.

Available Events

EventDescription
product.createdA new product was indexed
product.updatedA product was updated
product.deletedA product was deleted
post.createdA new post was indexed
post.updatedA post was updated
post.deletedA post was deleted
chat.message_sentA chat message was sent
chat.conversation_startedA new conversation began
feedback.submittedUser feedback was submitted
handoff.requestedCustomer requested live agent handoff
handoff.acceptedAgent accepted the handoff
handoff.resolvedHandoff conversation was resolved
contact.submittedCustomer submitted contact info

Creating a Webhook

curl -X POST https://api.intufind.com/webhooks \
  -H "Authorization: Bearer if_sk_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My Webhook",
    "url": "https://your-app.com/webhooks/intufind",
    "events": ["product.created", "product.updated", "chat.message_sent"],
    "secret": "your-webhook-secret"
  }'
import { createClient, createWebhook } from '@intufind/ai-sdk';

const client = createClient({
  baseUrl: 'https://api.intufind.com',
  auth: process.env.INTUFIND_SECRET_KEY!,
});

const { data } = await createWebhook({
  client,
  body: {
    name: 'My Webhook',
    url: 'https://your-app.com/webhooks/intufind',
    events: ['product.created', 'product.updated', 'chat.message_sent'],
    secret: 'your-webhook-secret',
  },
});

Payload Format

All webhook payloads follow this structure:

{
  "id": "evt_abc123",
  "event_type": "product.created",
  "created_at": "2026-01-15T10:30:00Z",
  "data": {
    "id": "product-123",
    "name": "Wireless Headphones",
    "price": 199.99,
    "categories": ["Electronics", "Audio"]
  }
}

contact.submitted

Triggered when a customer submits contact information (typically when live agents are unavailable):

{
  "id": "evt_ghi789",
  "event_type": "contact.submitted",
  "created_at": "2026-01-15T18:45:00Z",
  "data": {
    "thread_id": "web_1234567890_abc",
    "name": "Jane Doe",
    "email": "jane@example.com",
    "phone": "+1-555-123-4567",
    "message": "I need help with my recent order #12345"
  }
}

Use this event to add leads to your CRM, create support tickets, or trigger email/SMS alerts.

Signature Verification

Webhooks include a signature header for verification:

X-Webhook-Signature: sha256=abc123...

Node.js

import crypto from 'crypto';

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

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

PHP

function verifyWebhookSignature(
    string $payload,
    string $signature,
    string $secret
): bool {
    $expected = 'sha256=' . hash_hmac('sha256', $payload, $secret);
    return hash_equals($expected, $signature);
}

$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';

if (!verifyWebhookSignature($payload, $signature, $secret)) {
    http_response_code(401);
    exit('Invalid signature');
}

$event = json_decode($payload, true);

Retry Policy

If your endpoint returns a non-2xx response or times out, Intufind retries with increasing delays:

AttemptDelay
1Immediate
21 minute
35 minutes
430 minutes
52 hours

After 5 failed attempts the webhook is marked as failed and you receive an email notification.

Testing

Send a Test Event

curl -X POST https://api.intufind.com/webhooks/{webhook-id}/test \
  -H "Authorization: Bearer if_sk_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "test_payload": {
      "event_type": "product.created",
      "data": {"id": "test-123", "name": "Test Product"}
    }
  }'

Local Development

Use a tunneling service like ngrok for local testing:

ngrok http 3000

Then register the ngrok URL (https://abc123.ngrok.io/webhooks/intufind) as your webhook endpoint.

Best Practices

  1. Always verify signatures to ensure requests originate from Intufind
  2. Respond quickly (under 30 seconds) to avoid timeouts
  3. Process asynchronously — queue webhook payloads for background processing
  4. Handle duplicates — use the event id for idempotency
  5. Monitor failures — set up alerts for repeated webhook failures

Next Steps