# Authentication

Login, logout, and session management

## Authenticate user with email and password

> Authenticates a user using email and password credentials.\
> On success, establishes a session and returns an authentication token\
> with optional redirect URL.\
> \
> \*\*Email Verification Requirement:\*\*\
> When \`GUEST\_USER\_REGISTRATION\_REQUIRES\_EMAIL\_VERIFICATION\` is enabled\
> (Dynamic Configuration), login is blocked for users who:\
> 1\. Were created as guest users during checkout (have \`verification\_required\` \
> &#x20;  attribute set to \`true\` in their user profile)\
> 2\. Have not yet verified their email address\
> \
> These users must click the verification link sent to their email before\
> they can log in. The error message will be: "Please verify your email \
> address before login."\
> \
> Throttling scope: \`login\`.

```json
{"openapi":"3.1.0","info":{"title":"Users API - Authentication, Password, Orders, and Hooks","version":"1.0.0"},"tags":[{"name":"Authentication","description":"Login, logout, and session management"}],"servers":[{"description":"Default commerce site","url":"https://{commerce_url}","variables":{"commerce_url":{"default":"sandbox.akinon.com","description":"Commerce storefront hostname"}}}],"paths":{"/users/login":{"post":{"tags":["Authentication"],"operationId":"loginUser","summary":"Authenticate user with email and password","description":"Authenticates a user using email and password credentials.\nOn success, establishes a session and returns an authentication token\nwith optional redirect URL.\n\n**Email Verification Requirement:**\nWhen `GUEST_USER_REGISTRATION_REQUIRES_EMAIL_VERIFICATION` is enabled\n(Dynamic Configuration), login is blocked for users who:\n1. Were created as guest users during checkout (have `verification_required` \n   attribute set to `true` in their user profile)\n2. Have not yet verified their email address\n\nThese users must click the verification link sent to their email before\nthey can log in. The error message will be: \"Please verify your email \naddress before login.\"\n\nThrottling scope: `login`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}}},"responses":{"200":{"description":"Login successful","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginResponse"}}}},"400":{"description":"Invalid credentials or email not verified"},"429":{"description":"Too many login attempts (throttled)"}}}}},"components":{"schemas":{"LoginRequest":{"type":"object","required":["email","password"],"properties":{"email":{"type":"string","format":"email","description":"User email address"},"password":{"type":"string","format":"password","description":"User password"}}},"LoginResponse":{"type":"object","required":["key"],"properties":{"key":{"type":"string","description":"Authentication token for the user session.\nUse this token in the `Authorization: Token <key>` header\nfor subsequent API requests, or it will be used automatically\nvia TokenAuthentication."},"redirect_url":{"type":["string","null"],"description":"Optional redirect URL derived from 'next' query parameter.\nWill be null if no redirect was specified."}}}}}}
```

## Authenticate user with phone and OTP code

> Authenticates a user using phone number and SMS verification code.\
> This is a two-step process:\
> \
> \*\*Step 1 - Request OTP:\*\*\
> Send \`phone\` without \`code\`. System validates phone exists, sends SMS\
> verification code, and stores confirmation data in session.\
> Returns empty 200 response on success.\
> \
> \*\*Step 2 - Verify and Login:\*\*\
> Send \`phone\` with \`code\`. If valid, user is authenticated and\
> returns authentication token with redirect URL.\
> \
> \*\*Code Validation:\*\*\
> \- Code must be 4-20 characters\
> \- Code expiration controlled by \`SMS\_OTP\_EXPIRE\_TIME\` setting\
> \- Invalid or expired codes return 406 status\
> \
> Throttling scope: \`login\`.

```json
{"openapi":"3.1.0","info":{"title":"Users API - Authentication, Password, Orders, and Hooks","version":"1.0.0"},"tags":[{"name":"Authentication","description":"Login, logout, and session management"}],"servers":[{"description":"Default commerce site","url":"https://{commerce_url}","variables":{"commerce_url":{"default":"sandbox.akinon.com","description":"Commerce storefront hostname"}}}],"paths":{"/users/otp-login":{"post":{"tags":["Authentication"],"operationId":"otpLoginUser","summary":"Authenticate user with phone and OTP code","description":"Authenticates a user using phone number and SMS verification code.\nThis is a two-step process:\n\n**Step 1 - Request OTP:**\nSend `phone` without `code`. System validates phone exists, sends SMS\nverification code, and stores confirmation data in session.\nReturns empty 200 response on success.\n\n**Step 2 - Verify and Login:**\nSend `phone` with `code`. If valid, user is authenticated and\nreturns authentication token with redirect URL.\n\n**Code Validation:**\n- Code must be 4-20 characters\n- Code expiration controlled by `SMS_OTP_EXPIRE_TIME` setting\n- Invalid or expired codes return 406 status\n\nThrottling scope: `login`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OTPLoginRequest"}}}},"responses":{"200":{"description":"- With valid `code`: Login successful, returns authentication token\n- Without `code`: OTP sent successfully (empty response body)","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/LoginResponse"},{"type":"object","description":"Empty response when OTP is sent"}]}}}},"400":{"description":"Validation errors:\n- Phone number doesn't exist in system\n- Phone number format is invalid\n- Code length is invalid (less than 4 characters)"},"406":{"description":"- Incorrect OTP code\n- OTP code expired"},"429":{"description":"Too many login attempts (throttled)"}}}}},"components":{"schemas":{"OTPLoginRequest":{"type":"object","required":["phone"],"properties":{"phone":{"type":"string","maxLength":16,"description":"Phone number that matches an existing active user in the system.\nPhone number must pass the configured phone regex validator.\nReturns 400 error if no user exists with this phone number."},"code":{"type":"string","minLength":4,"maxLength":20,"description":"SMS verification code received in Step 1.\n- Omit this field on first request to receive OTP via SMS\n- Include this field with the received code to complete login\n- Code expiration is controlled by `SMS_OTP_EXPIRE_TIME` setting"}}},"LoginResponse":{"type":"object","required":["key"],"properties":{"key":{"type":"string","description":"Authentication token for the user session.\nUse this token in the `Authorization: Token <key>` header\nfor subsequent API requests, or it will be used automatically\nvia TokenAuthentication."},"redirect_url":{"type":["string","null"],"description":"Optional redirect URL derived from 'next' query parameter.\nWill be null if no redirect was specified."}}}}}}
```

## End user session

> Terminates the current user session and clears session data.\
> \
> \*\*Redirect Behavior:\*\*\
> \- If \`referrer\` starts with the account index path (e.g., \`/users/\`),\
> &#x20; redirects to home page\
> \- Otherwise, uses the \`next\` parameter or default logout redirect URL\
> \- For non-existent URLs in \`next\`, falls back to adapter's logout redirect\
> \
> \*\*Audit Logging:\*\*\
> Creates an audit event recording the logout action with user information,\
> client type, and browser agent.\
> \
> Can be called by anonymous users (no error, simply redirects).

```json
{"openapi":"3.1.0","info":{"title":"Users API - Authentication, Password, Orders, and Hooks","version":"1.0.0"},"tags":[{"name":"Authentication","description":"Login, logout, and session management"}],"servers":[{"description":"Default commerce site","url":"https://{commerce_url}","variables":{"commerce_url":{"default":"sandbox.akinon.com","description":"Commerce storefront hostname"}}}],"paths":{"/users/logout/":{"post":{"tags":["Authentication"],"operationId":"logoutUser","summary":"End user session","description":"Terminates the current user session and clears session data.\n\n**Redirect Behavior:**\n- If `referrer` starts with the account index path (e.g., `/users/`),\n  redirects to home page\n- Otherwise, uses the `next` parameter or default logout redirect URL\n- For non-existent URLs in `next`, falls back to adapter's logout redirect\n\n**Audit Logging:**\nCreates an audit event recording the logout action with user information,\nclient type, and browser agent.\n\nCan be called by anonymous users (no error, simply redirects).","parameters":[{"$ref":"#/components/parameters/CSRFTokenHeader"}],"requestBody":{"required":false,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"referrer":{"type":"string","description":"URL referrer. If starts with account index path\n(reverse of 'account-index'), redirects to home page."},"next":{"type":"string","description":"URL to redirect after logout. Must be a valid resolvable path.\nFalls back to adapter's logout redirect if invalid."}}}}}},"responses":{"302":{"description":"Redirect to specified or default logout URL"}}}}},"components":{"parameters":{"CSRFTokenHeader":{"name":"X-CSRFToken","in":"header","required":true,"schema":{"type":"string"},"description":"CSRF token for state-changing requests"}}}}
```

## Generate one-time login token (Admin Only)

> Generates a one-time login token for passwordless authentication.\
> This is an administrative endpoint used to create secure login links\
> that can be sent to users via email or other channels.\
> \
> \*\*Authentication Required:\*\* Admin users only.\
> \
> \*\*Flow:\*\*\
> 1\. Admin provides user ID and secret key\
> 2\. System generates one-time token\
> 3\. Returns redirect URL with embedded token\
> 4\. Admin sends this URL to the user (e.g., via email)\
> 5\. User clicks URL and is authenticated at \`/users/passwordless-login/{token}/\`\
> \
> \*\*Token Properties:\*\*\
> \- One-time use only (deleted after successful login)\
> \- Time-limited (expires after 5 minutes)\
> \
> \*\*Secret Key:\*\*\
> The secret\_key parameter is used for token generation and must be provided\
> again when the token is used at the GET endpoint. This adds an extra\
> layer of security beyond the token itself.

```json
{"openapi":"3.1.0","info":{"title":"Users API - Authentication, Password, Orders, and Hooks","version":"1.0.0"},"tags":[{"name":"Authentication","description":"Login, logout, and session management"}],"servers":[{"description":"Default commerce site","url":"https://{commerce_url}","variables":{"commerce_url":{"default":"sandbox.akinon.com","description":"Commerce storefront hostname"}}}],"security":[{"AdminAuthentication":[]}],"components":{"securitySchemes":{"AdminAuthentication":{"type":"http","scheme":"bearer","bearerFormat":"Token","description":"Admin authentication using Token Authentication.\nRequires user to have admin/staff privileges.\nInclude token in Authorization header as: `Authorization: Token <token>`"}},"schemas":{"PasswordlessLoginTokenRequest":{"type":"object","required":["user","secret_key"],"properties":{"user":{"type":"integer","description":"User ID for whom to generate the one-time login token.\nMust be an active user in the system."},"secret_key":{"type":"string","description":"Secret key used for token generation and validation.\nThis same key must be provided when using the generated token\nat `/users/passwordless-login/{token}/` endpoint."}}},"PasswordlessLoginTokenResponse":{"type":"object","properties":{"redirect_url":{"type":"string","description":"Partial URL path containing only the token.\nFormat: `/users/passwordless-login/{token}/`\n\n**Important:** This is NOT a complete URL. The admin must append query\nparameters `user` and `secret_key` to create the full login link:\n`/users/passwordless-login/{token}/?user={user_id}&secret_key={secret_key}`\n\nToken expires after `PASSWORDLESS_LOGIN_MAX_AGE` seconds (default: 300)."}}}}},"paths":{"/api/v1/passwordless-login/":{"post":{"tags":["Authentication"],"operationId":"generatePasswordlessLoginToken","summary":"Generate one-time login token (Admin Only)","description":"Generates a one-time login token for passwordless authentication.\nThis is an administrative endpoint used to create secure login links\nthat can be sent to users via email or other channels.\n\n**Authentication Required:** Admin users only.\n\n**Flow:**\n1. Admin provides user ID and secret key\n2. System generates one-time token\n3. Returns redirect URL with embedded token\n4. Admin sends this URL to the user (e.g., via email)\n5. User clicks URL and is authenticated at `/users/passwordless-login/{token}/`\n\n**Token Properties:**\n- One-time use only (deleted after successful login)\n- Time-limited (expires after 5 minutes)\n\n**Secret Key:**\nThe secret_key parameter is used for token generation and must be provided\nagain when the token is used at the GET endpoint. This adds an extra\nlayer of security beyond the token itself.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordlessLoginTokenRequest"}}}},"responses":{"200":{"description":"Token generated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordlessLoginTokenResponse"}}}},"400":{"description":"Validation errors:\n- User ID doesn't exist\n- User is not active\n- Missing required fields"},"401":{"description":"Authentication required"},"403":{"description":"Admin permission required"}}}}}}
```

## Authenticate via one-time token link

> Validates a one-time token and automatically logs in the user.\
> This endpoint is typically accessed via email link sent by administrators.\
> \
> \*\*Flow:\*\*\
> 1\. Administrator generates one-time token via admin API\
> 2\. Token is sent to user via email/link\
> 3\. User clicks link with token in URL\
> 4\. System validates token and completes login\
> 5\. User is redirected to specified URL or home\
> \
> \*\*Token Validation:\*\*\
> \- Token must exist and not be expired\
> \- Token expires after 5 minutes\
> \- After successful login, token is deleted (single use)\
> \
> \*\*Invalid Token Handling:\*\*\
> \- Expired or invalid tokens redirect to home page\
> \- No error message is shown (silent fail for security)

```json
{"openapi":"3.1.0","info":{"title":"Users API - Authentication, Password, Orders, and Hooks","version":"1.0.0"},"tags":[{"name":"Authentication","description":"Login, logout, and session management"}],"servers":[{"description":"Default commerce site","url":"https://{commerce_url}","variables":{"commerce_url":{"default":"sandbox.akinon.com","description":"Commerce storefront hostname"}}}],"paths":{"/users/passwordless-login/{token}/":{"get":{"tags":["Authentication"],"operationId":"passwordlessLogin","summary":"Authenticate via one-time token link","description":"Validates a one-time token and automatically logs in the user.\nThis endpoint is typically accessed via email link sent by administrators.\n\n**Flow:**\n1. Administrator generates one-time token via admin API\n2. Token is sent to user via email/link\n3. User clicks link with token in URL\n4. System validates token and completes login\n5. User is redirected to specified URL or home\n\n**Token Validation:**\n- Token must exist and not be expired\n- Token expires after 5 minutes\n- After successful login, token is deleted (single use)\n\n**Invalid Token Handling:**\n- Expired or invalid tokens redirect to home page\n- No error message is shown (silent fail for security)","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string"},"description":"One-time login token generated by the admin API."},{"name":"user","in":"query","required":true,"schema":{"type":"integer"},"description":"User ID for token validation"},{"name":"secret_key","in":"query","required":true,"schema":{"type":"string"},"description":"Secret key used for token generation and validation.\nMust match the key used when creating the token."},{"name":"next","in":"query","required":false,"schema":{"type":"string"},"description":"URL to redirect after successful login.\nDefaults to home page if not provided."}],"responses":{"302":{"description":"- Valid token: User logged in, redirected to 'next' URL or home\n- Invalid/expired token: Redirected to home page"}}}}}}
```

## Authenticate via auth token (API)

> Authenticates user using their existing authentication token via API call.\
> This is designed for programmatic/mobile app access.\
> \
> \*\*Important:\*\* This endpoint uses authentication tokens (from standard login), NOT\
> one-time tokens. For one-time token authentication, use the GET endpoint\
> \`/users/passwordless-login/{token}/\` with tokens generated from\
> \`/api/v1/passwordless-login/\` (admin endpoint).\
> \
> \*\*Flow:\*\*\
> 1\. User must already have an authentication token (obtained from previous login)\
> 2\. Client sends user ID and token\
> 3\. System validates token exists for that user\
> 4\. User is logged in via session authentication\
> 5\. Returns success status (no redirect, pure API response)\
> \
> \*\*Token Validation:\*\*\
> \- Token must exist and be associated with the specified user\
> \- Token is the user's permanent auth token (not a one-time token)\
> \- Token is NOT deleted after login (can be reused)\
> \
> \*\*Use Case:\*\*\
> This endpoint allows mobile apps or API clients to establish a session\
> using the token they received from standard login, enabling them\
> to access session-based endpoints.

```json
{"openapi":"3.1.0","info":{"title":"Users API - Authentication, Password, Orders, and Hooks","version":"1.0.0"},"tags":[{"name":"Authentication","description":"Login, logout, and session management"}],"servers":[{"description":"Default commerce site","url":"https://{commerce_url}","variables":{"commerce_url":{"default":"sandbox.akinon.com","description":"Commerce storefront hostname"}}}],"paths":{"/users/passwordless-login-with-token/":{"post":{"tags":["Authentication"],"operationId":"passwordlessLoginWithToken","summary":"Authenticate via auth token (API)","description":"Authenticates user using their existing authentication token via API call.\nThis is designed for programmatic/mobile app access.\n\n**Important:** This endpoint uses authentication tokens (from standard login), NOT\none-time tokens. For one-time token authentication, use the GET endpoint\n`/users/passwordless-login/{token}/` with tokens generated from\n`/api/v1/passwordless-login/` (admin endpoint).\n\n**Flow:**\n1. User must already have an authentication token (obtained from previous login)\n2. Client sends user ID and token\n3. System validates token exists for that user\n4. User is logged in via session authentication\n5. Returns success status (no redirect, pure API response)\n\n**Token Validation:**\n- Token must exist and be associated with the specified user\n- Token is the user's permanent auth token (not a one-time token)\n- Token is NOT deleted after login (can be reused)\n\n**Use Case:**\nThis endpoint allows mobile apps or API clients to establish a session\nusing the token they received from standard login, enabling them\nto access session-based endpoints.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordlessLoginRequest"}}}},"responses":{"200":{"description":"Login successful, session established"},"400":{"description":"Validation errors:\n- User ID doesn't exist or user is not active\n- Token doesn't exist for the specified user\n- Token doesn't match user's auth token"}}}}},"components":{"schemas":{"PasswordlessLoginRequest":{"type":"object","required":["user","token"],"properties":{"user":{"type":"integer","description":"User ID. Must be an active user in the system.\nReturns 400 if user doesn't exist or is inactive."},"token":{"type":"string","description":"User's authentication token.\nThis is the same token returned from `/users/login` endpoint.\nMust match the token associated with the specified user."}}}}}}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://apidocs.akinon.com/commerce-openapis/users/module-3/authentication.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
