Sessions API
Manage user sessions across all auth providers - list, validate, refresh, and revoke
Sessions API
Manage active user sessions across all authentication providers. Sessions are used to maintain authenticated state between requests.
Base Endpoint
/api/auth/sessionsList Active Sessions
Retrieve all active sessions for the current user.
Endpoint
GET /api/auth/sessionsHeaders
Authorization: Bearer {session_token}
# OR session cookie is automatically sentSuccess Response (200)
{
"success": true,
"data": {
"sessions": [
{
"id": "sess_abc123",
"userId": "usr_123456",
"createdAt": "2024-01-15T10:30:00Z",
"expiresAt": "2024-01-22T10:30:00Z",
"lastActiveAt": "2024-01-15T14:45:00Z",
"ipAddress": "192.168.1.1",
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)...",
"device": {
"type": "desktop",
"browser": "Chrome",
"os": "macOS"
},
"isCurrent": true
},
{
"id": "sess_def456",
"userId": "usr_123456",
"createdAt": "2024-01-14T09:00:00Z",
"expiresAt": "2024-01-21T09:00:00Z",
"lastActiveAt": "2024-01-14T18:30:00Z",
"ipAddress": "203.0.113.42",
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0...",
"device": {
"type": "mobile",
"browser": "Safari",
"os": "iOS"
},
"isCurrent": false
}
],
"total": 2
}
}Get Current Session
Validate and retrieve the current session details.
Endpoint
GET /api/auth/sessions/currentSuccess Response (200)
{
"success": true,
"data": {
"session": {
"id": "sess_abc123",
"userId": "usr_123456",
"expiresAt": "2024-01-22T10:30:00Z",
"lastActiveAt": "2024-01-15T14:45:00Z"
},
"user": {
"id": "usr_123456",
"email": "user@example.com",
"name": "John Doe",
"organizations": [
{
"id": "org_789",
"name": "Acme Inc",
"role": "owner"
}
]
}
}
}Error Response (401)
{
"success": false,
"error": {
"code": "SESSION_EXPIRED",
"message": "Session has expired, please sign in again"
}
}Refresh Session
Extend an expiring session with a refresh token.
Endpoint
POST /api/auth/sessions/refreshRequest
{
"refreshToken": "rt_xyz789..."
}Success Response (200)
{
"success": true,
"data": {
"session": {
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expiresAt": "2024-01-22T10:30:00Z",
"refreshToken": "rt_newabc..."
}
}
}Revoke Session
Sign out from a specific session.
Endpoint
DELETE /api/auth/sessions/:sessionIdSuccess Response (200)
{
"success": true,
"data": {
"revoked": true
},
"message": "Session revoked successfully"
}Revoke All Sessions
Sign out from all sessions except the current one.
Endpoint
DELETE /api/auth/sessionsRequest Body (Optional)
{
"keepCurrent": true // Default: true
}Success Response (200)
{
"success": true,
"data": {
"revokedCount": 3,
"keptCurrent": true
},
"message": "3 sessions revoked successfully"
}Code Examples
List Sessions
async function getSessions() {
const response = await fetch('/api/auth/sessions', {
credentials: 'include' // Include cookies
});
const result = await response.json();
if (result.success) {
return result.data.sessions;
}
throw new Error(result.error?.message);
}React Hook for Session Management
import { useEffect, useState } from 'react';
interface Session {
id: string;
createdAt: string;
expiresAt: string;
lastActiveAt: string;
device: {
type: string;
browser: string;
os: string;
};
isCurrent: boolean;
}
export function useSessions() {
const [sessions, setSessions] = useState<Session[]>([]);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
fetchSessions();
}, []);
const fetchSessions = async () => {
try {
const response = await fetch('/api/auth/sessions', {
credentials: 'include'
});
const result = await response.json();
if (result.success) {
setSessions(result.data.sessions);
} else {
setError(result.error?.message);
}
} catch {
setError('Failed to fetch sessions');
} finally {
setIsLoading(false);
}
};
const revokeSession = async (sessionId: string) => {
const response = await fetch(`/api/auth/sessions/${sessionId}`, {
method: 'DELETE',
credentials: 'include'
});
const result = await response.json();
if (result.success) {
setSessions(sessions.filter(s => s.id !== sessionId));
}
return result;
};
const revokeAllSessions = async () => {
const response = await fetch('/api/auth/sessions', {
method: 'DELETE',
credentials: 'include'
});
const result = await response.json();
if (result.success) {
// Keep only current session
setSessions(sessions.filter(s => s.isCurrent));
}
return result;
};
return {
sessions,
isLoading,
error,
revokeSession,
revokeAllSessions,
refresh: fetchSessions
};
}Session Security Component
export function SessionManager() {
const { sessions, isLoading, revokeSession, revokeAllSessions } = useSessions();
if (isLoading) return <div>Loading sessions...</div>;
return (
<div className="session-manager">
<h2>Active Sessions</h2>
<div className="sessions-list">
{sessions.map(session => (
<div
key={session.id}
className={`session-card ${session.isCurrent ? 'current' : ''}`}
>
<div className="device-info">
<span className="device-type">{session.device.type}</span>
<span className="browser">{session.device.browser}</span>
<span className="os">{session.device.os}</span>
{session.isCurrent && <span className="badge">Current</span>}
</div>
<div className="session-meta">
<p>Last active: {new Date(session.lastActiveAt).toLocaleString()}</p>
<p>Expires: {new Date(session.expiresAt).toLocaleString()}</p>
</div>
{!session.isCurrent && (
<button
onClick={() => revokeSession(session.id)}
className="revoke-btn"
>
Sign Out
</button>
)}
</div>
))}
</div>
{sessions.length > 1 && (
<button
onClick={revokeAllSessions}
className="revoke-all-btn"
>
Sign Out All Other Devices
</button>
)}
</div>
);
}Provider-Specific Behavior
BetterAuth
- Sessions stored in database with configurable expiry
- Supports concurrent session limits per user
- Device fingerprinting for security
NextAuth
- JWT sessions: Stateless, encoded in token
- Database sessions: Stored in session table
- Automatic session rotation on refresh
Clerk
- Sessions managed by Clerk infrastructure
- Automatic session refresh
- Device tracking included
AuthKit
- WorkOS session management
- Organization-aware sessions
- SSO session synchronization
Session Security
| Feature | Implementation |
|---|---|
| Expiration | Configurable TTL (default: 7 days) |
| Rotation | Refresh tokens rotate on use |
| Concurrent Limits | Max 10 active sessions per user |
| IP Binding | Optional IP validation |
| Device Fingerprint | Browser + OS detection |
Webhook Events
| Event | Description |
|---|---|
session.created | New session established |
session.refreshed | Session token rotated |
session.revoked | Session manually ended |
session.expired | Session TTL reached |
Rate Limits
- List sessions: 60 requests per minute
- Refresh session: 10 requests per minute
- Revoke session: 30 requests per minute