GET /v1/auth/session
Return the current authenticated user plus their resolved capabilities.
::: tip Auth Required: cookie or Bearer. No special permissions. :::
Request
GET /v1/auth/session
| Header | Required | Notes |
|---|---|---|
Cookie: identsphere_at=... OR Authorization: Bearer ... | yes | — |
No request body.
Response
200 OK
{
"user": {
"user_id": "1c8b2a5e-...",
"organization_id": "ec3f7b1a-...",
"email": "alice@example.com",
"is_platform_admin": false,
"platform_role": null,
"api_key_id": null,
"api_key_prefix": null,
"api_key_name": null,
"team_id": null,
"project_id": null,
"auth_method": "password",
"session_family_id": "9a4d3c1e-...",
"mfa_verified_at": null,
"scopes": [],
"allowed_ips": [],
"allowed_referrers": [],
"extensions": {}
},
"capabilities": {
"role": "owner",
"permissions": [
"org.read",
"org.update",
"members.list",
"members.invite",
"members.remove"
]
}
}
Error responses
| Status | Code | When |
|---|---|---|
| 401 | authentication_required | No valid auth credential. |
| 500 | internal_error | Database failure while resolving role / platform-admin status. |
Example: curl
curl https://auth.example.com/v1/auth/session \
-b cookies.txt
Example: TypeScript (@identsphere/react)
import { useSession } from '@identsphere/react';
function Profile() {
const { data, isLoading } = useSession();
if (isLoading) return <Spinner />;
if (!data) return <Redirect to="/login" />;
return <p>Signed in as {data.user.email}</p>;
}
Notes
- The
capabilitiesfield is recomputed on every call — if a user's role changes viaPATCH /v1/orgs/:org_id/members/:user_id, the nextGET /v1/auth/sessionreflects the new permissions immediately. - The
mfa_verified_atfield is non-null when the session was minted via passkey, MFA challenge, or step-up — and the assertion is still within the step-up TTL window. - This endpoint is cheap; calling it on every page load is fine.
@identsphere/reactcalls this once on mount and caches the result in React Query; manual invalidation viaqueryClient.invalidateQueries(['session'])re-fetches.