auth

Forgot Password

Begin a password reset (SEC-AUTH-013).

ALWAYS returns 202 with the same generic body regardless of whether the email resolves to an account — no enumeration via status, body, or shape. When the email DOES resolve to an email/password account, we mint a single-use, 1h, hashed-at-rest reset token and email a link; we also emit password_reset_requested.

Accounts with no password_hash (GitHub-OAuth-only) are treated as "no account to reset" — we don't send a reset link for a password that doesn't exist, but we still return the identical generic body.

Rate-limited via the middleware auth bucket (see rate_limiter _categorize_request) so the email-send can't be used to mail-bomb a victim or brute-probe the user table.

Anti-enumeration timing (security-auditor finding): the email send is a multi-hundred-ms Resend round-trip in prod. If we awaited it inline, the exists branch would return measurably slower than the unknown/OAuth-only branch — a timing oracle that re-enables enumeration despite the identical response shape. So the send is dispatched as a BackgroundTask, which runs AFTER the response is flushed; both branches return on the same fast timeline (the in-request work is only a sub-ms token mint + audit insert).

post/api/v1/auth/forgot-password

Request

  • Base URL: https://api.badgeia.com
  • URL: https://api.badgeia.com/api/v1/auth/forgot-password
  • Auth: none declared

Request body

emailstring email required

Response

Successful Response

object required

Changes

No recorded changes to this operation across all 1 revision of this API.