Configure OTP retry and resend limits per application¶
Use conditional authentication to control how many times a user can resend an OTP or fail OTP verification during a single login attempt.
Scenario¶
Consider a login flow that uses SMS OTP with these requirements:
- Users can request at most 3 OTP resends per login.
- Users can submit at most 3 incorrect OTPs per login.
Once a user reaches either limit, the login flow blocks further retries or resend requests.
Prerequisites¶
- Register an application in Asgardeo.
- Add an SMS OTP authenticator to at least one step in the application's login flow.
Configure the login flow¶
-
On the Asgardeo Console, go to Applications.
-
Select the application and open the Login Flow tab.
-
In the authentication script, find the
executeStep(...)call that runs SMS OTP or Email OTP. Inside that step, add anauthenticatorParamsblock. Use the correct authenticator identifier:sms-otp-authenticatorfor SMS OTPemail-otp-authenticatorfor Email OTP
See the Example script section for the full structure.
-
Set the following parameters in the script:
Parameter Description enableRetryFromAuthenticatorSet to "true"to enforce the limits defined in the script.maximumAllowedResendAttemptsMaximum number of OTP resend attempts allowed per login. maximumAllowedFailureAttemptsMaximum number of incorrect OTP submissions allowed before the flow blocks further retries. terminateOnResendLimitExceededControls what happens when the resend limit is reached.
"true"— Ends the authentication flow immediately.
"false"— Blocks further resends but still accepts the last issued OTP. -
Click Update to save the script.
Account lock takes precedence
If Asgardeo locks the user account (for example, due to too many failed login attempts at the tenant level) before the user reaches maximumAllowedFailureAttempts, the account lock ends the authentication flow immediately.
Connection-level resend block
You can also configure a resend block at the connection level using settings such as Allowed OTP resend attempt count and Resend block duration. If the connection-level block triggers before the application-level limit (maximumAllowedResendAttempts), the connection temporarily blocks resend requests for the configured duration.
Example script¶
The following script sets a maximum of 3 resends and 3 OTP verification failures for the SMS OTP step. The flow ends when the user exceeds the resend limit:
var onLoginRequest = function(context) {
executeStep(1); // Basic Authentication
executeStep(2, {
authenticatorParams: {
local: {
"sms-otp-authenticator": {
"enableRetryFromAuthenticator": "true",
"maximumAllowedResendAttempts": "3",
"maximumAllowedFailureAttempts": "3",
"terminateOnResendLimitExceeded": "true"
}
}
}
}, {});
};
For Email OTP, replace sms-otp-authenticator with email-otp-authenticator inside the local block:
"email-otp-authenticator": {
"enableRetryFromAuthenticator": "true",
"maximumAllowedResendAttempts": "3",
"maximumAllowedFailureAttempts": "3",
"terminateOnResendLimitExceeded": "true"
}
If you omit these parameters, the OTP step uses its default behavior with no application-level limits.
API-based flow error responses¶
When you use app-native authentication, reaching either limit returns an error response.
Retry limit exceeded¶
Asgardeo returns this error when the user exceeds maximumAllowedFailureAttempts:
{
"code": "ABA-60013",
"message": "Maximum retry attempts exceeded.",
"description": "Authentication failed. The maximum number of retry attempts has been exceeded.",
"traceId": "20260311T060000Z-186b9bdb58cwz52dhC1SG155uc00000005zg000000002m7c"
}
Resend limit exceeded¶
Asgardeo returns this error when the user exceeds maximumAllowedResendAttempts:
{
"code": "ABA-60014",
"message": "Maximum resend attempts exceeded.",
"description": "Authentication failed. The maximum number of resend attempts has been exceeded.",
"traceId": "20260311T060000Z-186b9bdb58cwz52dhC1SG155uc00000005zg000000002m7c"
}
Try it out¶
-
Open the application and complete the first authentication step (for example, username and password).
-
When prompted for an OTP, enter an incorrect code repeatedly. After
maximumAllowedFailureAttemptsfailures, the flow blocks OTP retries. -
Start a new login and request OTP resends repeatedly. After
maximumAllowedResendAttemptsresends:- If
terminateOnResendLimitExceededis"true", the authentication flow ends. - If
terminateOnResendLimitExceededis"false", the flow blocks further resends but still accepts the last issued OTP.
- If
Note
For more on the authentication script and executeStep, see the Conditional Authentication API Reference.