Skip to main content

Add a redirect

In this example, you will add a new redirect by staging a version with the redirect rule.
run.ts
import { Vercel } from '@vercel/sdk';

const vercel = new Vercel({
  bearerToken: process.env.VERCEL_BEARER_TOKEN,
});

async function addRedirect() {
  const teamId = process.env.VERCEL_TEAM_ID as string;
  const projectId = process.env.VERCEL_PROJECT_ID as string;

  try {
    const result = await vercel.bulkRedirects.stageRedirects({
      teamId,
      requestBody: {
        teamId,
        projectId,
        redirects: [
          {
            source: '/old-page',
            destination: '/new-page',
            statusCode: 308, // Permanent redirect
          },
        ],
      },
    });

    console.log(`Created redirect version: ${result.version?.id}`);
  } catch (error) {
    console.error(
      error instanceof Error ? `Error: ${error.message}` : String(error),
    );
  }
}

addRedirect();

Promote a redirect version

In this example, you promote a staged redirect version to active, making it live in production.
run.ts
import { Vercel } from '@vercel/sdk';

const vercel = new Vercel({
  bearerToken: process.env.VERCEL_BEARER_TOKEN,
});

async function promoteRedirectVersion() {
  const teamId = process.env.VERCEL_TEAM_ID as string;
  const projectId = process.env.VERCEL_PROJECT_ID as string;
  const versionId = 'your-version-id'; // The version ID to promote

  try {
    const result = await vercel.bulkRedirects.updateVersion({
      teamId,
      projectId,
      requestBody: {
        action: 'promote',
        id: versionId,
      },
    });

    console.log(`Promoted version to active`);
    console.log('Version Details:', JSON.stringify(result.version, null, 2));
  } catch (error) {
    console.error(
      error instanceof Error ? `Error: ${error.message}` : String(error),
    );
  }
}

promoteRedirectVersion();

Automate redirects with a webhook handler

In this example, you create a Next.js API route that receives redirect configurations from external systems (like a CMS) and uses the Vercel SDK to stage and promote bulk redirects automatically.
run.ts
import { NextResponse } from 'next/server';
import { Vercel } from '@vercel/sdk';

const vercel = new Vercel({
  bearerToken: process.env.VERCEL_BEARER_TOKEN,
});

interface RedirectRule {
  source: string;
  destination: string;
  statusCode?: 307 | 308 | 301 | 302;
}

interface WebhookPayload {
  redirects: RedirectRule[];
  autoPromote?: boolean;
}

export async function POST(request: Request) {
  const teamId = process.env.VERCEL_TEAM_ID as string;
  const projectId = process.env.VERCEL_PROJECT_ID as string;

  if (!teamId || !projectId) {
    return NextResponse.json(
      { error: 'Missing environment variables' },
      { status: 500 },
    );
  }

  try {
    const payload: WebhookPayload = await request.json();

    if (!payload.redirects || !Array.isArray(payload.redirects)) {
      return NextResponse.json(
        { error: 'Invalid payload: redirects array required' },
        { status: 400 },
      );
    }

    // Stage new redirects
    const stageResult = await vercel.bulkRedirects.stageRedirects({
      teamId,
      requestBody: {
        teamId,
        projectId,
        redirects: payload.redirects.map((redirect) => ({
          source: redirect.source,
          destination: redirect.destination,
          statusCode: redirect.statusCode || 308,
        })),
      },
    });

    const newVersion = stageResult.version;
    if (!newVersion) {
      return NextResponse.json(
        { error: 'Failed to create new version' },
        { status: 500 },
      );
    }

    // Optionally auto-promote to production
    if (payload.autoPromote) {
      const publishResult = await vercel.bulkRedirects.updateVersion({
        teamId,
        projectId,
        requestBody: {
          action: 'promote',
          id: newVersion.id,
        },
      });

      if (!publishResult.version) {
        return NextResponse.json(
          { error: 'Failed to publish new version' },
          { status: 500 },
        );
      }

      return NextResponse.json({
        message: 'Success!',
        version: publishResult.version,
        status: 'promoted',
      });
    }

    return NextResponse.json({
      message: 'Redirects staged successfully',
      version: newVersion,
      status: 'staged',
    });
  } catch (error) {
    console.error('Error processing redirect webhook:', error);

    return NextResponse.json(
      {
        error: 'Failed to process redirects',
        details: error instanceof Error ? error.message : 'Unknown error',
      },
      { status: 500 },
    );
  }
}