Prompt

How do I send a password reset email from a backend API?

Technology · API Platforms / Api platforms1 observationLast seen Jul 24, 2026

Latest observation

Jul 24, 2026 · OpenAI APIWeb search: off

To send a password reset email from a backend API, the usual flow is:

  1. User requests a reset

    • They submit their email address to an endpoint like POST /auth/forgot-password.
  2. Backend verifies the account exists

    • If the email is registered, generate a secure random reset token.
    • Store a hashed version of that token in your database, along with:
      • user ID
      • expiration time
      • whether it’s been used
  3. Send an email with a reset link

    • The email should contain a link like:
      • https://your-frontend.com/reset-password?token=...
    • The token in the URL should be the raw token, not the hash.
  4. User clicks the link and sets a new password

    • Frontend sends the token + new password to something like POST /auth/reset-password.
  5. Backend validates the token

    • Check:
      • token exists
      • token not expired
      • token not used
    • If valid, update the user’s password and invalidate the token.

Example backend flow

1) Request reset endpoint

POST /auth/forgot-password

Input:

{ "email": "user@example.com" }

Backend:

  • find user
  • generate token
  • save hashed token + expiry
  • send email

2) Generate token securely

In Node.js:

import crypto from "crypto";

const token = crypto.randomBytes(32).toString("hex");
const tokenHash = crypto.createHash("sha256").update(token).digest("hex");

Store tokenHash, not token.


3) Send the email

Use an email provider like:

  • SendGrid
  • Mailgun
  • SES
  • Postmark
  • Nodemailer with SMTP

Example email content:

Click here to reset your password:
https://yourapp.com/reset-password?token=RAW_TOKEN

Important security practices

  • Never send the password in email
  • Never store reset tokens in plain text
  • Make tokens expire quickly, e.g. 15–60 minutes
  • Make tokens single-use
  • Return a generic response even if the email doesn’t exist, so attackers can’t enumerate accounts:
    • "If the email exists, we sent a reset link."
  • Use HTTPS
  • Rate-limit reset requests
  • Invalidate existing sessions after password reset

Example API responses

For POST /auth/forgot-password:

{ "message": "If the email exists, a reset link has been sent." }

For POST /auth/reset-password:

{ "message": "Password reset successful." }

Minimal Node.js example

import crypto from "crypto";

app.post("/auth/forgot-password", async (req, res) => {
  const { email } = req.body;

  const user = await db.users.findOne({ email });
  if (!user) {
    return res.json({ message: "If the email exists, a reset link has been sent." });
  }

  const token = crypto.randomBytes(32).toString("hex");
  const tokenHash = crypto.createHash("sha256").update(token).digest("hex");

  await db.passwordResets.insertOne({
    userId: user._id,
    tokenHash,
    expiresAt: new Date(Date.now() + 1000 * 60 * 30), // 30 min
    used: false
  });

  const resetUrl = `https://yourapp.com/reset-password?token=${token}`;

  await sendEmail(user.email, "Reset your password", `
    Click this link to reset your password:
    ${resetUrl}
  `);

  res.json({ message: "If the email exists, a reset link has been sent." });
});

If you want, I can also show you:

  • a full Node/Express example
  • a NestJS example
  • a Python/FastAPI example
  • or how to do this with JWT reset tokens

Observation history

Unlock observation history

Create a free Obsurfable account to unlock historical responses, model comparisons, and deeper brand intelligence.

How did Obsurfable measure this prompt?

Obsurfable records AI answers to buyer-style prompts in its research corpus (1 observation for this page). Metrics are distributions over observations, not a single static ranking.

Which AI systems does Obsurfable collect answers from?

OpenAI, ChatGPT, Google, Gemini, Google AI Mode, Anthropic, Claude, Perplexity, Grok, DeepSeek, Mistral, Copilot, and Meta AI.