Prompt

How do I send password reset emails from a backend app using an email API?

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

Latest observation

Jul 24, 2026 · OpenAI APIWeb search: off

To send password reset emails from a backend app using an email API, the usual flow is:

  1. User requests a password reset
  2. Your backend generates a secure, short-lived reset token
  3. Your backend stores or signs that token
  4. Your backend sends an email with a reset link using an email API
  5. User clicks the link and sets a new password
  6. Your backend verifies the token and updates the password

Recommended flow

1) Create a reset token

Use a cryptographically secure random token, not a guessable value.

Example:

  • Generate a random 32-byte token
  • Store a hashed version in your database
  • Set an expiration time, like 15–60 minutes

Why hash it?

  • If your database is leaked, raw reset tokens aren’t exposed.

2) Build a reset URL

Include the token in a link to your frontend or backend page:

https://yourapp.com/reset-password?token=RESET_TOKEN

3) Send the email via an email API

Use a provider such as:

  • SendGrid
  • Mailgun
  • Amazon SES
  • Postmark
  • Resend

Send an email with a clear subject and a single reset link.

4) Verify the token on reset

When the user submits a new password:

  • Look up the token
  • Check expiration
  • Ensure it hasn’t been used
  • Update the password hash
  • Invalidate the token immediately

Example using Node.js and SendGrid

Install

npm install @sendgrid/mail crypto

Backend code

const sgMail = require('@sendgrid/mail');
const crypto = require('crypto');

sgMail.setApiKey(process.env.SENDGRID_API_KEY);

// Simulated DB functions
async function saveResetToken(userId, tokenHash, expiresAt) {
  // store tokenHash, userId, expiresAt in DB
}

async function findUserByEmail(email) {
  // return user record from DB
}

function hashToken(token) {
  return crypto.createHash('sha256').update(token).digest('hex');
}

async function requestPasswordReset(email) {
  const user = await findUserByEmail(email);

  // Avoid revealing whether the email exists
  if (!user) return;

  const token = crypto.randomBytes(32).toString('hex');
  const tokenHash = hashToken(token);
  const expiresAt = new Date(Date.now() + 1000 * 60 * 30); // 30 minutes

  await saveResetToken(user.id, tokenHash, expiresAt);

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

  await sgMail.send({
    to: email,
    from: 'no-reply@yourapp.com',
    subject: 'Reset your password',
    text: `Click this link to reset your password: ${resetLink}`,
    html: `<p>Click this link to reset your password:</p><p><a href="${resetLink}">Reset Password</a></p>`,
  });
}

Reset endpoint example

async function resetPassword(token, newPassword) {
  const tokenHash = hashToken(token);

  // Find token in DB
  const record = await findResetToken(tokenHash);

  if (!record) {
    throw new Error('Invalid token');
  }

  if (new Date() > record.expiresAt) {
    throw new Error('Token expired');
  }

  // Hash the new password with bcrypt/argon2
  const passwordHash = await hashPassword(newPassword);

  await updateUserPassword(record.userId, passwordHash);
  await deleteResetToken(tokenHash); // one-time use
}

Security best practices

  • Use HTTPS
  • Make tokens random and single-use
  • Set short expiration times
  • Store only hashed tokens
  • Rate-limit reset requests
  • Don’t reveal whether an email exists
  • Invalidate all active sessions after password reset
  • Use a proper password hashing algorithm like bcrypt or Argon2
  • Add anti-abuse controls to prevent email spam

If you use Python / FastAPI

The same pattern applies:

  • secrets.token_urlsafe() for token generation
  • Store hashed token in DB
  • Send via provider SDK or SMTP/API
  • Verify and invalidate on reset

Common mistake

Don’t send the user’s password in email.
Only send a reset link or reset code.

If you want, I can also show:

  • a complete Express + SendGrid example
  • a Python/FastAPI + email API example
  • a version using AWS SES or Resend

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.