Connect to your own API
Connect to your own API
Secure backend access with OIDC federation is available on all plans.
Validate the tokens
To configure your own API to accept Vercel's OIDC tokens, you need to validate the tokens using Vercel's JSON Web Keys (JWTs), available at https://oidc.vercel.com/[TEAM_SLUG]/.well-known/jwks with the team issuer mode, and https://oidc.vercel.com/.well-known/jwks for the global issuer mode.
Use the jose.jwtVerify function
Install the following package:
pnpm i jose
yarn add jose
npm i jose
bun add jose
In the code example below, you use the jose.jwtVerify function to verify the token. The issuer, audience, and subject are validated against the token's claims.
import http from 'node:http';
import * as jose from 'jose';
const ISSUER_URL = `https://oidc.vercel.com/[TEAM_SLUG]`;
// or use `https://oidc.vercel.com` if your issuer mode is set to Global.
const JWKS = jose.createRemoteJWKSet(new URL(ISSUER_URL, '/.well-known/jwks'));
const server = http.createServer(async (req, res) => {
const token = req.headers['authorization']?.split('Bearer ')[1];
if (!token) {
res.statusCode = 401;
res.end('Unauthorized');
return;
}
try {
const { payload } = await jose.jwtVerify(token, JWKS, {
issuer: ISSUER_URL,
audience: 'https://vercel.com/[TEAM_SLUG]',
subject:
'owner:[TEAM_SLUG]:project:[PROJECT_NAME]:environment:[ENVIRONMENT]',
});
res.statusCode = 200;
res.end('OK');
} catch (error) {
res.statusCode = 401;
res.end('Unauthorized');
}
});
server.listen(3000);
Make sure that you:
- Replace
[TEAM_SLUG]with your team identifier from the Vercel's team URL - Replace
[PROJECT_NAME]with your project's name in your project's settings - Replace
[ENVIRONMENT]withdevelopment,preview,production, or a Custom Environment slug
Use the getVercelOidcToken function
Install the following package:
pnpm i @vercel/oidc
yarn add @vercel/oidc
npm i @vercel/oidc
bun add @vercel/oidc
In the code example below, the getVercelOidcToken function is used to retrieve the OIDC token from your Vercel environment. You can then use this token to authenticate the request to the external API.
import { getVercelOidcToken } from '@vercel/oidc';
export const GET = async () => {
const result = await fetch('https://api.example.com', {
headers: {
Authorization: `Bearer ${await getVercelOidcToken()}`,
},
});
return Response.json(await result.json());
};
Use a custom audience
By default, the OIDC token's aud claim is set to https://vercel.com/[TEAM_SLUG]. If your API expects a different audience value, pass the audience option to getVercelOidcToken. This exchanges the default token for a new one with the custom aud claim.
import { getVercelOidcToken } from '@vercel/oidc';
export const GET = async () => {
const token = await getVercelOidcToken({
audience: 'https://api.example.com',
});
const result = await fetch('https://api.example.com', {
headers: {
Authorization: `Bearer ${token}`,
},
});
return Response.json(await result.json());
};
When validating the token on your API server, update the expected audience to match:
const { payload } = await jose.jwtVerify(token, JWKS, {
issuer: ISSUER_URL,
audience: 'https://api.example.com',
});
Last updated September 17, 2026.