Documentation Index
Fetch the complete documentation index at: https://docs.hawcx.com/llms.txt
Use this file to discover all available pages before exploring further.
Hawcx Web SDK API Reference
Core Methods
initialize(apiKey, baseUrl?, options?)
Initialize the Hawcx SDK. Must be called before any other methods.
Parameters:
apiKey (string, required) - Your Hawcx API key
baseUrl (string, optional) - Base URL for Hawcx API (default: https://api-beta.hawcx.com)
options (object, optional)
cryptoVersion (string) - Crypto version, default: 'v1'
timeoutMs (number) - Request timeout in milliseconds, default: 15000
Returns: Promise<Object>
{
status: 'INITIALIZED',
message: 'Successfully initialized',
success: true
}
Example:
import { HawcxInitializer } from 'https://drprpwzor5vmy.cloudfront.net/v1.1.55/hawcx-auth.esm.min.js';
const hawcx = await HawcxInitializer.init('YOUR_API_KEY', "your-base-url");
if (hawcx.status === 'INITIALIZED') {
// SDK is ready to use
}
Authentication
authenticate(userid, options?)
Start authentication for a user. Returns different statuses based on device registration and MFA setup.
Parameters:
userid (string) - User email address
options (object, optional)
rememberDevice (boolean) - Remember device for future logins
code_challenge (string) - PKCE code challenge (if using PKCE)
code_challenge_method (string) - PKCE method (e.g., ‘S256’)
Returns: Promise<Object> with possible statuses:
Status: SUCCESS (Trusted device, no verification needed)
{
status: 'SUCCESS',
message: 'Authentication successful',
success: true,
code: 'authorization_code_string' // Send to backend
}
Status: OTP_NEEDED (New device registration)
{
status: 'OTP_NEEDED',
message: 'This device is not registered with your account. Please verify your identity.',
deviceToken: 'token_string',
code: '123456' // OTP sent to email (test mode only)
}
Status: MFA_REQUIRED (Device registered, MFA enabled)
{
status: 'MFA_REQUIRED',
message: 'Additional verification required',
sessionId: 'session_id_string',
method: 'email|sms|totp'
}
Example:
const response = await hawcx.authenticate('user@example.com');
if (response.status === 'SUCCESS') {
// Send authorization code to backend
await exchangeCodeWithBackend(response.code);
} else if (response.status === 'OTP_NEEDED') {
// Show OTP verification screen
showOtpInput();
} else if (response.status === 'MFA_REQUIRED') {
// Start MFA verification
await hawcx.initiateMfa({
userid: 'user@example.com',
sessionId: response.sessionId
});
}
Registration Flow
verifyEmailOtp({ userid, otp })
Verify email OTP during device registration.
Parameters:
userid (string) - User email address
otp (string) - 6-digit OTP from email
Returns: Promise<Object>
{
status: 'SUCCESS',
message: 'Email verified successfully'
}
Example:
const result = await hawcx.verifyEmailOtp({
userid: 'user@example.com',
otp: '123456'
});
verifyDevice({ userid, mfaMethod })
Finalize device registration and set up MFA method.
Parameters:
userid (string) - User email address
mfaMethod (string) - MFA method to enable: 'email', 'sms', or 'totp' (optional - skip MFA if not provided)
Returns: Promise<Object> with status SUCCESS or DEVICE_REGISTERED
{
status: 'SUCCESS' | 'DEVICE_REGISTERED',
message: 'Device registered successfully',
code: 'authorization_code_string'
}
Example:
const result = await hawcx.verifyDevice({
userid: 'user@example.com',
mfaMethod: 'sms' // 'email', 'sms', or 'totp'
});
if (result.status === 'SUCCESS' || result.status === 'DEVICE_REGISTERED' || result.code) {
// Send authorization code to backend
await exchangeCodeWithBackend(result.code);
}
MFA Flow
initiateMfa({ userid, sessionId })
Start MFA verification for users with MFA enabled.
Parameters:
userid (string) - User email address
sessionId (string) - Session ID from authenticate() response
Returns: Promise<Object>
{
status: 'MFA_INITIATED',
message: 'MFA challenge initiated'
}
verifyMfa({ userid, otp, remember_me? })
Verify MFA code and complete authentication.
Parameters:
userid (string) - User email address
otp (string) - 6-digit OTP from MFA method
remember_me (boolean, optional) - Remember this device for future logins
Returns: Promise<Object>
{
status: 'SUCCESS',
message: 'Authentication successful',
success: true,
code: 'authorization_code_string' // Send to backend
}
Example:
const result = await hawcx.verifyMfa({
userid: 'user@example.com',
otp: userProvidedOtp,
remember_me: true
});
if (result.status === 'SUCCESS') {
// Send authorization code to backend
await exchangeCodeWithBackend(result.code);
}
import { exchangeCodeForClaims } from '@hawcx/oauth-client';
app.post('/api/login', async (req, res) => {
try {
const { code, userid } = req.body;
// Validate code with Hawcx
const claims = await exchangeCodeForClaims({
code,
oauthTokenUrl: process.env.OAUTH_TOKEN_ENDPOINT,
clientId: process.env.OAUTH_CLIENT_ID,
publicKey: process.env.OAUTH_PUBLIC_KEY,
apiKey: process.env.HAWCX_API_KEY,
code_verifier: req.body.code_verifier // PKCE if used
});
// Create your own session
const sessionToken = jwt.sign(
{ userId: claims.sub, email: claims.email },
process.env.SESSION_SECRET,
{ expiresIn: '7d' }
);
res.json({ success: true, sessionToken });
} catch (error) {
res.status(401).json({ error: 'Authentication failed' });
}
});
from hawcx_oauth_client import exchange_code_for_claims
import os, jwt
from datetime import datetime, timedelta
@app.route('/api/login', methods=['POST'])
def login():
try:
data = request.get_json()
code = data.get('code')
# Validate code with Hawcx
claims = exchange_code_for_claims(
code=code,
oauth_token_url=os.getenv('OAUTH_TOKEN_ENDPOINT'),
client_id=os.getenv('OAUTH_CLIENT_ID'),
public_key=os.getenv('OAUTH_PUBLIC_KEY'),
api_key=os.getenv('HAWCX_API_KEY'),
code_verifier=data.get('code_verifier') # PKCE if used
)
# Create your own session
session_token = jwt.encode(
{
'userId': claims['sub'],
'email': claims['email'],
'exp': datetime.utcnow() + timedelta(days=7)
},
os.getenv('SESSION_SECRET'),
algorithm='HS256'
)
return jsonify({'success': True, 'sessionToken': session_token})
except Exception as error:
return jsonify({'error': 'Authentication failed'}), 401
All Response Status Codes
authenticate() Statuses
| Status | Meaning | Next Action |
|---|
SUCCESS | User authenticated on trusted device | Send code to backend |
OTP_NEEDED | New device - email OTP verification required | Call verifyEmailOtp() with OTP |
MFA_REQUIRED | Device registered with MFA enabled | Call initiateMfa() then verifyMfa() |
INVALID_EMAIL | Invalid email format | Show error, retry with valid email |
verifyEmailOtp() Statuses
| Status | Meaning | Next Action |
|---|
SUCCESS | Email OTP verified successfully | Call verifyDevice() to finalize registration |
verifyDevice() Statuses
| Status | Meaning | Next Action |
|---|
SUCCESS | Device registered successfully | Send code to backend |
DEVICE_REGISTERED | Device registered, re-authenticate | Call authenticate() again |
MFA_ENROLLMENT_NEEDED | Email verified, offer MFA setup | Call verifyDevice() with mfaMethod |
FINALIZE_REGISTRATION_NEEDED | Device registration finalizing | Continue device registration flow |
initiateMfa() Statuses
| Status | Meaning | Next Action |
|---|
MFA_INITIATED | MFA challenge initiated | Call verifyMfa() with OTP |
verifyMfa() Statuses
| Status | Meaning | Next Action |
|---|
SUCCESS | MFA verified successfully | Send code to backend |
Complete Registration Flow Example
// Step 1: Start authentication (new device)
const response = await hawcx.authenticate('user@example.com');
if (response.status === 'OTP_NEEDED') {
// Step 2: User enters email OTP
const emailOtpResult = await hawcx.verifyEmailOtp({
userid: 'user@example.com',
otp: userEmailOtp
});
// Step 3: Complete device registration with MFA
const deviceResult = await hawcx.verifyDevice({
userid: 'user@example.com',
mfaMethod: 'sms' // email, sms, or totp
});
if (deviceResult.status === 'SUCCESS' | deviceResult.code) {
// Send code to backend
const backendResponse = await fetch('/api/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
code: deviceResult.code,
userid: 'user@example.com'
})
});
const { sessionToken } = await backendResponse.json();
localStorage.setItem('sessionToken', sessionToken);
// User is now authenticated
}
}
Complete Login Flow with MFA
// Step 1: Start authentication
const response = await hawcx.authenticate('user@example.com');
if (response.status === 'MFA_REQUIRED') {
// Step 2: Initiate MFA
await hawcx.initiateMfa({
userid: 'user@example.com',
sessionId: response.sessionId
});
// Step 3: Verify MFA code
const mfaResult = await hawcx.verifyMfa({
userid: 'user@example.com',
otp: userMfaOtp,
remember_me: true
});
if (mfaResult.status === 'SUCCESS') {
// Send code to backend
const backendResponse = await fetch('/api/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
code: mfaResult.code,
userid: 'user@example.com'
})
});
const { sessionToken } = await backendResponse.json();
localStorage.setItem('sessionToken', sessionToken);
}
}
Best Practices
- Always validate on backend - Never trust the authorization code on frontend
- Handle all response statuses - Different status codes require different UX flows
- Store authorization code safely - Send immediately to backend, don’t store in localStorage
- Use HTTPS only - Authentication must occur over HTTPS
- Implement PKCE - For enhanced security, especially with mobile and SPAs
- Add proper error handling - Display user-friendly error messages for failures
Support