Session Management
In YorAuth, each session corresponds to a refresh token. When a user logs in, a refresh token is created and stored (hashed) in the database. Listing sessions, revoking sessions, and enforcing concurrent session limits all operate on these refresh token records.
All session management endpoints require a valid JWT access token and the authenticated user must own the {userId} in the path.
What a Session Contains
Each session record exposes:
| Field | Description |
|---|---|
id | UUID of the session (refresh token record). Use this to revoke a specific session. |
device_info | Object containing ip_address and user_agent captured at login. |
is_remember_me | Whether the session was created with remember_me: true. |
last_used_at | When the refresh token was last used to obtain a new access token. |
expires_at | When the session expires. 7 days for standard, 30 days for remember me. |
created_at | When the user logged in and this session was created. |
List Active Sessions
Retrieve all non-expired, non-revoked sessions for a user. Sessions are returned in reverse chronological order (newest first).
Endpoint: GET /api/v1/applications/{applicationId}/users/{userId}/sessions
Authentication: JWT Bearer token required.
curl https://api.yorauth.com/api/v1/applications/your-application-id/users/550e8400-e29b-41d4-a716-446655440000/sessions \
-H "Authorization: Bearer <access_token>"
const response = await fetch(
`https://api.yorauth.com/api/v1/applications/your-application-id/users/${userId}/sessions`,
{
headers: { 'Authorization': `Bearer ${accessToken}` }
}
);
const data = await response.json();
Response 200 OK
{
"data": [
{
"id": "7f3c9b2a-4d5e-6f7a-8b9c-0d1e2f3a4b5c",
"device_info": {
"ip_address": "203.0.113.45",
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36"
},
"is_remember_me": false,
"last_used_at": "2026-02-25T14:30:00Z",
"expires_at": "2026-03-04T10:00:00Z",
"created_at": "2026-02-25T10:00:00Z"
},
{
"id": "1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
"device_info": {
"ip_address": "198.51.100.22",
"user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X)"
},
"is_remember_me": true,
"last_used_at": "2026-02-24T09:15:00Z",
"expires_at": "2026-03-26T09:00:00Z",
"created_at": "2026-02-24T09:00:00Z"
}
]
}
Error Responses
| HTTP Status | Error Code | Description |
|---|---|---|
| 404 | USER_NOT_FOUND | User does not exist in this application. |
Revoke a Specific Session
Revoke a single active session by its ID. The user will be signed out on the device that session belongs to after their current access token expires (up to 15 minutes).
Endpoint: DELETE /api/v1/applications/{applicationId}/users/{userId}/sessions/{sessionId}
Authentication: JWT Bearer token required.
curl -X DELETE https://api.yorauth.com/api/v1/applications/your-application-id/users/550e8400-e29b-41d4-a716-446655440000/sessions/1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d \
-H "Authorization: Bearer <access_token>"
await fetch(
`https://api.yorauth.com/api/v1/applications/your-application-id/users/${userId}/sessions/${sessionId}`,
{
method: 'DELETE',
headers: { 'Authorization': `Bearer ${accessToken}` }
}
);
Response 204 No Content
No body is returned on success.
Error Responses
| HTTP Status | Error Code | Description |
|---|---|---|
| 404 | SESSION_NOT_FOUND | Session does not exist, does not belong to this user, or is already revoked. |
Revoke All Sessions
Sign a user out of all devices by revoking every active session at once.
Endpoint: DELETE /api/v1/applications/{applicationId}/users/{userId}/sessions
Authentication: JWT Bearer token required.
curl -X DELETE https://api.yorauth.com/api/v1/applications/your-application-id/users/550e8400-e29b-41d4-a716-446655440000/sessions \
-H "Authorization: Bearer <access_token>"
const response = await fetch(
`https://api.yorauth.com/api/v1/applications/your-application-id/users/${userId}/sessions`,
{
method: 'DELETE',
headers: { 'Authorization': `Bearer ${accessToken}` }
}
);
const data = await response.json();
Response 200 OK
{
"data": {
"revoked_count": 3,
"message": "Revoked 3 active session(s)."
}
}
Error Responses
| HTTP Status | Error Code | Description |
|---|---|---|
| 404 | USER_NOT_FOUND | User does not exist in this application. |
Concurrent Session Limits
Your application can enforce a maximum number of concurrent sessions per user. This is configured on the application in the YorAuth dashboard.
When a new session is created and the user has already reached the limit, the oldest session (by last_used_at) is automatically revoked to make room. This ensures the limit is always respected without blocking new logins.
For example, with a limit of 3 concurrent sessions:
- User has 3 active sessions on Desktop, Mobile, and Tablet.
- User logs in on a second desktop.
- The session last used (e.g. Tablet, used 5 days ago) is automatically revoked.
- The new session is created. Active sessions: Desktop, Mobile, Second Desktop.
A limit of null or 0 means unlimited concurrent sessions.
Device Tracking
Session device information is captured at login time and on each token refresh. The device_info object contains:
{
"ip_address": "203.0.113.45",
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36"
}
This information is stored as-is from the request. Your frontend or application can parse the user_agent string to display a human-readable device description.
Token Reuse Detection
YorAuth implements refresh token reuse detection. Each refresh token can only be used once — after use it is immediately rotated (revoked and replaced with a new token).
If a previously revoked refresh token is presented, it indicates a potential token theft scenario. YorAuth responds by revoking all active sessions for the affected user across the application. The user must log in again on all devices.
This is a security measure to contain compromise: if an attacker stole a refresh token, using it will terminate both the attacker's and the legitimate user's sessions, prompting the user to re-authenticate and change their password.
See Token Management for more on token rotation.
Session Revocation Scenarios
| Trigger | Sessions Revoked | Notes |
|---|---|---|
POST /users/logout | Single session | Only the submitted refresh token is revoked. |
DELETE /users/{userId}/sessions/{sessionId} | Single session | User-initiated revocation of a specific session. |
DELETE /users/{userId}/sessions | All user sessions | Revokes all active refresh tokens for the user. |
| Concurrent session limit exceeded | Oldest session | Automatic, happens during new login. |
| Refresh token reuse detected | All user sessions | Security response to potential token theft. |
| Account deletion | All user sessions | Revoked as part of soft delete. |