Skip to main content

🔑 Password Reset Explorer

Complete password recovery system testing. Help users regain access to their accounts securely.


🚀 Initiate Password Reset

Send a password reset email to the user:

POSThttps://api.swapbits.co/auth/forgot-password

Request password reset email

Parámetros

Email address of the account to reset

Comando cURL

curl -X POST 'https://api.swapbits.co/auth/forgot-password' \
  -H 'Content-Type: application/json'

🔐 Reset Password with Code

Complete the password reset using the code from email:

POSThttps://api.swapbits.co/auth/reset-password

Reset password using verification code

Parámetros

Email address of the account

6-digit code from reset email

New password (8+ chars, secure)

Comando cURL

curl -X POST 'https://api.swapbits.co/auth/reset-password' \
  -H 'Content-Type: application/json'

🔄 Change Password (Authenticated)

Change password when user knows current password:

POSThttps://api.swapbits.co/auth/change-password

Change password (requires authentication)

Autenticación

Parámetros

User's current password

New password to set

Comando cURL

curl -X POST 'https://api.swapbits.co/auth/change-password' \
  -H 'Content-Type: application/json'

Response Scenarios

Password Reset Request

✅ Reset Email Sent (Code 1000)

Reset email dispatched - Check inbox for reset code.

{
"code": 1000,
"message": "Password reset email sent",
"data": {
"email": "user@example.com",
"codeSent": true,
"expiresIn": 300,
"rateLimit": {
"remaining": 2,
"resetTime": "2024-01-15T11:00:00Z"
}
}
}

Important: Code expires in 5 minutes (300 seconds)

❌ Account Not Found (Code 4004)

Email not registered - No account found with this email.

{
"code": 4004,
"message": "Account not found",
"id": "error-trace-id"
}

Action: Check email spelling or register a new account

⚠️ Rate Limited (Code 4029)

Too many requests - Reset requests temporarily blocked.

{
"code": 4029,
"message": "Too many reset requests",
"data": {
"retryAfter": 180,
"maxAttempts": 3,
"windowMinutes": 15
},
"id": "error-trace-id"
}

Action: Wait 3 minutes before trying again

Password Reset Completion

✅ Password Reset Successful (Code 1006)

Password updated successfully - User can now login with new password.

{
"code": 1006,
"message": "Password reset successfully",
"data": {
"passwordChanged": true,
"sessionRevoked": true,
"loginRequired": true
}
}

Next step: Use Login Explorer with new password

❌ Invalid Reset Code (Code 4005)

Code verification failed - Code is incorrect, expired, or already used.

{
"code": 4005,
"message": "Invalid or expired reset code",
"data": {
"codeExpired": true,
"attemptsRemaining": 2
},
"id": "error-trace-id"
}

Action: Request a new reset code if expired, or check code accuracy

Password Change (Authenticated)

✅ Password Changed (Code 1006)

Password updated - Successfully changed while authenticated.

{
"code": 1006,
"message": "Password changed successfully",
"data": {
"passwordChanged": true,
"sessionMaintained": true,
"securityNotification": true
}
}

Note: Current session remains active, security email sent

❌ Current Password Incorrect (Code 4001)

Authentication failed - Current password is wrong.

{
"code": 4001,
"message": "Current password is incorrect",
"data": {
"attemptsRemaining": 4,
"lockoutWarning": false
},
"id": "error-trace-id"
}

Action: Verify current password or use forgot password flow


🔄 Complete Password Recovery Flow

Step-by-step Password Recovery

Forgot Password Flow:

  1. Request Reset → POST /auth/forgot-password with email address
  2. Check Email → Look for reset code in inbox (check spam folder)
  3. Note Expiration → Code expires in 5 minutes from receipt
  4. Reset Password → POST /auth/reset-password with email, code, and new password
  5. Login Again → All sessions revoked, login required with new password

Change Password Flow (When Authenticated):

  1. Authenticate → Ensure you have valid access token
  2. Verify Current → Know your current password for verification
  3. Change Password → POST /auth/change-password with old and new passwords
  4. Continue Session → Current session remains active

Security Features:

  • Reset codes expire in 5 minutes
  • Maximum 3 reset requests per 15-minute window
  • All user sessions revoked after password reset
  • Security notification emails sent for changes
  • Failed attempts are tracked and limited

💻 Integration Examples

JavaScript/TypeScript

Complete password management
interface PasswordResetManager {
requestReset(email: string): Promise<boolean>;
resetPassword(email: string, code: string, newPassword: string): Promise<boolean>;
changePassword(currentPassword: string, newPassword: string): Promise<boolean>;
}

class SwapBitsPassword implements PasswordResetManager {
private baseUrl = 'https://api.swapbits.co';
private accessToken?: string;

constructor(accessToken?: string) {
this.accessToken = accessToken;
}

async requestReset(email: string): Promise<boolean> {
const response = await fetch(`${this.baseUrl}/auth/forgot-password`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ email }),
});

const result = await response.json();

if (result.code === 1000) {
console.log(`Reset email sent to ${email}`);
console.log(`Code expires in ${result.data.expiresIn} seconds`);
console.log(`Remaining attempts: ${result.data.rateLimit.remaining}`);
return true;
} else if (result.code === 4029) {
throw new Error(`Rate limited. Retry after ${result.data.retryAfter} seconds`);
} else {
throw new Error(`Reset request failed: ${result.message} (Code: ${result.code})`);
}
}

async resetPassword(email: string, code: string, newPassword: string): Promise<boolean> {
// Validate password strength first
const validation = this.validatePassword(newPassword);
if (!validation.valid) {
throw new Error(`Password validation failed: ${validation.errors.join(', ')}`);
}

const response = await fetch(`${this.baseUrl}/auth/reset-password`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
email,
code,
newPassword,
}),
});

const result = await response.json();

if (result.code === 1006) {
console.log('Password reset successful');
console.log('All sessions have been revoked - please login again');
return true;
} else if (result.code === 4005) {
throw new Error(`Reset code invalid or expired. Attempts remaining: ${result.data.attemptsRemaining}`);
} else {
throw new Error(`Password reset failed: ${result.message} (Code: ${result.code})`);
}
}

async changePassword(currentPassword: string, newPassword: string): Promise<boolean> {
if (!this.accessToken) {
throw new Error('Authentication required for password change');
}

// Validate new password
const validation = this.validatePassword(newPassword);
if (!validation.valid) {
throw new Error(`Password validation failed: ${validation.errors.join(', ')}`);
}

const response = await fetch(`${this.baseUrl}/auth/change-password`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${this.accessToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
currentPassword,
newPassword,
}),
});

const result = await response.json();

if (result.code === 1006) {
console.log('Password changed successfully');
console.log('Security notification email sent');
return true;
} else if (result.code === 4001) {
throw new Error(`Current password incorrect. Attempts remaining: ${result.data.attemptsRemaining}`);
} else {
throw new Error(`Password change failed: ${result.message} (Code: ${result.code})`);
}
}

private validatePassword(password: string): { valid: boolean; errors: string[] } {
const errors: string[] = [];

if (password.length < 8) {
errors.push('Password must be at least 8 characters long');
}

if (!/[A-Z]/.test(password)) {
errors.push('Password must contain at least one uppercase letter');
}

if (!/[a-z]/.test(password)) {
errors.push('Password must contain at least one lowercase letter');
}

if (!/[0-9]/.test(password)) {
errors.push('Password must contain at least one number');
}

if (!/[!@#$%^&*(),.?":{}|<>]/.test(password)) {
errors.push('Password must contain at least one symbol');
}

return {
valid: errors.length === 0,
errors,
};
}
}

// Usage examples
const passwordManager = new SwapBitsPassword();

// Request password reset
try {
await passwordManager.requestReset('user@example.com');
console.log('Check your email for reset code');
} catch (error) {
console.error('Reset request failed:', error.message);
}

// Complete password reset
try {
const resetCode = prompt('Enter reset code from email:');
const newPassword = prompt('Enter new password:');

await passwordManager.resetPassword('user@example.com', resetCode, newPassword);
console.log('Password reset complete! Please login again.');
} catch (error) {
console.error('Password reset failed:', error.message);
}

// Change password (when authenticated)
const authenticatedManager = new SwapBitsPassword('your-access-token');

try {
const currentPass = prompt('Enter current password:');
const newPass = prompt('Enter new password:');

await authenticatedManager.changePassword(currentPass, newPass);
console.log('Password changed successfully!');
} catch (error) {
console.error('Password change failed:', error.message);
}

Python

Password management with Python
import requests
import re
import time
from typing import Dict, Any, List

class SwapBitsPassword:
def __init__(self, access_token: str = None):
self.base_url = 'https://api.swapbits.co'
self.access_token = access_token

def request_reset(self, email: str) -> bool:
"""Request password reset email"""
response = requests.post(
f'{self.base_url}/auth/forgot-password',
json={'email': email}
)
result = response.json()

if result['code'] == 1000:
print(f"Reset email sent to {email}")
print(f"Code expires in {result['data']['expiresIn']} seconds")
print(f"Remaining attempts: {result['data']['rateLimit']['remaining']}")
return True
elif result['code'] == 4029:
retry_after = result['data']['retryAfter']
raise Exception(f"Rate limited. Retry after {retry_after} seconds")
else:
raise Exception(f"Reset request failed: {result['message']} (Code: {result['code']})")

def reset_password(self, email: str, code: str, new_password: str) -> bool:
"""Complete password reset with verification code"""
# Validate password first
validation = self.validate_password(new_password)
if not validation['valid']:
raise ValueError(f"Password validation failed: {', '.join(validation['errors'])}")

response = requests.post(
f'{self.base_url}/auth/reset-password',
json={
'email': email,
'code': code,
'newPassword': new_password
}
)
result = response.json()

if result['code'] == 1006:
print("Password reset successful")
print("All sessions have been revoked - please login again")
return True
elif result['code'] == 4005:
attempts = result['data'].get('attemptsRemaining', 0)
raise Exception(f"Reset code invalid or expired. Attempts remaining: {attempts}")
else:
raise Exception(f"Password reset failed: {result['message']} (Code: {result['code']})")

def change_password(self, current_password: str, new_password: str) -> bool:
"""Change password when authenticated"""
if not self.access_token:
raise Exception('Authentication required for password change')

# Validate new password
validation = self.validate_password(new_password)
if not validation['valid']:
raise ValueError(f"Password validation failed: {', '.join(validation['errors'])}")

response = requests.post(
f'{self.base_url}/auth/change-password',
headers={'Authorization': f'Bearer {self.access_token}'},
json={
'currentPassword': current_password,
'newPassword': new_password
}
)
result = response.json()

if result['code'] == 1006:
print("Password changed successfully")
print("Security notification email sent")
return True
elif result['code'] == 4001:
attempts = result['data'].get('attemptsRemaining', 0)
raise Exception(f"Current password incorrect. Attempts remaining: {attempts}")
else:
raise Exception(f"Password change failed: {result['message']} (Code: {result['code']})")

def validate_password(self, password: str) -> Dict[str, Any]:
"""Validate password against security requirements"""
errors = []

if len(password) < 8:
errors.append('Password must be at least 8 characters long')

if not re.search(r'[A-Z]', password):
errors.append('Password must contain at least one uppercase letter')

if not re.search(r'[a-z]', password):
errors.append('Password must contain at least one lowercase letter')

if not re.search(r'[0-9]', password):
errors.append('Password must contain at least one number')

if not re.search(r'[!@#$%^&*(),.?":{}|<>]', password):
errors.append('Password must contain at least one symbol')

return {
'valid': len(errors) == 0,
'errors': errors
}

def complete_reset_flow(self, email: str) -> bool:
"""Complete reset flow with user interaction"""
try:
# Request reset
self.request_reset(email)

# Get code from user
code = input("Enter the 6-digit code from your email: ")

# Get new password
while True:
new_password = input("Enter your new password: ")
validation = self.validate_password(new_password)

if validation['valid']:
break
else:
print("Password requirements not met:")
for error in validation['errors']:
print(f" - {error}")
print()

# Complete reset
self.reset_password(email, code, new_password)
return True

except Exception as e:
print(f"Reset flow failed: {e}")
return False

# Usage examples
password_manager = SwapBitsPassword()

# Forgot password flow
try:
email = 'user@example.com'
password_manager.request_reset(email)
print("Check your email for reset code")

# Wait for user to get code, then complete reset
code = input("Enter reset code: ")
new_password = input("Enter new password: ")

password_manager.reset_password(email, code, new_password)
print("Password reset complete! Please login again.")

except Exception as e:
print(f"Password reset failed: {e}")

# Change password (when authenticated)
authenticated_manager = SwapBitsPassword('your-access-token')

try:
current_password = input("Enter current password: ")
new_password = input("Enter new password: ")

authenticated_manager.change_password(current_password, new_password)
print("Password changed successfully!")

except Exception as e:
print(f"Password change failed: {e}")

# Complete interactive reset flow
password_manager.complete_reset_flow('user@example.com')


🆘 Troubleshooting

🔧 Common Password Issues & Solutions

Problem: No reset email received Solution: Check spam folder, verify email spelling, ensure account exists

Problem: Reset code expired Solution: Request new reset code (codes expire in 5 minutes)

Problem: "Too many reset requests" Solution: Wait 15 minutes between attempts (3 max per window)

Problem: Current password rejected during change Solution: Verify current password or use forgot password flow

Problem: New password rejected Solution: Ensure 8+ chars with uppercase, lowercase, numbers, and symbols

Problem: Reset code not working Solution: Check for typos, ensure code wasn't already used, request new one if expired