The thing to remember in this scenario is that Web API is just that: an API. Even though there might not be a website, there is still a user interface somewhere (an actual website, or a WPF application, or a mobile application - doesn't matter). So the usual secure "forgotten password" functionality can still be implemented.
There is one difference, however. Instead of sending a link, send the token itself. The UI then provides the place to enter the token. The steps to follow are below:
- The user wanting to reset his password goes to the appropriate "Forgotten Password" screen in the UI.
- The user is prompted for his username.
- A token is sent to his associated email address in plaintext. The hashed version is stored in the database together with an expiry of, e.g., one hour from now.
- The user enters the token in the next screen.
- If the token is valid, the user is taken to a screen in which he can enter a new password (without having to enter the old one - the token already authenticated him).
Sending a plaintext token via email might sound a bit like sending a password via email. However the fact that it expires after a short period of time gives an attacker a very small window of opportunity to use it. Also, the token is one-time, and is discarded upon use.