---
# System prepended metadata

title: External 2FA Server

---

# External 2FA Server

## User flows

#### Setting up the 2FA SMS for the first time

```
/**
 *  REGISTER THE USER.
 */

const payload = {
    pubKey: <tkey_pub_key>
    sig: <signed_using_tkey_priv_key and hash of number>
    // number should be in +{country_code}-{number} format.
    identifier: <number> 
}
const result = await register(payload);

// check if the user is already registered.
if (result.registered) {
    // user is already registered.
    return;
}

/**
 *  INITIATE THE VERIFICATION PROCESS.
 */
const result = await start(payload);
saveInSesssionStorage(tracking_id, result.tracking_id);

/**
 *  VERIFY THE USER & COMPLETE SMS 2FA SETUP PROCESS.
 */
// create a new factor key to setup data in the database.
const factorKey = new generatePrivate().toString(16, 64)

// get the trackingId from sessionStorage and call /verify API.
const res = await verify({ data: { factorKey }, code, address, tracking_id });

// if successfull, add this factorKey and share info in tkey instance.
await coreKitInstance.addFactorKey(factorKey, metadata)
deleteInSessionStorage(tracking_id);

```

### Recover your account on a new device using sms.
```
/**
 *  INITIATE THE VERIFICATION PROCESS.
 */
const result = await start(payload);
saveInSesssionStorage(tracking_id, result.tracking_id);

/**
 *  VERIFY THE USER & RECOVER ACCOUNT USING THE FACTOR KEY.
 */
// get the trackingId from sessionStorage and call /verify API.
const res = await verify({ code, address, tracking_id });

// if successfull, get the factor key from the response.
const factorKey = JSON.parse(res.data).factorKey;
await coreKitInstance.inputFactorKey(factorKey)
await coreKitInstance.reconstructTkey()
deleteInSessionStorage(tracking_id);

```

## APIs

### Base Url

https://api-external-safeauth.web3auth.com

### Register the user number

This API is called when user is initiating the sms 2fa for the **first time**.

Endpoint: POST {BASE_API_URL}/api/v1/:factor_type/register

**Request Params**
```
export type FACTOR_TYPE = 'sms' | 'authenticator'
```

**Request Body**
```
export interface IRegisterRequestBody {
    pubKey: {
        x: string;
        y: string;
    };
    sig: {
        r: string;
        s: string;
        v: string;
    }
    identifier: string;
}
```

**Response**
```
export interface IRegisterResponse {
    // true if the request is handled completely.
    success: boolean; 
    
    // true, if the number is already registered for the address.
    registered: boolean;
    
    // generic message or description of error if any.
    message: string;
}
```

**Sample Request Body Code**
```
// sample code to generate the pubKey and sig for the request body.
// privkey should always be unique to a user.
// tkeyPrivKey from the core kit sdk could be used here.
const ec = getEcCrypto();
const privKeyPair: ec.KeyPair = ec.keyFromPrivate(privKey.toString(16, 64));
const pubKey = privKeyPair.getPublic();
const sig = ec.sign(keccak256(Buffer.from(number, "utf8")), Buffer.from(privKey.toString(16, 64), "hex"));
```

### Initiate the verification process.

This API is called when you want to send a verification code to the user number.

*NOTE: This could be used to resend a verification code also but with the same tracking_id.*

**Endpoint:** POST {BASE_API_URL}/api/v1/:factor_type/start

**Request Params**
```
// This only supports sms currently.
// This API is not required for setting up authenticator factor.
export type FACTOR_TYPE = 'sms'
```

**Request**
```
export interface IStartRequestBody {
    // `${pubKey.x.toString(16, 64)}{pubkey.y.toString(16, 64)}`
    address: string;
    
    // web3auth client id.
    client_id: string;  
    
    // This is the value you get from the first /start response body.
    // Save this in session storage.
    // Send this value in next /start requests (page reload, resend code, verify).
    // It helps the backend to identify a unique verification session.
    tracking_id?: string;
}
```

**Response**
```
export interface IStartResponseBody {
    // true if the request is handled completely.
    success: boolean; 
    
    // unique sms verification session identifier.
    // save this in session storage for further use.
    tracking_id?: string;
    
    // error code, could be used to handle error messages on the UI.
    error_code?: string;
    
    // description of error if any.
    message?: string;
}
```

### Verify the number

Call this api if you want to verify the user number using the code entered by the user.

*Note: If the user is setting up the sms factor for the first time, then also send the factorKey with this, so that you can get the factor key from the database.*

**Endpoint:** POST {BASE_API_URL}/api/v1/:factor_type/verify

**Request Params**
```
export type FACTOR_TYPE = 'sms' | 'authenticator'
```

**Request Body**
```
export interface IVerifyRequestBody {
    // `${pubKey.x.toString(16, 64)}{pubkey.y.toString(16, 64)}`
    address: string;
    
    // web3auth client id.
    client_id: string;  
    
    // Get it from the session storage, saved previously from the /start request.
    tracking_id: string;
    
    // unique identifier, entered by the user
    code: string;
    
    // custom metadata you want to set with the user.
    // this is only for the first time, when user is setting up the MFA for the first time.
    // Send the factorKey in this, which could be in raw format or encrypted using the postbox key.
    // This can always be updated in the future as well.
    data?: string;
}
```

**Response**
```
export interface IVerifyResponseBody {
    // true if the request is handled completely.
    success: boolean; 
    
    // if success is true, then data will be there.
    // It's the same as the data you set previous /verify requests.
    data: string;
    
    // error code, could be used to handle error messages on the UI.
    error_code?: string;
    
    // description of error if any.
    message?: string;
}
```

## Error Codes

Coming soon...




