Webhooks Overview

Webhooks are the best way to get real-time information about events happening within your Jodie AI account. When a specified event occurs, we’ll send an HTTP POST request to a URL you provide, allowing you to build powerful, event-driven integrations.

Enterprise Subscription Required

Access to webhooks is a premium feature. You will need to upgrade to an Enterprise plan or the@ API is a paid addon.

How It Works

When an event, such as a new.call, is triggered, Jodie AI sends a signed HTTP POST request to your configured webhook endpoint. The request body contains a JSON payload with details about the event.

If your endpoint doesn’t respond with a 2xx success status code, we’ll automatically retry the request.

Setting Up a Webhook

  1. Navigate to the Developers > Webhooks section in your dashboard.
  2. Click Add Webhook.
  3. Enter the Webhook URL. This must be a secure https URL.
  4. Save the endpoint.

Once added, you will see your new endpoint along with its unique Signing Secret. You’ll need this secret to verify that incoming requests are genuinely from Jodie AI.

Verifying Signatures

To ensure the security of your data, Jodie AI signs every webhook request with a unique signature. This signature is passed in the Signature HTTP header.

The signature is a SHA256 HMAC hash of the raw request payload, keyed by your webhook’s Signing Secret.

Here’s an example of how you can verify the signature in a Node.js application using Express:

const express = require('express');
const crypto = require('crypto');

const app = express();

// Use raw body parser for signature verification
app.use(
  express.json({
    verify: (req, res, buf) => {
      req.rawBody = buf;
    },
  })
);

const webhookSecret = process.env.JODIE_WEBHOOK_SECRET; // Your signing secret

app.post('/webhooks/jodie', (req, res) => {
  const signature = req.get('Signature');
  if (!signature) {
    return res.status(400).send('No signature provided.');
  }

  const hmac = crypto.createHmac('sha256', webhookSecret);
  const digest = 'sha256=' + hmac.update(req.rawBody).digest('hex');

  if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(digest))) {
    return res.status(401).send('Invalid signature.');
  }

  // Signature is valid, process the event
  console.log('Received valid webhook:', req.body);

  res.status(200).send('Success');
});

app.listen(3000, () => console.log('Server running on port 3000'));

Always use a timing-safe comparison method (crypto.timingSafeEqual in Node.js) to prevent timing attacks.

Retries

If your endpoint is unavailable or returns a non-2xx status code, we will retry sending the webhook up to 3 times with an exponential backoff strategy. This ensures that you receive the event even if your server has a temporary outage.