Docs
Webhooks

Webhooks

Set up organization webhooks and verify signed events from your Inrconnect workspace.

Overview

Webhooks let your system receive real‑time events from your Inrconnect organization. When configured, Inrconnect sends an HTTP POST to your endpoint whenever selected events occur.

Supported triggers

  • CONTACT_CREATED
  • CONTACT_UPDATED
  • CONTACT_DELETED

You can choose one or more triggers per webhook.

Create a webhook

  1. In the Dashboard, go to Settings → Organization → Developers → Webhooks.
  2. Click “Create Webhook”.
  3. Enter your HTTPS endpoint URL (e.g., https://api.example.com/inrconnect/webhooks).
  4. Select the triggers you want to receive.
  5. Provide a signing secret (recommended). This is used to verify authenticity.
  6. Save.

You can create multiple webhooks per organization.

Event delivery

Requests are sent as POST application/json with the following body:

{
  "trigger": "CONTACT_CREATED",
  "createdAt": "2025-08-14T21:10:00.000Z",
  "payload": {
    "contact": {
      "id": "uuid",
      "record": "person|company",
      "name": "Jane Doe",
      "email": "jane@example.com",
      "phone": "+1 555-0100",
      "stage": "lead|qualified|...",
      "tags": ["vip", "newsletter"]
    }
  }
}

For updates:

{
  "trigger": "CONTACT_UPDATED",
  "createdAt": "2025-08-14T21:10:00.000Z",
  "payload": {
    "contact": { "id": "uuid", "name": "Jane Doe", "...": "..." },
    "changes": {
      "name": { "old": "Jane", "new": "Jane Doe" },
      "tags": { "old": "vip", "new": "vip,newsletter" }
    }
  }
}

For deletes:

{
  "trigger": "CONTACT_DELETED",
  "createdAt": "2025-08-14T21:10:00.000Z",
  "payload": {
    "contact": { "id": "uuid" }
  }
}

Security and signature verification

If you set a secret when creating the webhook, each request includes:

  • X-Webhook-Signature-256: HMAC-SHA256 hex digest of the raw JSON body using your secret

Verify by computing the HMAC over the exact raw request body and comparing in constant time.

Node/Next.js example

import crypto from 'node:crypto';
import { NextResponse } from 'next/server';
 
const SECRET = process.env.INRCONNECT_WEBHOOK_SECRET!;
 
export async function POST(req: Request) {
  const signature = req.headers.get('x-webhook-signature-256') || '';
  const rawBody = await req.text();
 
  const expected = crypto
    .createHmac('sha256', SECRET)
    .update(rawBody)
    .digest('hex');
 
  const ok =
    signature.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
 
  if (!ok)
    return NextResponse.json({ error: 'Invalid signature' }, { status: 401 });
 
  const event = JSON.parse(rawBody);
  // TODO: handle event.trigger and event.payload
  return NextResponse.json({ ok: true });
}

Express example

import crypto from 'node:crypto';
import express from 'express';
 
const app = express();
app.use(express.text({ type: 'application/json' })); // preserve raw body
 
const SECRET = process.env.INRCONNECT_WEBHOOK_SECRET!;
 
app.post('/inrconnect/webhooks', (req, res) => {
  const signature = req.header('x-webhook-signature-256') || '';
  const expected = crypto
    .createHmac('sha256', SECRET)
    .update(req.body)
    .digest('hex');
 
  const ok =
    signature.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
 
  if (!ok) return res.status(401).json({ error: 'Invalid signature' });
 
  const event = JSON.parse(req.body);
  res.json({ ok: true });
});

Retries

Deliveries are attempted up to 3 times. If your endpoint returns a non-2xx status or times out, we retry with exponential backoff.

Best practices

  • Use a unique, sufficiently long secret per webhook
  • Respond with 2xx quickly (queue heavy work)
  • Log request IDs and timestamps
  • Treat unknown triggers as no-ops for forward compatibility

Troubleshooting

  • 401: Check your secret and signature computation against the raw body
  • 4xx: Validate your endpoint accepts application/json
  • 5xx/timeouts: Ensure your handler returns quickly; move processing to a queue
All systems normal