GoodRx app login flow for a recycled phone number, showing account matching via birthdate and SMS verification.
GoodRx app login flow for a recycled phone number, showing account matching via birthdate and SMS verification.

GoodRx | Senior Product Designer

Recycled Mobile Number Verification

Designing a framework for authentication when a phone number can no longer be trusted.

The challenge

Phone numbers are useful authentication credentials, but they aren't permanent.

A number is recycled when it’s permanently disconnected and later reassigned to someone new. This happens when someone cancels phone service, switches carriers without keeping their number, or passes away and the account is closed. The FCC estimates that approximately 35 million telephone numbers are disconnected and become available for reassignment each year.

When a number is recycled, an SMS code meant for an existing GoodRx user could give a complete stranger access to that account and their personally identifiable information (PII), such as birthdate, full legal name, prescription details, and medical history.

The design problem was adding verification for potentially recycled numbers without disrupting users who could still verify account ownership another way.

My approach

Design the system logic before the screens.

I mapped every path from the moment GoodRx flags a potentially recycled number to a safe resolution. Instead of designing only the ideal path, I built flows with checkpoints that defined what the system knew at each stage, what to verify next, and where a user could safely continue.

Product management had limited involvement, so I worked directly with engineering to diagram what information the system had at each step, where to exit the Descope flow, and where to check the API for recycled numbers. Those conversations shaped the logic as much as the screens did.

Overall, the full flow has seven system decision points, three system outcomes, six new screens per platform, and no dead ends.

Legend

◆ System decision
◇ System outcome
◻What the user sees

Simplified overview for an existing-account user.


Treat trust as a decision, not a binary.

A recycled number didn't mean "block the user." It meant the phone number was no longer sufficient proof of ownership. The mobile login flow evaluated what else was available and chose the safest next step: verify a birthdate, confirm an email, or create a new account. The goal was friction where it protects the account, and none where the system already knew the answer.

Mobile login on iOS: five system decisions behind three new screens. Android and web follow the same logic.


Decide where verification should stop.

Verification only works when there’s something to verify against. In this flow, that meant asking the person to confirm a birthdate or email already on the account. When a flagged mobile account had neither on file, there was nothing reliable to check. That left two options. One was to tell the person an account already existed with that number and that they needed to create a new account because their details couldn’t be verified. This risked confusion and friction, and it confirmed to whoever held the number, possibly a stranger, that an account existed. The other option was to send them straight to creating a new account. I set the rule to do the latter, to reduce the security and privacy exposure.

A birthdate is required to submit a prescription claim or use telehealth, GoodRx’s core features, and an email is required for a Gold membership, GoodRx’s paid subscription service. An account with neither had never done any of those things, so it held little value that its member would miss. These were the accounts least likely to belong to a highly involved member, and the cheapest to replace. The trade-off is that the owner of a genuine but very lightly used account starts fresh without being told why. With these cases projected at under 5 a month, I judged that user experience price worth paying.


Account context changes the experience.

The same flagged number led to different experiences depending on how the person arrived. Consider an account with both an email and a phone number. If the number was flagged as recycled, but the user had logged in by email, the system already had a stronger ownership signal, so I designed the recycled number to be handled without treating the user as if they'd failed.

Email login on iOS, simplified: two system decisions behind three new screens. Android and web follow the same logic.


Errors are part of the logic.

The update-number step is where a person types a new number, so it’s where errors were most likely and needed the most care. Field problems showed inline, next to the field. A system failure showed as a banner and left the field neutral, since nothing the person entered was wrong. Skip stayed available in every state, so no error was a dead end.

Update-number errors on iOS: invalid number, already linked, and system error. Android and web follow the same patterns.


Same number, different paths.

Side by side, the two login paths show how account context changes what the system asks for and what happens when verification fails.

Mobile number login

What the system already knows:

Only the phone number

What the user is asked:

Confirm birthdate or email

Worst case:

New account creation

Email login

What the system already knows:

A verified email

What the user is asked:

Confirm the phone number or update it

Worst case:

Number removed, same account

Outcome

Shipped on iOS, Android, and web. The recycled-number logic became the standard pattern across all of the redesigned authentication flows I also created.

The framework lets GoodRx distinguish between numbers it can trust, numbers that need more verification, and numbers that can no longer establish ownership.

The interface was the easier part. The harder work was deciding what the system should know, when, and what that means for the person on the other side of the screen.

More of my work