The settings flow allows authenticated users to manage their account information, credentials, and security settings. Users can update their profile, change passwords, add or remove authentication methods, and configure multi-factor authentication.
Flow initialization
Settings flows require an active authenticated session.
Browser flows
Initialize a settings flow for browser applications:
curl -X GET \
'https://{project}.projects.oryapis.com/self-service/settings/browser' \
-H 'Cookie: ory_kratos_session=...' \
-H 'Accept: application/json'
Query parameters:
return_to - URL to redirect to after successful settings update
Response:
{
"id" : "f6a7b8c9-d0e1-4f2a-3b4c-5d6e7f8a9b0c" ,
"type" : "browser" ,
"expires_at" : "2026-03-03T12:00:00Z" ,
"issued_at" : "2026-03-03T11:00:00Z" ,
"request_url" : "https://{project}.projects.oryapis.com/self-service/settings/browser" ,
"ui" : {
"action" : "https://{project}.projects.oryapis.com/self-service/settings?flow=f6a7b8c9-d0e1-4f2a-3b4c-5d6e7f8a9b0c" ,
"method" : "POST" ,
"nodes" : [ ... ]
},
"identity" : {
"id" : "..." ,
"traits" : { ... }
},
"state" : "show_form"
}
API flows
For native applications (mobile, desktop, server-to-server):
curl -X GET \
'https://{project}.projects.oryapis.com/self-service/settings/api' \
-H 'X-Session-Token: your_session_token' \
-H 'Accept: application/json'
Settings flows require authentication. If no valid session is present:
Browser flows: Redirect to the login page
API flows: Return 401 Unauthorized
Settings methods
The settings flow supports multiple methods for updating account information.
Profile updates
Update identity traits (email, name, etc.):
curl -X POST \
'https://{project}.projects.oryapis.com/self-service/settings?flow=<flow_id>' \
-H 'Content-Type: application/json' \
-H 'X-Session-Token: your_session_token' \
-d '{
"method": "profile",
"traits": {
"email": "newemail@example.com",
"name": {
"first": "Jane",
"last": "Smith"
}
}
}'
Changing the email address may trigger a verification flow if email verification is enabled.
Password changes
Update the account password:
curl -X POST \
'https://{project}.projects.oryapis.com/self-service/settings?flow=<flow_id>' \
-H 'Content-Type: application/json' \
-H 'X-Session-Token: your_session_token' \
-d '{
"method": "password",
"password": "new-secure-password"
}'
TOTP setup
Enable time-based one-time password authentication:
Initialize TOTP setup
Fetch the settings flow which includes the TOTP QR code: curl -X GET \
'https://{project}.projects.oryapis.com/self-service/settings/flows?id=<flow_id>' \
-H 'X-Session-Token: your_session_token'
The response includes a totp_qr image URL and totp_secret_key.
Verify TOTP code
Submit a code from the authenticator app to confirm setup: curl -X POST \
'https://{project}.projects.oryapis.com/self-service/settings?flow=<flow_id>' \
-H 'Content-Type: application/json' \
-H 'X-Session-Token: your_session_token' \
-d '{
"method": "totp",
"totp_code": "123456"
}'
Receive backup codes
After successful TOTP setup, backup codes are provided for account recovery.
WebAuthn/Passkey management
Add or remove security keys and passkeys:
Add a new passkey:
curl -X POST \
'https://{project}.projects.oryapis.com/self-service/settings?flow=<flow_id>' \
-H 'Content-Type: application/json' \
-H 'X-Session-Token: your_session_token' \
-d '{
"method": "passkey",
"passkey_register": "<webauthn_credential>",
"passkey_display_name": "My iPhone"
}'
Remove a passkey:
curl -X POST \
'https://{project}.projects.oryapis.com/self-service/settings?flow=<flow_id>' \
-H 'Content-Type: application/json' \
-H 'X-Session-Token: your_session_token' \
-d '{
"method": "passkey",
"passkey_remove": "credential_id"
}'
WebAuthn (security keys)
Manage FIDO2 hardware security keys:
curl -X POST \
'https://{project}.projects.oryapis.com/self-service/settings?flow=<flow_id>' \
-H 'Content-Type: application/json' \
-H 'X-Session-Token: your_session_token' \
-d '{
"method": "webauthn",
"webauthn_register": "<webauthn_credential>",
"webauthn_register_displayname": "YubiKey 5"
}'
Lookup secrets (backup codes)
Regenerate backup recovery codes:
curl -X POST \
'https://{project}.projects.oryapis.com/self-service/settings?flow=<flow_id>' \
-H 'Content-Type: application/json' \
-H 'X-Session-Token: your_session_token' \
-d '{
"method": "lookup_secret",
"lookup_secret_regenerate": true
}'
OIDC connections
Link or unlink social login providers:
Link a provider:
curl -X POST \
'https://{project}.projects.oryapis.com/self-service/settings?flow=<flow_id>' \
-H 'Content-Type: application/json' \
-H 'X-Session-Token: your_session_token' \
-d '{
"method": "oidc",
"link": "google"
}'
Unlink a provider:
curl -X POST \
'https://{project}.projects.oryapis.com/self-service/settings?flow=<flow_id>' \
-H 'Content-Type: application/json' \
-H 'X-Session-Token: your_session_token' \
-d '{
"method": "oidc",
"unlink": "google"
}'
Authenticator assurance levels
Some settings operations may require a higher AAL (Authenticator Assurance Level).
AAL1 required
AAL2 required
Basic authentication with a single factor: profile updates, adding new authentication methods, and linking OIDC providers.
Critical operations requiring MFA: changing password (if AAL2 is configured as required), removing authentication methods, and regenerating backup codes. Configure in your Kratos settings: selfservice :
flows :
settings :
required_aal : aal2
If the session doesn’t meet the required AAL, the response includes a 403 error directing the user to upgrade their session via a login flow.
Configuration
Configure settings flow behavior:
selfservice :
flows :
settings :
required_aal : aal1
lifespan : 1h
ui_url : https://your-app.com/settings
after :
default_browser_return_url : https://your-app.com/
password :
default_browser_return_url : https://your-app.com/login
hooks :
- hook : verify
Fetching an existing flow
Retrieve a settings flow by its ID:
curl -X GET \
'https://{project}.projects.oryapis.com/self-service/settings/flows?id=<flow_id>' \
-H 'X-Session-Token: your_session_token'
Error handling
Status: 401 UnauthorizedNo active session exists. Solution: Redirect to the login flow.
Status: 403 ForbiddenThe session’s AAL is insufficient for the requested operation. Solution: Upgrade the session by requesting an AAL2 login flow.
Status: 410 GoneThe settings flow has expired. Solution: Initialize a new flow.
Status: 403 ForbiddenCSRF token validation failed. Solution: Ensure cookies are properly forwarded in browser flows.
Complete flow example
Browser flow
API flow
Node.js SDK
# 1. Initialize the flow
curl -X GET \
'https://{project}.projects.oryapis.com/self-service/settings/browser' \
-H 'Cookie: ory_kratos_session=...'
# Browser is redirected to UI with flow ID
# User visits: https://your-app.com/settings?flow=<flow_id>
# 2. Update password
curl -X POST \
'https://{project}.projects.oryapis.com/self-service/settings?flow=<flow_id>' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-H 'Cookie: ory_kratos_session=...' \
-d 'method=password&password=new-password&csrf_token=...'
# User is redirected to success page
Continuity management
Some settings operations (like changing email) may require interrupting the flow for verification. Kratos uses continuity sessions to maintain state across these interruptions.
The continuity key format: ory_kratos_settings_<strategy_id>
API reference
Endpoint Method Description /self-service/settings/browserGET Initialize browser settings flow /self-service/settings/apiGET Initialize API settings flow /self-service/settings/flowsGET Get settings flow by ID /self-service/settingsPOST Submit settings flow
All endpoints are defined in selfservice/flow/settings/handler.go:37-42