InstaWebhook
Contents

Security

Configure Webhook Signing

Updated July 5, 2026

Configure Webhook Signing

Signing lets receivers verify that a delivery came from InstaWebhook and was not modified in transit. The signature payload is:

Code example
timestamp.event_id.raw_body

Delivery requests include these headers:

Code example
InstaWebhook-Event-Id
InstaWebhook-Delivery-Id
InstaWebhook-Timestamp
InstaWebhook-Attempt
InstaWebhook-Signature

Use a timestamp tolerance in the receiver to reduce replay risk. Rotate signing secrets when access changes.

Node.js

Code example
import crypto from "crypto";

export function verifyInstaWebhookSignature({
  secret,
  timestamp,
  eventId,
  rawBody,
  signature,
}: {
  secret: string;
  timestamp: string;
  eventId: string;
  rawBody: string;
  signature: string;
}) {
  const signedPayload = `${timestamp}.${eventId}.${rawBody}`;
  const expected = crypto
    .createHmac("sha256", secret)
    .update(signedPayload)
    .digest("hex");

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

Python

Code example
import hmac
import hashlib

def verify_instawebhook_signature(secret, timestamp, event_id, raw_body, signature):
    payload = f"{timestamp}.{event_id}.{raw_body}".encode("utf-8")
    expected = hmac.new(secret.encode("utf-8"), payload, hashlib.sha256).hexdigest()
    return hmac.compare_digest(signature, expected)

Ruby

Code example
require "openssl"

def verify_instawebhook_signature(secret, timestamp, event_id, raw_body, signature)
  payload = "#{timestamp}.#{event_id}.#{raw_body}"
  expected = OpenSSL::HMAC.hexdigest("SHA256", secret, payload)
  return false unless signature.bytesize == expected.bytesize

  OpenSSL.fixed_length_secure_compare(signature, expected)
end

PHP

Code example
function verifyInstaWebhookSignature(string $secret, string $timestamp, string $eventId, string $rawBody, string $signature): bool
{
    $payload = $timestamp . "." . $eventId . "." . $rawBody;
    $expected = hash_hmac("sha256", $payload, $secret);

    return hash_equals($expected, $signature);
}

Go

Code example
package webhooks

import (
  "crypto/hmac"
  "crypto/sha256"
  "encoding/hex"
)

func VerifyInstaWebhookSignature(secret, timestamp, eventID, rawBody, signature string) bool {
  payload := timestamp + "." + eventID + "." + rawBody
  mac := hmac.New(sha256.New, []byte(secret))
  mac.Write([]byte(payload))
  expected := hex.EncodeToString(mac.Sum(nil))

  return hmac.Equal([]byte(signature), []byte(expected))
}

Related articles