Webhook signatures are strings used to verify the validity of an incoming webhook event. This signature is passed as header values in the format: X-Neynar-Signature.

The validation is an important process to prevent exploitation and malicious webhook requests.

{
  "Content-Type": "application/json",
  "X-Neynar-Signature": "6ffbb59b2300aae63f272406069a9788598b792a944a07aba816edb039989a39"
}

Verification Process

1

Create a new signature string

Use an HMAC library of your choice to create a sha512 digest with the following:

  • Shared secret - Find this on the Developer Portal
  • Encoding format - This is always hex
  • Request payload - The request body object of the webhook POST
2

Compare the signatures

Compare the signatures from Step 1 and the request header X-Neynar-Signature

Example

Here’s an example of a Next.js API handler validating a signature from a request.

import { NextRequest } from "next/server";
import { createHmac } from "crypto";

export async function POST(req: NextRequest) {
	const body = await req.text();

  const sig = req.headers.get("X-Neynar-Signature");
  if (!sig) {
    throw new Error("Neynar signature missing from request headers");
  }

  const webhookSecret = process.env.NEYNAR_WEBHOOK_SECRET;
  if (!webhookSecret) {
    throw new Error("Make sure you set NEYNAR_WEBHOOK_SECRET in your .env file");
  }

  const hmac = createHmac("sha512", webhookSecret);
  hmac.update(body);

  const generatedSignature = hmac.digest("hex");

  const isValid = generatedSignature === sig;
  if (!isValid) {
    throw new Error("Invalid webhook signature");
  }

  const hookData = JSON.parse(body);

  // your code continues here ...
}

Appendix