remainingOTPAttempts Condition

In your flow, check the remainingOTPAttempts dynamic value to see how many OTP attempts a user has left. Descope returns the same action error whether a user mistypes the code once or exhausts every attempt, remainingOTPAttempts is what lets you tell the two apart, so you can warn users as they approach the limit.

Descope sets remainingOTPAttempts to your configured limit when it sends the OTP, decrements it after each incorrect attempt, and clears it to an empty value on lockout. It's only populated for OTP sent by email, SMS, voice, WhatsApp, or instant message — for any other authentication method, the value is empty.

Detect a Locked Out User

Set the OTP verification action's error handling to Continue and connect its error output into a condition, with the key set to remainingOTPAttempts, the operator set to Greater Than, and the value set to 0. With the default Automatic handling the user is returned to the previous screen and the condition never runs.

remaining otp attempts condition showing the available numeric operators

The If branch means the user still has attempts left, so return them to the code entry screen. The Else branch means they are locked out, and you can route them to a dedicated screen, a custom error message, or an account recovery step.

Warn Before Lockout

To warn the user on their final attempt, change the If value from 0 to 1, then add an Else if with the operator set to Equals and the value set to 1. Connect it to a screen that makes the consequence explicit, such as prompting the user to request a new code rather than risk being locked out.

This gives you three branches, evaluated in order: Greater Than 1 for users with attempts to spare, Equals 1 for the final attempt warning, and Else for the lockout. Leaving the If at 0 makes the Else if unreachable, since a value of 1 already satisfies Greater Than 0.

Show the Remaining Count in an Error Message

Instead of (or in addition to) branching with a condition, you can insert remainingOTPAttempts directly into a customized error message on an action or a condition, so the live count shows up in the same message the user already sees. This uses the same mechanism described in Dynamic Values in Flow Errors: open the message field, then use its dynamic value picker to insert remainingOTPAttempts at the point in the text where the count should appear.

On the Verify Code / OTP action

  1. On the OTP verification action, leave (or set) the error's handling to Automatic.
  2. Open the Custom Error Message field and write your message, inserting remainingOTPAttempts as a dynamic value where the count should appear, for example: Incorrect code. You have {{remainingOTPAttempts}} attempts left before your account is locked.
  3. At runtime, Descope substitutes the live count, so a user on their second wrong attempt (of a 3-attempt limit) sees: Incorrect code. You have 1 attempts left before your account is locked.

Error handling with dynamic values

On a condition, alongside the branches from above

Because a condition lets you branch on the exact value, you can pair a custom error message with each branch from Warn Before Lockout, each branch only ever shows the message written for it:

  • Greater Than 1: route back to the code entry screen with a generic retry message, optionally still including the count, for example Incorrect code. You have remainingOTPAttempts attempts left.
  • Equals 1: route to a dedicated warning screen (or the same screen with a distinct message) with wording like Incorrect code. This is your last attempt before your account is locked. Consider requesting a new code instead.
  • Else (locked out): since remainingOTPAttempts is already empty here, use a fixed message with no dynamic value, for example You've used all your attempts. Request a new code or contact support to continue.
Was this helpful?

On this page