> How authentication works in Pylo, user sessions vs API tokens

# Authentication

Pylo supports two authentication methods: user login (OAuth2) for user-facing applications and API
tokens for server-to-server integrations.

| Method                                   | Best for                            | Token lifetime        |
| ---------------------------------------- | ----------------------------------- | --------------------- |
| User login (OAuth2)                      | Web applications, user sessions     | 1 hour (auto-refresh) |
| [API tokens](/authentication/api-tokens) | Server integrations, scripts, CI/CD | Long-lived            |

**Use user login** when you build a web application with user sessions and user-specific
permissions. The [Next.js integration](/authentication/nextjs-setup) handles login, logout, and
token refresh.

**Use API tokens** for server-to-server integrations, automated scripts, and long-lived credentials
without user login.

## Making authenticated requests

With a user session (Bearer token):

```bash filename="terminal"
curl -X POST https://api.pyloapp.com/graphql \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -d '{"query": "{ me { id email } }"}'
```

With an API token:

```bash filename="terminal"
curl -X POST https://api.pyloapp.com/graphql \
  -H "Content-Type: application/json" \
  -H "pylo-api-key: YOUR_API_KEY" \
  -d '{"query": "{ customerList { data { id name } } }"}'
```

## OAuth2 flow

1. User submits email and password
2. Pylo validates credentials and returns tokens
3. The auth token (1 hour) authenticates API requests
4. The refresh token (7 days) gets new auth tokens

### Login mutation

```graphql filename="mutation"
mutation Login($input: AuthRequest!) {
  login(input: $input) {
    data {
      auth_token
      refresh_token
    }
  }
}
```

### Token refresh

```graphql filename="mutation"
mutation RefreshToken($input: AuthRefreshRequest!) {
  refreshToken(input: $input) {
    data {
      auth_token
      refresh_token
    }
  }
}
```

> **Automatic refresh**
> With the [Next.js integration](/authentication/nextjs-setup), the middleware refreshes tokens
> before they expire. You never touch them yourself.

## Public endpoints

To expose public-facing endpoints without user authentication, create an API token with restrictive
permissions and send it with your requests.

Next: [Next.js Setup](/authentication/nextjs-setup)
