In short
Sometimes you need a proper URL that returns JSON, for a mobile app, a webhook or a third-party service. Route handlers let you build that right inside your Next.js project.
Backend endpoints defined inside your Next.js app (`app/api/.../route.ts`) — letting you build a small API alongside your frontend in the same project.

Think of it like this
The ATM outside the bank
The bank (your website) has a counter for people walking in. The ATM outside serves anyone with a card at any hour, through a fixed set of buttons. A route handler is your app's ATM: a fixed endpoint other programs can use.
Watch it happen
A mobile app calls your route
GET /api/courses/42
1/6The URL matches app/api/courses/[id]/route.ts, so its GET function runs.
The big ideas
What you need to know
route.ts files
app/api/courses/route.ts becomes /api/courses. Export functions named GET, POST, PATCH or DELETE.
Web standard Request and Response
You get a standard Request and return Response.json(data) with a status code.
Dynamic segments work too
app/api/courses/[id]/route.ts receives params as a Promise in its second argument.
Not always needed
Your own pages can fetch in Server Components or use Server Actions. Use routes for outside callers.
See it in code
Walk through the code
1// app/api/courses/[id]/route.ts2export async function GET(3 request: Request,4 { params }: { params: Promise<{ id: string }> }5) {6 const { id } = await params;7 const course = await db.course.findUnique({ where: { id } });8 9 if (!course) {10 return Response.json({ error: "Course not found" }, { status: 404 });11 }12 return Response.json(course);13}1/4Export a function named after the HTTP method. The second argument holds params.
GET /api/courses/42 runs this function. Return honest status codes so whoever calls it can handle errors properly.
Save yourself the pain
Common mistakes
Oops
Having a page.tsx and a route.ts in the same folder.
Do this instead
A segment can have one or the other. Keep APIs under app/api/ to avoid clashes.
Oops
Returning 200 with { error: "..." } for every failure.
Do this instead
Use real status codes like 400, 401, 404 and 500 so clients can react correctly.
Your mission
Build a tiny courses API
Quick check
Which file handles GET requests to /api/hello?
Go deeper
- 1Build a simple GET/POST API route and call it from a client component.
- 2Learn how to read query params and request bodies inside a route handler.
- 3Understand when to use an API route vs a Server Action for the same task.
More topics at this stop
Stuck on this topic? Ask an Insider
Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.