Prompt

How do I send password reset emails from an 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 an API, the usual flow is:

  1. User submits their email address
  2. Your backend verifies the account exists
  3. Backend generates a secure, single-use reset token
  4. Backend stores a hashed version of that token with an expiration time
  5. Backend sends an email containing a reset link with the token
  6. User clicks the link and sets a new password
  7. Backend verifies token, updates password, and invalidates the token

Typical API endpoints

1) Request a reset email

POST /auth/password-reset-request

Body

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

Behavior

  • Always return a generic success response like:
{
  "message": "If an account exists, a reset email has been sent."
}
  • This avoids revealing whether the email is registered

2) Confirm reset with token

POST /auth/password-reset-confirm

Body

{
  "token": "reset-token-from-email",
  "newPassword": "NewStrongPassword123!"
}

Behavior

  • Validate token
  • Check expiration
  • Hash and store the new password
  • Invalidate the token after use

How to generate the token

Use a cryptographically secure random token, for example:

  • 32 bytes random
  • URL-safe encoded

Example conceptually:

  • generate token
  • store hash(token) in DB
  • email the raw token in a link

Why hash it?
If your database is compromised, attackers shouldn’t be able to use raw reset tokens.


Example email link

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

Or if you use a frontend app:

https://app.yourdomain.com/reset-password?token=abc123...

Important security practices

  • Do not send the new password by email
  • Do not include sensitive user info in the email
  • Use HTTPS only
  • Make tokens:
    • random
    • single-use
    • short-lived, e.g. 15–60 minutes
  • Rate-limit reset requests
  • Return the same response whether or not the email exists
  • Invalidate all existing sessions after password reset if appropriate
  • Consider logging password reset events for auditing

Example implementation outline

Request handler

// POST /auth/password-reset-request
const token = crypto.randomBytes(32).toString("hex");
const tokenHash = sha256(token);

saveResetTokenToDB(user.id, tokenHash, Date.now() + 3600000); // 1 hour

sendEmail(user.email, `
  Click here to reset your password:
  https://yourapp.com/reset-password?token=${token}
`);

Confirm handler

// POST /auth/password-reset-confirm
const tokenHash = sha256(req.body.token);
const record = findResetToken(tokenHash);

if (!record || record.expiresAt < Date.now()) {
  return res.status(400).json({ message: "Invalid or expired token" });
}

const passwordHash = hashPassword(req.body.newPassword);
updateUserPassword(record.userId, passwordHash);
deleteResetToken(record.id); // single-use

If you’re using an email service

You can send the email through:

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

If you want, I can also give you:

  • a Node.js/Express example
  • a Python/FastAPI example
  • a Laravel example
  • or a database schema for 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.