← Files ClerkARCHIVED FILE
skills/clerk-nextjs-patterns/references/api-routes.md
1.43 KB · Oct 3, 2026 · 06:25 UTC
# API Routes
## Auth Check Pattern
```typescript
import { auth } from '@clerk/nextjs/server';
export async function GET() {
const { isAuthenticated, userId } = await auth();
if (!isAuthenticated) {
return Response.json({ error: 'Unauthorized' }, { status: 401 });
}
const data = await db.data.findMany({ where: { userId } });
return Response.json(data);
}
```
> **Core 2 ONLY (skip if current SDK):** `isAuthenticated` is not available. Use `if (!userId)` instead.
## 401 vs 403
- **401** - Not authenticated
- **403** - Authenticated but lacks permission
```typescript
export async function DELETE(req: Request) {
const { isAuthenticated, has } = await auth();
if (!isAuthenticated) return Response.json({ error: 'Unauthorized' }, { status: 401 });
const isAdmin = await has({ role: 'org:admin' });
if (!isAdmin) return Response.json({ error: 'Forbidden' }, { status: 403 });
return Response.json({ success: true });
}
```
## Org Route Protection
```typescript
export async function GET(req: Request, { params }: { params: { orgId: string } }) {
const { userId, orgId } = await auth();
if (!userId) return Response.json({ error: 'Unauthorized' }, { status: 401 });
if (orgId !== params.orgId) return Response.json({ error: 'Forbidden' }, { status: 403 });
const orgData = await db.orgs.findUnique({ where: { id: orgId } });
return Response.json(orgData);
}
```
[Docs](https://clerk.com/docs/reference/nextjs/auth)
SHA-256: 751a4881c20d6bbbd1e53555e3228af3e13a29fd61dd724b496a0cd9c9a6b51e