diff --git a/README.md b/README.md
index 52e1c6fb..476f1955 100644
--- a/README.md
+++ b/README.md
@@ -570,6 +570,78 @@ Used for internal logging. Defaults to [`console`](https://developer.mozilla.org
+### validateEventNameOrNames()
+
+```js
+validateEventNameOrNames(event);
+```
+
+
+
+
+
+ event
+
+ string | string[]
+
+ |
+
+ Required.
+ The event name or an array of event names to validate.
+ |
+
+
+
+
+Returns `true` if the provided event name(s) match a known event name; otherwise, returns `false`.
+
+Example:
+
+```js
+const event = "user.created";
+if (validateEventNameOrNames(event)) {
+ console.log("Event is valid!");
+}
+```
+
+---
+
+### validatePayload()
+
+```js
+validatePayload(input);
+```
+
+
+
+
+
+ input
+
+ Object
+
+ |
+
+ Required.
+ The JSON input to validate and type-cast to the event type. Should contain properties `name`, `id`, and `payload`.
+ |
+
+
+
+
+Returns a boolean value. If the input matches the expected structure and contains a valid event name, an ID, and a payload, it returns `true`. Otherwise, it returns `false`.
+
+Example:
+
+```js
+const webhookData = { name: 'user.created', id: '12345', payload: { ... } };
+
+if (validatePayload(webhookData)) {
+ // You can safely access webhookData as an EmitterWebhookEvent
+ console.log('Webhook payload is valid!');
+}
+```
+
### Webhook events
See the full list of [event types with example payloads](https://docs.github.com/developers/webhooks-and-events/webhook-events-and-payloads/).
diff --git a/src/index.ts b/src/index.ts
index 7d8b6e02..94edd1ce 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -20,6 +20,7 @@ import type {
export { createNodeMiddleware } from "./middleware/node/index.js";
export { createWebMiddleware } from "./middleware/web/index.js";
export { emitterEventNames } from "./generated/webhook-names.js";
+export { validateEventNameOrNames, validatePayload } from "./validate-event.js";
// U holds the return value of `transform` function in Options
class Webhooks {
diff --git a/src/validate-event.ts b/src/validate-event.ts
new file mode 100644
index 00000000..46c46495
--- /dev/null
+++ b/src/validate-event.ts
@@ -0,0 +1,63 @@
+import { emitterEventNames } from "./generated/webhook-names.js";
+import type { EmitterWebhookEventName, EmitterWebhookEvent } from "./types.js";
+
+/**
+ * Validates if the provided event name or names are a know event name.
+ * If validation is successful, the types get narrowed to {@link EmitterWebhookEventName}.
+ *
+ * @param {string | string[]} event The event name or an array of event names to validate.
+ * @returns {event is EmitterWebhookEventName | EmitterWebhookEventName[]} True if the event name(s) are valid, otherwise false.
+ */
+export function validateEventNameOrNames(
+ event: string | string[],
+): event is EmitterWebhookEventName | EmitterWebhookEventName[] {
+ if (Array.isArray(event)) {
+ return event.every((e) =>
+ emitterEventNames.includes(e as EmitterWebhookEventName),
+ );
+ }
+ return emitterEventNames.includes(event as EmitterWebhookEventName);
+}
+
+/**
+ * Validates the structure and type of a webhook payload and narrows the type to the corresponding event type.
+ *
+ * This function ensures that the provided input matches the expected structure of an event,
+ * including a valid event name, an ID, and a payload. If the validation passes, the input is
+ * narrowed to the specific {@link EmitterWebhookEvent} type.
+ *
+ * @template {EmitterWebhookEventName} TName The specific event name to validate against.
+ * @param {unknown} input The JSON input to validate and type-cast to the event type.
+ * @returns {input is EmitterWebhookEvent} True if the input is a valid event payload, otherwise false.
+ */
+export function validatePayload(
+ input: unknown,
+): input is EmitterWebhookEvent {
+ // Ensure the input is an object and has the necessary properties
+ if (
+ typeof input !== "object" ||
+ input === null ||
+ !("name" in input) ||
+ !("id" in input) ||
+ !("payload" in input)
+ ) {
+ return false;
+ }
+
+ const typedInput = input as {
+ name: Object | undefined;
+ id: Object | undefined;
+ payload: Object | undefined;
+ };
+
+ if (
+ typeof typedInput.name !== "string" ||
+ typeof typedInput.id !== "string" ||
+ typeof typedInput.payload !== "object" ||
+ typedInput.payload === null
+ ) {
+ return false;
+ }
+
+ return validateEventNameOrNames(typedInput.name);
+}