This guide shows how to protect API routes in a Next.js App Router application using protectApi().
Protected API routes require authentication and can optionally enforce group-based authorization.
protectApi()This guide assumes you’ve completed the Next.js App Router quickstart.
You should already have:
.env.localCreate an API route and wrap the handler with protectApi().
import { protectApi } from "@monocloud/auth-nextjs";
import { NextResponse } from "next/server";
export const GET = protectApi(() =>
NextResponse.json({ message: "You have accessed a protected endpoint" }),
);
How it works:
protectApi() runs on every requestYou can require users to belong to specific groups before accessing an API route.
groups to the application scopes.env.local:MONOCLOUD_AUTH_SCOPES=openid profile email groups
After updating scopes, users must sign out and sign back in for the new claims to be included in their session.
import { protectApi } from "@monocloud/auth-nextjs";
import { NextResponse } from "next/server";
export const GET = protectApi(
() => NextResponse.json({ message: "Admin-only data" }),
{
groups: ["admin"],
}
);
To customize the response when a user is not authenticated, pass the onAccessDenied option.
import { protectApi } from "@monocloud/auth-nextjs";
import { NextResponse } from "next/server";
export const GET = protectApi(
() => NextResponse.json({ message: "Protected data" }),
{
onAccessDenied: () =>
NextResponse.json(
{
error: "unauthorized",
message: "Please sign in"
},
{ status: 401 }
)
}
);
How it works:
To customize the response when a user is authenticated but does not belong to the required group, pass the onGroupAccessDenied option.
import { protectApi } from "@monocloud/auth-nextjs";
import { NextResponse } from "next/server";
export const GET = protectApi(
() => NextResponse.json({ message: "Admin-only data" }),
{
groups: ["admin"],
onGroupAccessDenied: (_req, _ctx, user) =>
NextResponse.json(
{
error: "forbidden",
message: `User ${user.email} does not have access to this resource.`
},
{ status: 403 }
)
}
);
How it works:
onAccessDenied).onGroupAccessDenied).Protect other parts of your application: