Account Recovery & Device Rotation
TryMellon follows a strictly B2B posture: we never store or command your users’ personal data. Recovery is initiated from your server — you own the relationship with the user; we handle the cryptography.
How it works
- Your backend identifies the user and calls TryMellon to dispatch an OTP via email.
- The user receives a 6-digit code.
- Your frontend calls
client.auth.recoverAccount()with the OTP — the SDK verifies the code, prompts the OS for a new passkey, and returns a fresh session token.
1. Server-to-Server: start recovery
When a user requests account recovery (e.g. via a “Lost phone” form), your backend must call TryMellon’s recovery endpoint. The email is used ephemerally for the OTP and not stored.
// Your backend — POST to TryMellon API
const response = await fetch('https://api.trymellonauth.com/v1/users/recovery/start', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_SECRET_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
external_user_id: 'usr_123A',
email: 'customer@domain.com',
}),
});
2. Client-side: rotate the device
Once the user receives the 6-digit OTP, call recoverAccount from the SDK. This verifies the OTP, triggers a WebAuthn registration ceremony for a new passkey, and returns a session token.
import { TryMellon } from '@trymellon/js';
const clientResult = TryMellon.create({ appId: 'YOUR_APP_ID', publishableKey: 'cli_xxxx' });
if (!clientResult.ok) throw clientResult.error;
const client = clientResult.value;
// When the user submits the 6-digit OTP
const result = await client.auth.recoverAccount({
externalUserId: 'usr_123A',
otp: '632145',
});
if (result.ok) {
console.log('Device rotated securely!');
// Send result.value.sessionToken to your backend to set session
await fetch('/api/auth/set-session', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ sessionToken: result.value.sessionToken }),
});
}
if (!result.ok) {
console.error(result.error.code, result.error.message);
// Handle: INVALID_ARGUMENT (bad OTP format), NETWORK_FAILURE, etc.
}
RecoverAccountOptions
| Field | Type | Description |
|---|---|---|
externalUserId | string (required) | The external user ID of the account being recovered. |
otp | string (required) | The 6-digit OTP sent via email. |
RecoverAccountResult
| Field | Type | Description |
|---|---|---|
success | true | Always true on success. |
credentialId | string | The new passkey credential ID. |
status | string | Registration status. |
sessionToken | string | Fresh session token — send to your backend. |
user.userId | string | TryMellon internal user ID. |
user.externalUserId | string? | Your external user ID. |
user.email | string? | User email if available. |
redirectUrl | string? | Set when successUrl was passed and allowed. |
Security standards
- Rate limits: Maximum 3 OTPs per hour to prevent brute-force.
- Idempotency: OTP generation is debounced to 60 seconds.
- Revocation: Previous cryptographic keys are immediately invalidated — lost devices cannot authenticate.