One-time-password authentication
Request and consume one-time passwords, then recover from invalid or expired codes.
Use one-time-password (OTP) authentication when an enabled auth collection can deliver a one-time code to the user's email. You need OTP enabled in the collection, working mail delivery, and a client initialized for the PocketBase URL.
This workflow leaves the client with a valid auth store after the reader submits the code from the current challenge. Start with the user's email and a client connected to the same auth collection that will process the response.
Complete an OTP sign-in
Submit the user's email to the auth collection.
const result = await pb.collection("users").requestOTP("reader@example.com");
console.log(result.otpId);PocketBase returns an otpId that identifies the pending challenge. Keep it with the sign-in attempt and show the user where to enter the emailed code. The response can contain an ID even when the email does not identify an existing user; do not use it to enumerate accounts.
Submit the returned otpId and the code from the email.
const authData = await pb.collection("users").authWithOTP(
result.otpId,
"123456",
);
console.log(pb.authStore.isValid, authData.record.id);On success, the client receives regular authentication data and the auth store becomes valid. By default, successful OTP validation marks the related user email as verified.
If another method returns an mfaId, pass that value with the OTP authentication request.
await pb.collection("users").authWithOTP(result.otpId, code, {
mfaId,
});The second successful method completes MFA and returns the regular authenticated response.
Recover from failed codes
The API returns Invalid or expired OTP when the OTP is expired, belongs to another collection, cannot be found, or the password is incorrect. Do not keep retrying the same code: request a new OTP, replace the stored otpId, and submit the new code. OTP verification also has an additional rate limit, so excessive attempts can be rejected.
pb.authStore.isValid and confirming that the returned record belongs to the expected auth collection.If the check is false, do not continue with authenticated requests or reuse a code after requesting a replacement. A successful check gives the application an authenticated record context for the next authorized request.
Troubleshoot an OTP attempt
If the API returns \Invalid or expired OTP\, compare the submitted code and \otpId\ with the latest request. Requesting another code replaces the challenge context, so discard the older identifier before trying again. If repeated verification attempts are rejected, wait for the additional rate limit to clear. If an MFA flow supplied an \mfaId\, include it on the OTP request so the second method can complete the same challenge.
Next steps
Review the Authentication model to choose between password, OTP, OAuth2, and MFA, then apply authorization with API rules and filters.