Skip to content

Webhooks API

Learn about the supported webhook events and how to use them.

Vercel Integrations allow you to subscribe to certain trigger-based events through webhooks. An example use-cases for webhooks might be cleaning up resources after someone removes your Integration.

The webhook payload is a JSON object with the following keys.

Key
Description
type
id
The ID of the webhook delivery.
createdAt
The webhook delivery timestamp.
region
The region the event occurred in (possibly null).
payload
The payload of the webhook. See Supported Event Types for more information.

Occurs whenever a deployment is created.

Occurs whenever a deployment is ready.

Note: This event gets fired after all blocking Checks have passed. See deployment-prepared if you registered Checks.

Occurs whenever a deployment is successfully built and your integration has registered at least one check.

Occurs whenever a deployment is canceled.

Occurs whenever a deployment has failed.

Occurs when a user has requested for a check to be rerun after it failed.

Occurs whenever a project has been created.

Note: This event is sent only when the Integration has access to all projects in a Vercel scope.

Occurs whenever a project has been removed.

Note: This event is sent only when the integration has access to all projects in a Vercel scope.

Occurs whenever the user confirms pending scope changes.

Occurs whenever an integration has been removed.

Occurs whenever the user changes the project permission for an integration.

Occurs whenever a domain has been created.

The legacy webhook payload is a JSON object with the following keys.

Key
Description
type
id
The ID of the webhook delivery.
createdAt
The webhook delivery timestamp.
region
The region the event occurred in (possibly null).
clientId
The ID of integration's client.
ownerId
The ID of the event owner (user or team).
teamId
The ID of the event's team (possibly null).
userId
The ID of the event's users.
webhookId
The ID of the webhook.
payload
The payload of the webhook. See Legacy Event Types for more information.

The following event types have been deprecated and webhooks that listen for them can no longer be created. Vercel will continue to deliver the deprecated events to existing webhooks.

Note: This event is replaced by deployment.created.

Occurs whenever a deployment is created.

Note: This event is replaced by deployment.succeeded.

Occurs whenever a deployment is ready.

Note: This event gets fired after all blocking checks have passed. See deployment-prepared if you registered Checks.
Note: This event is replaced by deployment.ready.

Occurs whenever a deployment is successfully built and your integration has registered at least one check.

Note: This event is replaced by deployment.canceled.

Occurs whenever a deployment is canceled.

Note: This event is replaced by deployment.error.

Occurs whenever a deployment has failed.

Note: This event is replaced by deployment.check-rerequested.

Occurs when a user has requested for a check to be rerun after it failed.

Note: This event has been removed. deployment.succeeded can be used for the same purpose.

Occurs when all checks for a deployment have completed. This does not indicate that they have all passed, only that they are no longer running. It is possible for webhook to occur multiple times for a single deployment if any checks are re-requested.

Note: This event is replaced by project.created.

Occurs whenever a project has been created.

Note: This event is sent only when the Integration has access to all projects in a Vercel scope.

Note: This event is replaced by project.removed.

Occurs whenever a Project has been removed.

Note: This event is sent only when the Integration has access to all Projects in a Vercel scope.

Note: This event is replaced by integration-configuration.removed.

Occurs whenever an integration has been removed.

Note: This event is replaced by integration-configuration.permission-upgraded.

Occurs whenever the user changes the project permission for an integration.

Note: This event is replaced by integration-configuration.scope-change-confirmed.

Occurs whenever the user confirms pending scope changes.

Note: This event is replaced by domain.created.

Occurs whenever a domain has been created.

Once your server is configured to receive payloads, it will listen for any payload sent to the endpoint you configured. By knowing the URL of your webhook, anybody can send you requests. Therefore, it is recommended to check whether the requests are coming from Vercel or not.

The recommended method to check is to use the x-vercel-signature security header you receive with each request. The value of this header corresponds to the sha1 of the request body using your client secret.

For example, you can validate a webhook request as follows:

import type { NextApiRequest, NextApiResponse } from 'next';
import crypto from 'crypto';
import getRawBody from 'raw-body';

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse,
) {
  const rawBody = await getRawBody(req);
  const bodySignature = sha1(rawBody, process.env.INTEGRATION_SECRET);

  if (bodySignature !== req.headers['x-vercel-signature']) {
    return res.status(403).json({
      code: 'invalid_signature',
      error: "signature didn't match",
    });
  }

  const json = JSON.parse(rawBody.toString('utf-8'));

  switch (json.type) {
    case 'project.created':
    // ...
  }

  res.status(200).end('OK');
}

function sha1(data: Buffer, secret: string): string {
  return crypto.createHmac('sha1', secret).update(data).digest('hex');
}

export const config = {
  api: {
    bodyParser: false,
  },
};

Example on how to validate a webhook message.

You can compute the signature using an HMAC hexdigest from the secret token of OAuth2 and request body, then compare it with the value of the x-vercel-signature header to validate the payload.

You should consider this HTTP request to be an event. Once you receive the request, you should schedule a task for your action.

This request has a timeout of 30 seconds. That means if a 2XX HTTP response is not received within 30 seconds, the request will be aborted.

If your HTTP endpoint does not respond with a 2XX HTTP status code, we attempt to deliver the webhook event up to 24 hours with an exponential backoff. Events that could not be delivered within 24 hours will not be retried and will be discarded.