Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Advanced Clerk auth patterns for Next.js: Server Actions, middleware, caching, and App Router integration.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
references/api-routes.md
1# API Routes23## Auth Check Pattern45```typescript6import { auth } from '@clerk/nextjs/server';78export async function GET() {9const { isAuthenticated, userId } = await auth();10if (!isAuthenticated) {11return Response.json({ error: 'Unauthorized' }, { status: 401 });12}13const data = await db.data.findMany({ where: { userId } });14return Response.json(data);15}16```1718> **Core 2 ONLY (skip if current SDK):** `isAuthenticated` is not available. Use `if (!userId)` instead.1920## 401 vs 4032122- **401** - Not authenticated23- **403** - Authenticated but lacks permission2425```typescript26export async function DELETE(req: Request) {27const { isAuthenticated, has } = await auth();28if (!isAuthenticated) return Response.json({ error: 'Unauthorized' }, { status: 401 });2930const isAdmin = await has({ role: 'org:admin' });31if (!isAdmin) return Response.json({ error: 'Forbidden' }, { status: 403 });3233return Response.json({ success: true });34}35```3637## Org Route Protection3839```typescript40export async function GET(req: Request, { params }: { params: { orgId: string } }) {41const { userId, orgId } = await auth();42if (!userId) return Response.json({ error: 'Unauthorized' }, { status: 401 });43if (orgId !== params.orgId) return Response.json({ error: 'Forbidden' }, { status: 403 });4445const orgData = await db.orgs.findUnique({ where: { id: orgId } });46return Response.json(orgData);47}48```4950[Docs](https://clerk.com/docs/reference/nextjs/auth)51