# Authenticating machine callers
## The trap
Your route checks `auth()` / `getAuth()` for a session. A service calling with a Clerk API key or an M2M token has no session, so it gets a 401 even though its credential is valid. Session auth and machine auth are different checks.
## The pattern
In Next.js Route Handlers, pass `acceptsToken` to `auth()` to declare which machine token types the handler accepts alongside sessions:
```ts
const { userId } = await auth({ acceptsToken - 'api_key' })
```
Clerk's docs call this out for machine requests (API keys, OAuth tokens, machine tokens) hitting Route Handlers.
On the backend SDK side, `authenticateRequest()` accepts the same concept: it requires the publishable key unless `acceptsToken` is set to `api_key` or `m2m_token`. For M2M tokens specifically, the backend SDK exposes a dedicated `verify()` for M2M token verification.
## Checklist
- Decide per route: user sessions only, machine tokens only, or both. Do not leave it ambiguous; ambiguous routes either reject legit automation or accept sessions where only machines should call.
- API keys identify the caller; map the key to permissions server-side rather than trusting the key's existence alone.
- OAuth access tokens from third-party providers are verified with Clerk's OAuth token verification helpers, not the session flow.
- Log which token type authenticated each request. When a partner's integration breaks, "session vs machine" is the first branch in the diagnosis.