# An API route answers without signing in, what it means and how to fix it

By Mark Kashef, founder of Lockpick. Published 2026-10-08, updated 2026-10-08.

Why an API route that returns data to anyone is a real risk, why hiding it in the page does not help, and how to add the check in Next.js and other stacks.

If an API route returns private data without a valid sign-in, anyone who finds it can read that data. Add the check in the route itself, not in the page that calls it. Being reachable isn't a problem by itself. The trouble starts when something reachable also answers without asking who you are.

## Why the page is not enough

Your page may only call the route after someone signs in, but the route is a public address. Anyone can send it a request without your page. Next.js says to treat Route Handlers with the same security considerations as public-facing API endpoints, and to verify the user is allowed to access each one. Replit's security checklist says to always verify permissions before performing actions.

## How to fix it

1. List every API route and decide who may call it.
2. In each private route, read the session on the server and refuse the request when it is missing.
3. Check the record belongs to the caller, not only that someone is signed in.
4. Return only the fields the page needs.

```ts
// app/api/orders/route.ts on atlas.example
import { getSession } from '@/lib/session'
import { ordersFor } from '@/lib/orders'

export async function GET() {
  const session = await getSession()
  if (!session) return Response.json({ error: 'Sign in first' }, { status: 401 })
  return Response.json(await ordersFor(session.userId))
}
```

`getSession` and `ordersFor` stand for your own session and data code.

| What the route returns without signing in | What to do |
| --- | --- |
| Private records | Add the session check now |
| Public data, on purpose | Nothing, but make sure it is only public data |
| An error | Good, as long as it says nothing about the data |

## How to check

A scan tells you what answered, with the request it sent, so your developer can repeat it. Atlas, our example app at atlas.example, would show which route answered. Deep scans read your API when you have proved you own the site, and a [Pulse or Deep](/docs/get-started/pulse-or-deep) page explains the difference. An outside check sees what answered, not your code, so it cannot prove that a route it did not find is protected.

## Questions people ask

### Is a route safe if nothing in my app links to it?

No. Routes can be found from your scripts and by guessing common names. The route has to check who is asking.

### Is a check in Next.js middleware enough?

Use it for quick redirects, but check the session in the route itself as well, where the data is read.

## Sources

- [How to implement authentication in Next.js](https://nextjs.org/docs/app/guides/authentication), Next.js docs, read on 2026-10-06
- [Security checklist](https://docs.replit.com/learn/security-checklist), Replit docs, read on 2026-10-06
- [Your admin page is on the internet](https://www.lockpick.app/docs/learn/your-admin-page-is-online), Lockpick docs, read on 2026-10-06
