> ## Documentation Index
> Fetch the complete documentation index at: https://docs.noyo.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Verifying webhooks

> Maintain security with verified transmissions

To verify that a webhook was actually sent by Noyo, every payload is signed with a signature that is passed through as the HTTP header. Here's how to create a secret token and signature then confirm credentials.

<Steps>
  <Step title="Create a secret token for your subscription">
    You'll create your secret token when you create the subscription in the Noyo web application. You will not be able to retrieve this secret after creating it.

    <Warning>If your webhook key is compromised or accidentally made public, contact [support@noyo.com](mailto:support@noyo.com) as soon as possible</Warning>
  </Step>

  <Step title="Generate a signature">
    The signature is hex encoded and can be replicated by applying HMAC-SHA-256 to the body of the webhook with your webhook key.

    ```bash theme={"system"}
    echo -n "{...}" | openssl dgst -sha256 -hmac "MY_WEBHOOK_KEY"
    ```
  </Step>

  <Step title="Confirm the signature">
    Webhook signatures are sent in the `x-noyo-signature` header. You can verify that Noyo sent the event by comparing the signatures.

    ```js JavaScript  theme={"system"}
    const express = require("express");
    const { createHmac, timingSafeEqual } = require("crypto");

    const PORT = 3000;

    const app = express();

    app.use(
        express.json({
            verify: (req, res, buf) => {
                const hmac = createHmac("sha256", "NOYO_WEBHOOK_KEY");
                const toHash = `${req.headers["x-noyo-timestamp"]}.${buf.toString()}`;
                hmac.update(toHash);
                const signatures = req.headers["x-noyo-signature"].split(",").map(Buffer.from);
                digest = Buffer.from(hmac.digest("hex"));
                for (noyoSignature of signatures) {
                    if (noyoSignature.length === digest.length && timingSafeEqual(noyoSignature, digest)) {
                        return;
                    }
                }
                throw new Error("Invalid signature");
            },
        })
    );

    app.post("/", (req, res) => {
        res.send("OK :)");
    });

    app.listen(PORT, () => {
        console.log(`Listening on port ${PORT}`);
    });
    ```
  </Step>
</Steps>
