API Reference

Public auth API

These are the endpoints your application uses for sign-in, registration, PKCE token exchange, refresh rotation, logout, and current-user lookup. Dashboard and service APIs are intentionally excluded from this reference.

Base rules

Base path /api/v1/auth

Every endpoint below is served by the public Passport Auth web container.

PKCE Required for auth codes

Hosted and custom flows send a SHA-256 code challenge, then exchange with the verifier.

Redirects Exact allowlist

redirect_url must match one configured Redirect URL, except localhost in development.

Content-Type: application/json
Authorization: Bearer public_access_token   # only for GET /me
GET

/api/v1/auth/request/validate

Validate a hosted-page or custom-page request before showing a login UI.

Query

  • redirect_urlRequired. App callback URL that should receive the auth code.
  • code_challengeRequired. PKCE SHA-256 challenge, 32-256 chars.

200 response

{
  "ok": true,
  "redirect_url": "https://app.example.com/auth/callback"
}

Password registration and login

POST

/api/v1/auth/register

Start password registration. Passport Auth stores a pending registration, sends an email OTP, and does not create the user until verification succeeds.

Request body

  • nameRequired. Display name, 1-120 chars. Normalized to title case.
  • emailRequired. User email, normalized to lowercase.
  • passwordRequired. Minimum 12 chars.
  • redirect_urlRequired. Exact allowed callback URL.
  • code_challengeRequired. PKCE challenge for the later token exchange.

200 response

{
  "sent": true,
  "dev_otp": "482913",
  "dev_token": null,
  "dev_magic_link": null
}

dev_otp is only returned outside production.

POST

/api/v1/auth/register/verify

Verify the registration OTP, create the user, mark email verified, and issue an authorization code.

Request body

{
  "email": "[email protected]",
  "otp": "482913"
}

200 response

{
  "authorization_code": "pa_code_...",
  "redirect_url": "https://app.example.com/auth/callback"
}
POST

/api/v1/auth/password/login

Validate email and password for an existing active user, then issue an authorization code.

Request body

{
  "email": "[email protected]",
  "password": "correct-horse-battery-staple",
  "redirect_url": "https://app.example.com/auth/callback",
  "code_challenge": "S256_challenge"
}

200 response

{
  "authorization_code": "pa_code_...",
  "redirect_url": "https://app.example.com/auth/callback"
}

One-time passcode login

POST

/api/v1/auth/otp/start

Send a login OTP to the supplied email. If auto-create is enabled for OTP, verification can create the user.

{
  "email": "[email protected]",
  "redirect_url": "https://app.example.com/auth/callback",
  "code_challenge": "S256_challenge"
}

200 response

{ "sent": true, "dev_otp": "482913" }
POST

/api/v1/auth/otp/verify

Verify the OTP and issue an authorization code for the configured redirect URL.

{
  "email": "[email protected]",
  "otp": "482913",
  "redirect_url": "https://app.example.com/auth/callback",
  "code_challenge": "S256_challenge"
}

Password reset OTP

POST

/api/v1/auth/password-reset/start

Send a reset code if the user exists. The response is intentionally generic to avoid account enumeration.

{ "email": "[email protected]" }

200 response

{ "sent": true }
POST

/api/v1/auth/password-reset/confirm

Verify the reset OTP and replace the user's password.

{
  "email": "[email protected]",
  "otp": "482913",
  "password": "new-correct-horse-battery-staple"
}

200 response

{ "ok": true }

Google OAuth

GET

/api/v1/auth/google/start

Create a Google authorization URL after validating the configured redirect URL and PKCE challenge.

Query

redirect_url=https://app.example.com/auth/callback
code_challenge=S256_challenge

200 response

{ "authorization_url": "https://accounts.google.com/o/oauth2/v2/auth?..." }
GET

/api/v1/auth/google/callback

Google returns here. Passport Auth consumes the OAuth state, creates or updates the user using Google's email and name, then redirects back with ?code=.

Query

state=oauth_state
code=google_provider_code
response=redirect | json

Token exchange and sessions

POST

/api/v1/auth/token

Exchange an authorization code and PKCE verifier for a short-lived access token and a rotating refresh token.

Request body

{
  "code": "pa_code_...",
  "code_verifier": "original_pkce_verifier"
}

200 response

{
  "access_token": "jwt...",
  "refresh_token": "opaque_refresh_token",
  "token_type": "bearer",
  "expires_in": 7776000,
  "user": {
    "id": "user_id",
    "name": "Jane Appleseed",
    "email": "[email protected]",
    "role": "user",
    "email_verified": true,
    "user_metadata": {}
  }
}
POST

/api/v1/auth/refresh

Rotate a refresh token and return a new token pair. Replaying an old refresh token returns 401.

{ "refresh_token": "opaque_refresh_token" }
POST

/api/v1/auth/logout

Revoke the current refresh token. Your app should also clear local tokens.

{ "refresh_token": "opaque_refresh_token" }

200 response

{ "ok": true }
GET

/api/v1/auth/me

Return the current public auth user for the supplied access token.

Headers

Authorization: Bearer public_access_token

200 response

{
  "id": "user_id",
  "name": "Jane Appleseed",
  "email": "[email protected]",
  "role": "user",
  "email_verified": true,
  "user_metadata": {
    "plan": "pro",
    "subscription_status": "active"
  }
}

Errors

400

Invalid OTP, expired code, redirect mismatch, bad OAuth state, or malformed input.

401

Invalid password, expired refresh token, missing bearer token, or replayed refresh token.

403

User is blocked or deactivated. The response detail can include the configured block message.

404

The requested auth method is disabled in dashboard settings.

409

A user with the same email already exists during registration.

503

Email or provider configuration is unavailable, for example Resend or Google OAuth is not configured.