I actually found a way to do this without implementing the custom enrollment flows via API. Basically, you need to enable app-level MFA first. If you’re using the okta-hosted signin widget there’s nothing special for you to do in code. You just have to add an app-level MFA sign on policy. But if you have a custom signin widget, then use the solution described here.
Once that’s done, create a new group, call it something like Users_SMS_OptIn. Then create a new Multifactor enrollment policy and assign it to that group. Add SMS Auth as a required factor, all other factors disabled. Add a policy rule where users are prompted to enroll on first challenge. Now add an app sign on policy that is only applied to users in the Users_SMS_OptIn group. The policy should require multifactor at whatever interval you choose. Finally, you need to create a custom web page where users can go to in order to opt in to MFA. This will have to be built custom since it’s not supported by the signin widget. When users click opt in you need to make a backend API call to Okta to add them to the Users_SMS_OptIn group. Then on their next login they will be prompted for factor enrollment. To opt out, make two API calls to remove them from the group and then reset their MFA factors.
This solution does still require some custom code but it’s much simpler than trying to implement the MFA enrollment flows by hand. You still leverage the widget’s built in support for MFA factor enrollment and prompting.