Introduction

Webhooks allow you to subscribe to changes in Certifier and receive real-time HTTP requests to a specified URL when those changes occur.

This mechanism is ideal for real-time data synchronization (e.g., ETL pipelines) and event-driven automation (e.g., Certifier's Zapier integration relies on webhooks).

Creating Webhooks

You can create, view, and manage your webhooks in the Certifier dashboard:

Settings > Developers > Webhooks

Webhook Payloads

Webhooks are sent as POST requests with a JSON payload. The payload structure depends on the event type.

Example Payload

{
  "id": "01jmyw7nvtk2372kwn572mwfq7",
  "type": "credential.created",
  "createdAt": "2025-02-25T15:39:59.680Z",
  "data": {
    "resource": {
      "id": "01jmyw4zyyrtyntqcevy2zmbnf",
      "type": "credential"
    }
  },
}

Webhook Security

To ensure authenticity, all webhook requests are signed using a cryptographic signature.

Signature Verification

Each webhook request includes an X-Webhook-Signature header, which contains a SHA256 HMAC signature of the request payload, signed with your webhook secret.

How to Verify Signatures

  1. Retrieve the X-Webhook-Signature header.
  2. Compute the HMAC SHA256 signature using your webhook secret and the request payload.
  3. Compare your computed signature with the received signature using a timing-safe comparison.

Example in Node.js

const crypto = require("crypto");

/**
 * Verifies the authenticity of a webhook request using HMAC SHA256.
 * @param {string} payload - The raw webhook payload.
 * @param {string} receivedSignature - The received X-Webhook-Signature header.
 * @param {string} secret - Your webhook secret.
 * @returns {boolean} - Returns true if the signature is valid, false otherwise.
 */
function verifyWebhookSignature(payload, receivedSignature, secret) {
    if (!receivedSignature) {
        console.error("Missing webhook signature");
        return false;
    }

    try {
        const hmac = crypto.createHmac("sha256", secret);
        hmac.update(payload, "utf8");
        const expectedSignature = hmac.digest("hex");

        return crypto.timingSafeEqual(
            Buffer.from(receivedSignature, "hex"),
            Buffer.from(expectedSignature, "hex")
        );
    } catch (error) {
        console.error("Error verifying webhook signature:", error);
        return false;
    }
}

// Usage example
const webhookPayload = JSON.stringify(request.body);
const receivedSignature = request.headers["x-webhook-signature"];
const webhookSecret = "your_webhook_secret";

if (!verifyWebhookSignature(webhookPayload, receivedSignature, webhookSecret)) {
    throw new Error("Invalid webhook signature");
}

Webhook Event Types

Webhooks follow a resource.action naming pattern. The available events are:

  • credential.created – A credential has been created.
  • credential.updated – A credential has been updated.
  • credential.deleted – A credential has been deleted.
  • credential.issued – A credential has been issued.

Best Practices

  • Verify webhook signatures to ensure authenticity.
  • Use HTTPS endpoints for security.
  • Respond within 5 seconds to avoid timeouts.
  • Process webhooks asynchronously to improve reliability.
  • Log webhook deliveries and failures for debugging purposes.
  • Use idempotency mechanisms to handle duplicate webhook deliveries.

Retry Mechanism

If your server fails to respond with a 2xx HTTP status code, we will retry the delivery using an exponential backoff schedule:

  1. 3 minutes after the first failure
  2. 6 minutes after the previous retry
  3. 30 minutes after the previous retry
  4. 1 hour after the previous retry
  5. 12 hours after the previous retry
  6. 24 hours after the previous retry
  7. 48 hours after the previous retry

Retries stop after 7 failed attempts (~3.5 days total). You can monitor webhook failures in the dashboard.

Retry Headers

  • X-Retry-Count: Indicates the retry attempt number (starts at 1). The initial attempt does not include this header.

Webhook Technical Details

PropertyValue
Timeout5 seconds
Maximum Retries7 attempts
Retry Window~3.5 days
Required ResponseHTTP 2xx
Request MethodPOST
Content Typeapplication/json
Character EncodingUTF-8

Testing Webhooks

We recommend using webhook.site or RequestBin to inspect webhook payloads during development.

Monitoring & Debugging

You can track webhook deliveries, failures, and retries in the Certifier dashboard:

Settings > Developers > Webhooks > Events

Rate Limiting

Currently, there are no rate limits on webhook deliveries. However, we recommend implementing queue-based processing on your end to handle high event volumes efficiently.

Support

If you need assistance with webhooks, contact our support team or join the discussion on Discussions.