Sounds like there is business logic that you want to implement. The specifics will depend on the language or framework you have used to build your web application. I suggest that you have your pages or routes that need to be authenticated (ie private) and those that do not (ie public). The "update password" page is private, the OTP page is public. This means that no one can get to the update password page unless they have been authenticated.
The workflow then is the user lands on your public OTP page. Anyone can get there and anyone can enter any OTP. Your target user types in their OTP. You trust the OTP* and therefore you trust that that the OTP is a suitable and robust authentication token. At that point your code (your controller if you are using an MVC or whatever your app is) signs in the user. You know the user's ID because you have said that you record the OTP in a database.
Now your user is a legitimate signed-in user and you can redirect from your route to the update password page.
You didn't say that you wanted to prevent the user going anywhere other than the update password page, but if you want that to be the only place they can go then you will need to have a flag that says this user is at the post-OTP stage and then your routes will have to check for this and deny access to any route if the user is a post-OTP user. You will have to reset the OTP flag after they have updated the database. I don't think I'd bother as it seems like a lot of effort to code for marginal benefit, but if you wanted to then you could either check in each page or if you use Django you can decorate the view function or use whatever helper your framework gives you.
* You did specifically put any discussion of OTP resistance to attack out of scope, but I think that if you do use the OTP as a unique identifier then you should ask for the user's username/email address / phone number on the OTP page and you should take into account that OTPs are short (low entropy) and therefore you may want to prevent brute-force, you then use the combination of OTP + UID to identify the user. Obviously a short OTP is worse than a long passphrase so you will need to build controls against that but I won't go into those. If you want to go directly from the "forgot password" page then you can redirect after your "we have sent you a OTP code if we have your details" confirmation and you could use a server-side variable to ensure that you know the UID entered by the user who wants to reset their password, but as the forgot password page is public and you can't trust that user then I can't see any disadvantage to asking for the UID/email or even including it in the headers.