When you actually need an API route
Server Actions cover internal mutations. Server Components cover internal data reads. Route Handlers cover the rest: webhooks, third-party integrations, and public APIs — anything that exposes a stable URL the outside world can call.
The shape
A route.ts in any folder under app/ exports HTTP method handlers (GET, POST, PUT, DELETE, etc.). Each receives a NextRequest and returns a NextResponse.
Hard rule
A folder with route.ts can't also have page.tsx. They serve different worlds (API vs UI). Pick one per folder.
Choose a Route Handler when the contract itself is an HTTP endpoint: a webhook, public API, file response, health check, or integration another system must call by URL. For an internal form mutation, prefer a Server Action; for an internal read, fetch in the Server Component that owns the view.
A familiar REST shape is not a reason to put an API between your own server-rendered page and its database. That extra hop adds serialization, authentication plumbing, and another cache boundary. The handler earns its place only when the URL is part of the product contract. Call the handler without the application UI. Verify method handling, input validation, authentication, status codes, response headers, and the missing-resource case. For a webhook, replay the same signed event and prove the write is idempotent.