Web

Learn how to get started with Truv for your web application

Setup for web app

The easiest way to get started with Truv is to run the Quickstart. The Quickstart shows the entire workflow from initializing Bridge to retrieving data. It contains code examples in some of the most popular languages (C#, Go, NodeJS, Python and Ruby) and is open source.

Run the code below to setup Quickstart.

# Clone the Quickstart repository
git clone https://github.com/truvhq/quickstart.git

# Open Quickstart
cd quickstart

# Create .env file 
make env

# Update the values in .env file by adding in your Client ID and Sandbox Access key. 
#API_CLIENT_ID=<Your Client ID here>
#API_SECRET=<Your Access key here>

# Also, in .env uncomment the line with API_PRODUCT_TYPE that you want to use
#API_PRODUCT_TYPE=employment

# Run the make script for your coding language
make python_local
# Clone the Quickstart repository
git clone https://github.com/citadelid/quickstart.git
# Open Quickstart in your coding language
cd quickstart/python
# Copy the .env.example file to a new file in the same directory and name it .env. 
cp .env.example .env
# Update the values adding in the your Client ID and Sandbox Access key. 
#API_CLIENT_ID=<Your Client ID here>
#API_SECRET=<Your Access key here>
# Uncomment the line with API_PRODUCT_TYPE that you want to use
#API_PRODUCT_TYPE=employment
#Run the make script for your coding language
make python_docker

Run Quickstart

Visit http://localhost:5000 to view the Quickstart application. Click the "Connect" button and follow the instructions in Bridge. Your sandbox environment is designed to allow you to log in with multiple different credentials that give you different data scenarios. You can view the different credentials available in Sandbox.

When you click "Done" at the end of Bridge session you will be able to see the data returned by the Truv.

Step-by-step overview

Console logs have been added to both the front end and back end of Quickstart to give you a good idea of the process an application runs through, but here's a basic explanation of the flow Quickstart (and most applications) follows. This flow involves a user, the application front end, the application back end and the Truv. You can see a visual diagram of tokens and data exchange in Bridge section of docs.

1. Authorize and initialize Bridge

Truv Bridge is the client-side component that your users will interact with in order to link their accounts to Truv and allow you to access their accounts via the Truv. When the page loads, the applicant front end sends a request to the application back end for a bridge_token. This token is required to authorize the application front end to use Bridge.

const getBridgeToken = async () => {
    const response = await fetch(apiEnpoint + `getBridgeToken`, {
      method: 'get',
      headers,
    }).then((r) => r.json());
    return response;
  }

The application back end sends a request to the Truv for a bridge_tokenbridge_token - A short-lived token provided by the Truv to authorize the use of Bridge. This token has a 6 hour expiration. and sends the response to the application front end. It's necessary to request the bridge_tokenbridge_token - A short-lived token provided by the Truv to authorize the use of Bridge. This token has a 6 hour expiration. from the application back end because the Client IDClient ID - The unique identifier passed into the X-Access-Client-Id header of every API request to authorize it. and Access keyAccess key - The unique key passed into the X-Access-Secret header of every API request to authorize it. are required to authorize the request.

❗️

Never place or use your Client ID or Access key in your application's front end.

def get_bridge_token(self) -> Any:
        """
        https://docs.truv.com/?python#bridge-tokens_create
        :param public_token:
        :return:
        """
        logging.info("TRUV: Requesting bridge token from https://prod.truv.com/v1/bridge-tokens")
        class BridgeTokenRequest(TypedDict):
            product_type: str
            client_name: str
            tracking_info: str
        request_data: BridgeTokenRequest = {
            'product_type': self.PRODUCT_TYPE,
            'client_name': 'Truv Quickstart',
            'tracking_info': '1337'
        }
        tokens: Any = requests.post(
            self.API_URL + 'bridge-tokens/',
            json=request_data,
            headers=self.API_HEADERS,
        ).json()
        return tokens

The application front end runs TruvBridge.init, passing the bridge_tokenbridge_token - A short-lived token provided by the Truv to authorize the use of Bridge. This token has a 6 hour expiration. returned from the application back end and assigning callback functions.

@app.route('/getBridgeToken', methods=['GET'])
def create_bridge_token():
    """Back end API endpoint to request a bridge token"""
    return api_client.get_bridge_token()
const bridge = TruvBridge.init({
  bridgeToken: bridgeToken.bridge_token,
  onLoad: function() { ... },
  onSuccess: function(public_token, meta) { ... },
  onEvent: function(event_type, payload) { ... },
  onClose: function() { ... }
});
window.bridge = bridge;

2. User connects account

The user clicks the "Connect" button. The application front end displays Bridge, which executes the onLoad callback function.

onLoad: function () {
  console.log('loaded');
  successClosing = null
},

The user follows the instructions in Bridge and connects their account. Bridge executes the onSuccess callback function, which sends a request to the application back end with a public_tokenpublic_token - A short-lived token used to exchange for an *access_token* from the backend. This token has a 6 hour expiration.. Bridge also closes.

onSuccess: async function (token) {
  console.log('token: ', token);
  successClosing = true
  const content = document.querySelector('.spinnerContainer');
  content.classList.remove('hidden');
  let verificationInfo;
  try {
    verificationInfo = await apiRequests.getVerificationInfoByToken(token);
  } catch(e) {
    console.error(e)
    content.classList.add('hidden');
    return;
  }
  content.classList.add('hidden');
  if (!verificationInfo.length) {
    return;
  }
  setUserInfo(verificationInfo[0]);
  renderEmploymentHistory(verificationInfo);
},
...
onClose: function () {
  console.log('closed');
  if (successClosing !== true) {
    renderEmploymentHistory([{ company: { address: {} } }]);
  }
},

3. Get data from API

The application back end sends a request to the Truv, exchanging the public_tokenpublic_token - A short-lived token used to exchange for an *access_token* from the backend. This token has a 6 hour expiration. passed by Bridge for an access_tokenaccess_token - A private token unique to a single Link. Used to access Link data and initiate any actions using the same Link. While the public_tokenpublic_token - A short-lived token used to exchange for an *access_token* from the backend. This token has a 6 hour expiration. is temporary and is only used to exchange for an access_tokenaccess_token - A private token unique to a single Link. Used to access Link data and initiate any actions using the same Link, the access_tokenaccess_token - A private token unique to a single Link. Used to access Link data and initiate any actions using the same Link is permanent and can be stored to retrieve data at a later point.

📘

public_token is temporary and expires after 6 hours

def get_access_token(self, public_token: str) -> str:
        """
        https://docs.truv.com/?python#exchange-token-flow
        :param public_token:
        :return:
        """
        logging.info("TRUV: Exchanging a public_token for an access_token from https://prod.truv.com/v1/link-access-tokens")
        logging.info("TRUV: Public Token - %s", public_token)
        class AccessTokenRequest(TypedDict):
            public_token: str
        class AccessTokenResponse(TypedDict):
            access_token: str
            link_id: str
        request_data: AccessTokenRequest = {
            'public_token': public_token,
        }
        tokens: AccessTokenResponse = requests.post(
            self.API_URL + 'link-access-tokens/',
            json=request_data,
            headers=self.API_HEADERS,
        ).json()
        return tokens['access_token']

The application back end sends a request for data to the Truv with the access_tokenaccess_token - A private token unique to a single Link. Used to access Link data and initiate any actions using the same Link.

def get_employment_info_by_token(self, access_token: str) -> Any:
    """
    https://docs.truv.com/#employment-verification
    :param access_token:
    :return:
    """

    class VerificationRequest(TypedDict):
        access_token: str

    request_data: VerificationRequest = {'access_token': access_token}
    return requests.post(
        self.API_URL + 'verifications/employments/',
        json=request_data,
        headers=self.API_HEADERS,
    ).json()
      
    
def get_income_info_by_token(self, access_token: str) -> Any:
    """
    https://docs.truv.com/#income-verification
    :param access_token:
    :return:
    """

    class VerificationRequest(TypedDict):
        access_token: str

    request_data: VerificationRequest = {'access_token': access_token}
    return requests.post(
        self.API_URL + 'verifications/incomes/',
        json=request_data,
        headers=self.API_HEADERS,
    ).json()

The application back end sends the data returned by the Truv to the application front end.

@app.route('/getVerifications/<public_token>', methods=['GET'])
def get_verification_info_by_token(public_token: str):
    """ getVerificationInfoByToken """
    # First exchange public_token to access_token
    access_token = api_client.get_access_token(public_token)
    # Use access_token to retrieve the data
    if product_type == 'employment':
        verifications = api_client.get_employment_info_by_token(access_token)
    elif product_type == 'income':
        verifications = api_client.get_income_info_by_token(access_token)
    else:
        raise Exception('Unsupported product type!')
    return verifications

The application front end renders the data sent by the back end for the user to view.

function renderPayrollData(data) {
  const historyContainer = document.querySelector("#history")
  historyContainer.innerHTML = JSON.stringify(data, null, 2)
}

The application front end can close the Bridge by calling close method.

window.bridge.close();

Did this page help you?