# Retrieve an employment history report for a link Source: https://truv.com/docs/api-reference/account-link-income-and-employment-reports/link_detail_reports_employment GET /v1/links/{link_id}/employment/report/ The endpoint returns the VOE report for a link # Retrieve an income and employment report for a link Source: https://truv.com/docs/api-reference/account-link-income-and-employment-reports/link_detail_reports_income GET /v1/links/{link_id}/income/report/ The endpoint returns the VOIE report for a link # The Link Income & Employment Reports object Source: https://truv.com/docs/api-reference/account-link-income-and-employment-reports/object Account link-level income and employment verification reports for individual account connections. Account Link Reports return income and employment data for a single account link (connection to a payroll provider). For aggregated reports across all of a user's account links, see [User Income and Employment Reports](/api-reference/user-income-and-employment-reports/object). # Attributes The table below covers information from the report response. | Attribute | Type | Description | | :-------------- | :--------------- | :------------------------------------------------------------------------------------- | | id | string | Unique identifier | | status | string | Status from Connection Lifecycle | | finished\_at | string | Time when report was finished | | completed\_at | string | ~~Time when report was completed~~ **(Deprecated, invalid datetime format)** | | access\_token | string | Access token for Link to payroll provider | | tracking\_info | string | Information passed to Truv Bridge from partner | | refresh\_status | string | Status of most recent refresh task | | employments | array of objects | List of employments, see [Employments object](#employments-object) | | pdf\_report | uri | Verification report in PDF format | | provider | string | Payroll provider name | | data\_source | string | Source of data: `payroll` - Payroll provider parsing, `docs` - User-uploaded documents | ## Employments object The Employments object contains the values and descriptions below. | Attribute | Type | Description | | :---------------------- | :--------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | income | string | Income amount not including commission or bonuses, only for income product. Null for employment product | | income\_unit | string | Pay interval for income field, only for income product: `YEARLY` - Annual income, `MONTHLY` - Monthly income, `WEEKLY` - Weekly income, `DAILY` - Daily income, `HOURLY` - Hourly income. Null for employment product | | pay\_rate | string | Payment rate per pay cycle, only for income product. Null for employment product | | pay\_frequency | string | Pay frequency, only for income product: `M` - Monthly, `SM` - Semi-Monthly, `W` - Weekly, `BW` - Bi-Weekly, `A` - Annually, `SA` - Semiannually, `C` - Commission. Null for employment product | | statements | array of objects | List of paystubs received from a payroll provider, only for income product, see [Statements object](#statements-object). Null for employment product | | annual\_income\_summary | array of objects | Annual income summary by years, only for income product, see [Annual income summary object](#annual-income-summary-object). Null for employment product | | bank\_accounts | array of objects | List of bank accounts linked to employment, only for income product, see [Bank accounts object](#bank-accounts-object). Null for employment product | | w2s | array of objects | List of W-2 forms linked to employment, only for income product, see [W2s object](#w2s-object). Null for employment product | | id | string | Unique ID | | is\_active | Boolean | Status of active employment | | job\_title | string | Employee's job title | | job\_type | string | Employee's job type: `F` - Full Time, `P` - Part Time, `S` - Seasonal, `D` - Daily (per diem), `C` - Contract | | start\_date | date | Employee's hire date | | original\_hire\_date | date | Original hire date | | end\_date | date | Employee's end date | | external\_last\_update | date | Indicates date of last updated employment data from Payroll Provider | | derived\_fields | array of strings | Array of derived fields | | missing\_data\_fields | array of strings | List of missing data fields from payroll response | | manager\_name | string | Supervisor's name | | profile | object | Person's identity information | | company | object | [Company object](#company-object) | | gse\_accepted | Boolean | Status of provider eligibility from Fannie Mae Desktop Underwriter | ### Company object This table covers values within the company object. | Attribute | Type | Description | | :-------- | :----- | :-------------------------------- | | name | string | Company name | | address | object | [Address object](#address-object) | | phone | string | Company phone number | | ein | string | Employer Identification Number | #### Address object The values in this table are for the address object of the company. | Attribute | Type | Description | | :-------- | :----- | :---------- | | street | string | Street | | city | string | City | | state | string | State | | zip | string | Zip | | country | string | Country | ### Statements object View the table below for information from the Statements object. | Attribute | Type | Description | | :-------------------- | :--------------- | :------------------------------------------------------------------ | | id | string | Unique ID | | check\_number | string | External ID of pay stub from payroll provider | | pay\_date | date | Pay date | | net\_pay | string | Net pay | | net\_pay\_ytd | string | Net pay year to date | | gross\_pay | string | Gross pay | | gross\_pay\_ytd | string | Gross pay year to date | | bonus | string | Bonus | | commission | string | Commission | | hours | string | Work hours during pay period | | basis\_of\_pay | string | Basis of pay: `S` - Salary, `H` - Hourly, `D` - Daily, `W` - Weekly | | period\_start | date | Period start | | period\_end | date | Period end | | regular | string | Regular pay | | regular\_ytd | string | Regular salary year to date | | other\_pay\_ytd | string | All other payment year to date | | bonus\_ytd | string | Bonus year to date | | commission\_ytd | string | Commission year to date | | overtime | string | Overtime pay | | overtime\_ytd | string | Overtime pay year to date | | other\_pay | string | All other payment | | earnings | array of objects | Earnings for this pay cycle by type | | earnings\_ytd | array of objects | Earnings year to date by type | | deductions | array of objects | Deductions for pay cycle by type | | deductions\_ytd | array of objects | Deductions year to date by type | | md5sum | string | MD5 hash value computed based on file content | | file | uri | Link to pay stub file, format is specified in the content-type | | derived\_fields | array of strings | Array of derived fields | | missing\_data\_fields | array of strings | List of missing data fields from payroll response | ### Annual income summary object Find information for the attributes and values of the annual income summary object. | Attribute | Type | Description | | :--------- | :------ | :---------------------- | | id | string | Unique ID | | year | integer | Income report year | | regular | string | Regular salary | | bonus | string | Bonus | | commission | string | Commission | | overtime | string | Overtime pay | | other\_pay | string | All other payment forms | | net\_pay | string | Net pay | | gross\_pay | string | Gross pay | ### Bank accounts object The table below covers the attributes within the bank accounts object. | Attribute | Type | Description | | :-------------- | :----- | :---------------------------------------------------------------------------------------------------------- | | account\_number | string | Account number | | routing\_number | string | Routing number | | account\_name | string | User friendly account name | | account\_type | string | Account type: `C` - Checking account, `S` - Savings account | | deposit\_type | string | Deposit type: `E` - Entire paycheck, `P` - Percentage of the paycheck, `A` - Fixed amount from the paycheck | | deposit\_value | string | Deposit value | | bank\_name | string | Bank name | ### W2s object The values in this table are for the W-2s object field. | Attribute | Type | Description | | :---------------------- | :------ | :-------------------------------------------------------------- | | file | uri | Link to W2 report file, format is specified in the content-type | | md5sum | string | MD5 hash value computed based on file content | | year | integer | Year | | wages | string | Wages, tips, other compensation (Section 1) | | federal\_tax | string | Federal income tax withheld (Section 2) | | social\_security\_wages | string | Social security wages (Section 3) | | social\_security\_tax | string | Social security tax withheld (Section 4) | | medicare\_wages | string | Medicare wages (Section 5) | | medicare\_tax | string | Medicare tax withheld (Section 6) | | gross\_pay | string | Gross pay | *** ## Earnings object The `earnings` or `earnings_ytd` field is an array that contains all earnings. Below is an example of the earnings object with the supported categories: `regular`, `bonus`, `commission`, `overtime`, `other_pay`. ```json theme={null} [ { "name": "Regular", "amount": "38072.0", "category": "regular", "rate": "475.9", "units": "80" }, { "name": "Bonus", "amount": "10000.0", "category": "bonus", "rate": null, "units": null } ] ``` *** ## Deductions object The `deductions` or `deductions_ytd` field is an array that contains all deductions. Below is an example of the deductions object. The supported categories are the following: `memo`, `medicare`, `retirement`, `benefit`, `socialsec`, `federal`, `state`, `garnishment`, `local`, `other`. ```json theme={null} [ { "amount": "127.01", "category": "socialsec", "name": "Social Security Tax" }, { "amount": "46.23", "category": "state", "name": "VA State Income Tax" }, { "amount": "29.7", "category": "medicare", "name": "Medicare Tax" } ] ``` # Endpoints Use the endpoints below to retrieve link-level reports. * [Retrieve an employment history report for an account link](/api-reference/account-link-income-and-employment-reports/link_detail_reports_employment) * [Retrieve an income and employment report for an account link](/api-reference/account-link-income-and-employment-reports/link_detail_reports_income) # Example response The sample below is a JSON response for the endpoint. ```json theme={null} { "id": "24d7e80942ce4ad58a93f70ce4115f5c", "status": "new", "finished_at": "2021-04-06T11:30:00Z", "completed_at": "2021-04-06 11:30:00+00:00", "access_token": "48427a36d43c4d5aa6324bc06c692456", "tracking_info": "user123456", "refresh_status": "new", "employments": [ { "income": "70000.00", "income_unit": "YEARLY", "pay_rate": "6500.00", "pay_frequency": "M", "statements": [ { "id": "24d7e80942ce4ad58a93f70ce4115f5c", "check_number": "29205182", "pay_date": "2018-05-15", "net_pay": "11500.32", "net_pay_ytd": "31980.64", "gross_pay": "13900.11", "gross_pay_ytd": "49200.00", "bonus": "100.00", "commission": "12000.00", "hours": "40.00", "basis_of_pay": "S", "period_start": "2018-05-01", "period_end": "2018-05-15", "regular": "1695.11", "regular_ytd": "23000.00", "other_pay_ytd": "700.00", "bonus_ytd": "1000.00", "commission_ytd": "24000.00", "overtime": "45.00", "overtime_ytd": "500.00", "other_pay": "60.00", "earnings": [ { "name": "Regular", "amount": "1935.77", "category": "regular", "rate": null, "units": null }, { "name": "Overtime", "amount": "60.58", "category": "overtime", "rate": "30.29", "units": "2" } ], "earnings_ytd": [ { "name": "Regular", "amount": "1935.77", "category": "regular", "rate": null, "units": null }, { "name": "Overtime", "amount": "60.58", "category": "overtime", "rate": "30.29", "units": "2" } ], "deductions": [ { "amount": "127.01", "category": "socialsec", "name": "Social Security Tax" }, { "amount": "46.23", "category": "state", "name": "VA State Income Tax" }, { "amount": "29.7", "category": "medicare", "name": "Medicare Tax" } ], "deductions_ytd": [ { "amount": "127.01", "category": "socialsec", "name": "Social Security Tax" }, { "amount": "46.23", "category": "state", "name": "VA State Income Tax" }, { "amount": "29.7", "category": "medicare", "name": "Medicare Tax" } ], "md5sum": "03639d6a6624f69a54a88ea90bd25e9d", "file": "https://citadelid-resources.s3-us-west-2.amazonaws.com/paystub_sample.pdf", "derived_fields": [ "basis_of_pay" ], "missing_data_fields": [ "earnings_ytd" ] } ], "annual_income_summary": [ { "id": "24d7e80942ce4ad58a93f70ce4115f5c", "year": 2018, "regular": "23000.00", "bonus": "1000.00", "commission": "24000.00", "overtime": "500.00", "other_pay": "700.00", "net_pay": "31980.64", "gross_pay": "49200.00" } ], "bank_accounts": [ { "account_number": "1234567890", "routing_number": "123456789", "account_name": "My Bank", "account_type": "C", "deposit_type": "A", "deposit_value": "200.00", "bank_name": "TD Bank" } ], "w2s": [ { "file": "https://citadelid-resources.s3-us-west-2.amazonaws.com/W2_sample.pdf", "md5sum": "f65e30c39124ad707ac4b3aeaee923a7", "year": 2020, "wages": "900.50", "federal_tax": "75.01", "social_security_wages": "900.50", "social_security_tax": "56.30", "medicare_wages": "900.50", "medicare_tax": "13.15", "gross_pay": "18211.48" } ], "id": "24d7e80942ce4ad58a93f70ce4115f5c", "is_active": false, "job_title": "PR associate", "job_type": "F", "start_date": "2018-01-01", "original_hire_date": "2017-06-21", "end_date": "2023-04-29", "external_last_updated": "2023-04-29", "dates_from_statements": false, "derived_fields": [ "is_active" ], "missing_data_fields": [ "w2s" ], "manager_name": "Jenny McDouglas", "profile": { "id": "48427a36d43c4d5aa6324bc06c692456", "created_at": "2022-06-07T15:00:00Z", "updated_at": "2022-06-31T15:00:00Z", "first_name": "John", "last_name": "Doe", "full_name": "John Doe", "middle_initials": "K", "email": "john.doe@example.com", "ssn": "123456789", "date_of_birth": "1992-03-03", "home_address": { "street": "1 Morgan Ave", "city": "Los Angeles", "state": "CA", "zip": "90210", "country": "US" } }, "company": { "name": "Facebook Demo", "address": { "street": "1 Morgan Ave", "city": "Los Angeles", "state": "CA", "zip": "90210", "country": "US" }, "phone": "6503087300", "ein": "12-345678" } } ], "pdf_report": "https://citadelid-resources.s3-us-west-2.amazonaws.com/report.pdf", "provider": "adp", "data_source": "payroll" } ``` # Retrieve auth data Source: https://truv.com/docs/api-reference/auth/bank-auth-get GET /v1/links/{link_id}/auth/ The endpoint retrieves a list of connected financial accounts, including their bank identification numbers. # The Auth object Source: https://truv.com/docs/api-reference/auth/object Account and routing numbers for ACH, RTP, and wire transfers from connected financial accounts. Each auth response includes the standard [Account](/api-reference/balances/object) fields plus the `numbers` object documented below. The Auth endpoint returns account and routing numbers for a user's connected financial accounts. Use this data for ACH transfers, wire transfers, and account verification. # Attributes The auth response returns an `accounts` array. Each account includes the standard [Accounts object](/api-reference/balances/object) fields plus a `numbers` object with account and routing numbers grouped by network type. ## Numbers object Each key (`ACH`, `RTP`, `OTHERS`) contains an array of number objects. | Attribute | Type | Description | | :---------------------------- | :------ | :-------------------------------------------------------------------------- | | `account_number` | string | Unique identifier assigned to the financial account | | `routing_number` | string | Unique identifier for the financial institution, used to route transactions | | `is_tokenized_account_number` | boolean | Whether the account number has been tokenized by the institution | # Endpoints * [Retrieve auth data](/api-reference/auth/bank-auth-get) # Example response ```json theme={null} { "accounts": [ { "id": "24d7e80942ce4ad58a93f70ce4115f5c", "created_at": "2022-05-04T11:30:00Z", "updated_at": "2022-05-04T12:00:00Z", "type": "CHECKING", "subtype": "MONEY_MARKET", "mask": "6789", "nickname": "My account", "is_open": true, "balances": { "currency_code": "USD", "balance": "100.00", "available_balance": "50.99", "credit_limit": "200.00" }, "provider": "truv", "provider_name": "Truv Bank", "numbers": { "ACH": [ { "account_number": "16002600", "routing_number": "123456789", "is_tokenized_account_number": true } ], "RTP": [ { "account_number": "16002600", "routing_number": "123456789", "is_tokenized_account_number": true } ], "OTHERS": [ { "account_number": "16002600", "routing_number": "123456789", "is_tokenized_account_number": true } ] } } ] } ``` # Authentication Source: https://truv.com/docs/api-reference/authentication How to authenticate with the Truv API ## Base URL All API requests use the same base URL regardless of environment: ``` https://prod.truv.com/v1/ ``` Your **Access Secret** determines which environment the request is routed to, not the URL. Sandbox and Production both use the same endpoint. *** ## API Authentication All Truv API requests require authentication using your **Client ID** and **Secret**. ### Get your credentials 1. Log in to [dashboard.truv.com](https://dashboard.truv.com) 2. Navigate to **Development** → **API Keys** 3. Copy your credentials **Keep your API Secret secure!** * Never expose your secret in client-side code * Don't commit credentials to version control * Use environment variables in production *** ## Authentication headers Include these headers in every API request: ```bash theme={null} X-Access-Client-Id: your_client_id X-Access-Secret: your_api_secret ``` ### Example Request ```bash theme={null} curl -X GET https://prod.truv.com/v1/users/ \ -H "X-Access-Client-Id: YOUR_TRUV_CLIENT_ID" \ -H "X-Access-Secret: YOUR_TRUV_CLIENT_SECRET" \ -H "Content-Type: application/json" ``` *** ## Environments | Environment | Base URL | Purpose | | -------------- | --------------------------- | ----------------------------------------- | | **Sandbox** | `https://prod.truv.com/v1/` | Testing with predefined sample data | | **Production** | `https://prod.truv.com/v1/` | Live data, each successful task is billed | Your Access Secret prefix determines the environment: | Prefix | Environment | Example | | ---------- | ----------- | -------------------------------------------------- | | `sandbox-` | Sandbox | `sandbox-a57b3109f1f4a8b3f2ebbc1c526950f1795464af` | | `prod-` | Production | `prod-e82c4f19d3a7b6e5f0c8d2a1b4e7f3a6d9c2b5e8` | Sandbox and production use the same base URL. Your Access Secret prefix determines which environment the request is routed to. *** ## API Key Rotation Rotate your API keys periodically or whenever credentials may have been compromised. ### Dashboard-Only Integrations If you create [Orders](/developers/integration/hosted-orders/new-user) exclusively through the Dashboard: 1. Create a new key in the [Truv Dashboard API Keys page](https://dashboard.truv.com/app/development/keys) 2. Delete the old key. Pending transactions with the original key continue to process ### API Integrations For embedded solutions or Orders created via the API: Generate a new key in the Truv Dashboard. Create a sandbox key first to test before updating production. Search your code for the `X-Access-Secret` header and replace the old key everywhere. Remove outdated keys to reduce risk. Pending transactions with the original key continue to process. Deleting keys cannot be undone. Confirm the new key is working before deleting the old one. *** ## Security For webhook verification and data protection guidelines, see the [Security](/api-reference/security-overview) section. *** ## Next steps Understand orders, links, tasks, and the Truv data model Data protection, encryption, and compliance guidelines # List all balances Source: https://truv.com/docs/api-reference/balances/balances-list GET /v1/links/{link_id}/balances/ The endpoint allows developers to receive balances. # The Balances object Source: https://truv.com/docs/api-reference/balances/object Current balance data for connected financial accounts. Each balance belongs to an [Account](/api-reference/balances/object). The balance fields appear within the `balances` object on each account. The Balances endpoint returns current balance information for all accounts associated with a link. # Attributes | Attribute | Type | Description | | :------------------ | :----- | :---------------------------------------------------------------------- | | `currency_code` | string | Three-character ISO 4217 currency code (e.g., `USD`) | | `balance` | string | Current account balance | | `available_balance` | string | Available balance for use. `PENDING` transactions may not be reflected. | | `credit_limit` | string | Credit limit (for credit accounts) | # Endpoints * [List all balances](/api-reference/balances/balances-list) # Example response ```json theme={null} { "count": 1, "results": [ { "id": "24d7e80942ce4ad58a93f70ce4115f5c", "type": "CHECKING", "subtype": "MONEY_MARKET", "mask": "6789", "nickname": "My account", "balances": { "currency_code": "USD", "balance": "100.00", "available_balance": "50.99", "credit_limit": "200.00" } } ] } ``` # Bank Account Webhook Events Source: https://truv.com/docs/api-reference/bank-accounts/events Webhook events for bank account creation and updates. Subscribe to these events via [Webhooks](/api-reference/webhooks/object) to receive notifications when bank account data becomes available or changes during a refresh. All webhook payloads include the [common fields](/api-reference/webhooks/object#webhook-payload-structure) plus the event-specific fields below. *** ## bank-accounts-created Fires when bank account data has been retrieved. This occurs once per [Link](/api-reference/links/object) for each non-refresh [Task](/api-reference/tasks/object) completion. Multiple responses are sent when additional bank accounts are found. **Additional fields:** | Field | Description | | --------------- | --------------------------------- | | `employment_id` | The associated employment record | | `task_id` | The associated Task | | `objects_count` | Number of bank accounts retrieved | ```json theme={null} { "webhook_id": "3cc6a3e58cbe4b71bbbe8b821d2242b8", "task_id": "c32fb957ec7246828da56be7516da765", "link_id": "9915c50cc047413bb810767f218390f8", "product": "employment", "data_source": "payroll", "tracking_info": null, "event_type": "bank-accounts-created", "event_created_at": "2022-08-23T17:32:19.269355Z", "objects_count": 2, "employment_id": "427abebd8590457e8332fdff77fc412f", "user_id": "88fef4cea64c40b5ad6727cc9b0b9fdc", "template_id": null } ``` *** ## bank-accounts-updated Fires when the bank account count changes during a refresh Task. For example, if a person had 3 bank accounts and now has 4. **Additional fields:** Same as `bank-accounts-created` (`employment_id`, `task_id`, `objects_count`). ```json theme={null} { "webhook_id": "3cc6a3e58cbe4b71bbbe8b821d2242b8", "task_id": "c32fb957ec7246828da56be7516da765", "link_id": "9915c50cc047413bb810767f218390f8", "product": "employment", "data_source": "payroll", "tracking_info": null, "event_type": "bank-accounts-updated", "event_created_at": "2022-08-23T17:32:19.269355Z", "objects_count": 2, "employment_id": "427abebd8590457e8332fdff77fc412f", "user_id": "88fef4cea64c40b5ad6727cc9b0b9fdc", "template_id": null } ``` # List all bank accounts Source: https://truv.com/docs/api-reference/bank-accounts/link-bank-accounts GET /v1/links/{link_id}/bank_accounts/ List of all bank accounts used for the direct deposit # The Bank Accounts object Source: https://truv.com/docs/api-reference/bank-accounts/object Learn how to manage bank accounts for the DDS and PLL. Manage bank accounts for Direct Deposit Switching (**DDS**) and Paycheck Linked Lending (**PLL**) with the endpoints in this section. Access information from bank accounts in a user's payroll account during **Verification of Income and Employment (VOIE)** before making deposit switches. ## Attributes The values in these sections are for bank account objects. | Attribute | Type | Description | | :-------------- | :----- | :----------------------------------------------------------------------------------------------------------------------------------------------------- | | account\_number | string | Bank account number | | routing\_number | string | Routing number | | account\_name | string | User-friendly account name for bank account | | account\_type | string | Account type of bank account, includes two types: `C` - Checking account, `S` - Saving account | | deposit\_type | string | Deposit type of bank account, three types of deposits available: `E` - Entire paycheck, `P` - Percentage of paycheck, `A` - Fixed amount from paycheck | | deposit\_value | string | Deposit value of selected bank account | | bank\_name | string | Bank name | *** ## Endpoints The two items below are the available endpoints. * List all bank accounts *** ## Example response This JSON object is a sample payload for the endpoint. ```json theme={null} [ { "account_number": "11114623", "routing_number": "101014378", "account_name": null, "account_type": "C", "deposit_type": "A", "deposit_value": "1604.98", "bank_name": "Sandbox Bank" }, { "account_number": "11111308", "routing_number": "101013399", "account_name": null, "account_type": "C", "deposit_type": "A", "deposit_value": "25.00", "bank_name": "Sandbox Bank" } ] ``` # The Bridge Token object Source: https://truv.com/docs/api-reference/bridge-token/object Create tokens with the API to use Truv Bridge in your integration. A **bridge\_token** is a short-lived token that is required to open Truv Bridge. ### Bridge Token Attributes The attributes of the Bridge Token are below. | Attribute | Type | Description | | :------------------- | :----- | :------------------------------------------------------------------------------------------ | | bridge\_token | string | Unique ID of Bridge Token | | tracking\_info | string | Information to associate with current user | | product\_type | string | Indicates main product type | | data\_sources | array | List of data sources for the provided product type. Leave blank to apply default values. | | use\_case | string | Use case for the connection which will be used for billing. | | template\_id | string | An ID of a customization template. Leave blank to apply default values. | | allowed\_products | array | List of allowed product types for linked account, only main type is allowed if not included | | company\_mapping\_id | string | Company ID to skip search step | | provider\_id | string | Provider ID to skip search step | | access\_token | string | Access token of existing Link, used for data refresh with re-authentication | | account | object | Bank account info. Used for Direct deposit switching and Paycheck linked lending | ## Endpoints Below is the available endpoint list for creating a **bridge\_token**. * [Create a bridge token](/api-reference/bridge-token/users_tokens) *** ## Example response The example object below is from the `Create Bridge Token` endpoint. ```json theme={null} { "bridge_token": "2f67984a110747d190c39e1022c81837", "tracking_info": "any data for tracking current user", "client_name": "Truv Demo", "product_type": "income", "allowed_products": [ "income", "deposit_switch" ], "company_mapping_id": "99dd17074ac94aa9ace2621d657c7610", "access_token": "99dd17074ac94aa9ace2621d657c7610" } ``` # Create a bridge token Source: https://truv.com/docs/api-reference/bridge-token/users_tokens POST /v1/users/{user_id}/tokens/ The endpoint creates a bridge token for a user. This is typically the endpoint called before initializing the Bridge since the response from this call is passed to the TruvBridge.init function. # Search companies with autocomplete Source: https://truv.com/docs/api-reference/companies/company_autocomplete_search GET /v1/company-mappings-search/ The endpoint provides company search using prefix. # Get company information Source: https://truv.com/docs/api-reference/companies/company_info GET /v1/companies/{company_mapping_id}/ The endpoint returns detailed information for a specific company mapping, including basic company details, success rate, and bank account information. # Search companies Source: https://truv.com/docs/api-reference/companies/company_mapping POST /v1/companies/ The endpoint returns the `company_mapping_id` for a company if it exists. This `company_mapping_id` can be passed to the `/bridge-tokens` endpoint to have the user skip the company selection step and suggest a data provider. # The Companies object Source: https://truv.com/docs/api-reference/companies/object Search employers, check coverage, and map companies to payroll providers A **Company** represents an organization where a user works and receives income. Truv Bridge prompts users with a company search by default, allowing users to find and connect their employer's payroll system. When a `company_mapping_id` is passed directly into Truv Bridge, the user skips the search step entirely and goes straight to authentication. Check a company's `success_rate` and `mapping_status` before creating an order to optimize the user experience and decide whether to fall back to document upload. *** ## Attributes | Attribute | Type | Description | | -------------------- | ------ | ------------------------------------------------------------------------- | | `company_mapping_id` | String | Unique company identifier. Pass to Truv Bridge to bypass employer search. | | `name` | String | Company name | | `domain` | String | Unique web domain of the company | | `logo_url` | String | URL to the company's logo | | `confidence_level` | Float | Predicted success rate (0.0–1.0; values ≥ 0.5 indicate high success) | | `success_rate` | String | Classification: `"high"`, `"low"`, `"unsupported"`, or `null` | | `mapping_status` | String | Integration status: `"verified"`, `"mapped"`, or `"unmapped"` | *** ## Endpoints Search companies by name with autocomplete. Use results to populate or pre-fill Truv Bridge. Retrieve detailed attributes for a specific company by its mapping ID Map a domain or company name to a Truv company record and mapping ID *** ## Example response ```json theme={null} { "company_mapping_id": "48427a36d43c4d5aa6324bc06c692456", "name": "Facebook Demo", "domain": "facebook.com", "logo_url": "https://citadelid-resources.s3-us-west-2.amazonaws.com/facebook.png", "confidence_level": "0.9", "success_rate": "high", "mapping_status": "verified" } ``` *** ## Common use cases Search for a company using the autocomplete endpoint, retrieve its `company_mapping_id`, and pass it directly to Truv Bridge. The user lands straight on the login screen for their employer. No search step needed. ```javascript theme={null} // 1. Search for the company const results = await fetch('https://prod.truv.com/v1/company-mappings-search/?query=Facebook', { headers: { 'X-Access-Client-Id': CLIENT_ID, 'X-Access-Secret': SECRET } }); const { companies } = await results.json(); const { company_mapping_id } = companies[0]; // 2. Pass to Truv Bridge TruvBridge.init({ bridgeToken, companyMappingId: company_mapping_id }).open(); ``` Use `success_rate` and `mapping_status` to decide whether to offer payroll-based verification or prompt the user to upload documents instead. | `success_rate` | `mapping_status` | Recommendation | | --------------- | ---------------- | --------------------------------------------- | | `"high"` | `"verified"` | Proceed with payroll verification | | `"low"` | `"mapped"` | Offer document upload as primary path | | `"unsupported"` | `"unmapped"` | Skip payroll. Go straight to document upload. | # Data Processing Source: https://truv.com/docs/api-reference/data-processing Processing stages, timing, and data availability during verification Truv processes verification data in sequential stages. Each stage produces progressively more data. Large documents and certain formats may require longer processing times. ## Processing stages | Stage | Approximate time | Description | | ---------------- | ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `login` | \< 10 seconds | User authentication with payroll provider | | `mfa` | 10–30 seconds | Payroll provider multi-factor authentication request from user | | `parse` | \~30 seconds | Collecting basic information about identity, employment, and list of paystubs with pay dates | | `full_parse` | \< 45 seconds, up to 5 minutes | Downloading and parsing paystubs, W-2s, and income sources. Data processing continues in the background after successful authentication and closing Truv Bridge | | `switch_deposit` | \~30 seconds | Updating pay allocations and specified distributions within user account | *** ## Median stage times Processing durations are approximations and may vary. * **Login**: 5 to 15 seconds * **Parse**: 30 to 60 seconds (Base parsing) * **Full parse**: 1 to 5 minutes *** ![Processing timeline](https://files.readme.io/87c2d19-timeline.png) Each task has a maximum limit of 20 minutes to complete. *** ## Data available at each stage | Stage | Data available | | -------------- | ----------------------------------------------------- | | **Login** | — | | **Base parse** | Identity, Employment, List of paystubs with pay dates | | **Full parse** | Paystubs, Parsed income, W-2s, Bank accounts | When using VOIE endpoints, data from the base parse is available without waiting for full parse to complete. Use [webhooks](/api-reference/webhooks/object) or the [Tasks API](/api-reference/tasks/tasks_read) to track progress. # The Data Providers object Source: https://truv.com/docs/api-reference/data-providers/object Look up payroll, bank, and insurance providers supported by Truv, filter by product type and data source A **Data Provider** is the underlying system that stores user data: payroll platforms (e.g., ADP, Workday, Gusto), banks (e.g., Chase, Wells Fargo), and insurance carriers. Each [company](/api-reference/companies/object) typically maps to one data provider. Use the Data Providers endpoints to check which providers Truv supports, verify coverage for a specific product type, and retrieve provider details before creating orders. Filter by `product_type` and `data_source` to find providers relevant to your use case. ### Supported product types `income`, `employment`, `deposit_switch`, `pll`, `insurance`, `transactions`, `assets`, `admin` ### Supported data sources `payroll`, `financial_accounts`, `insurance` Before creating an order, confirm that the user's provider supports your product type by checking the `is_disabled` field and `success_rate`. *** ## Attributes | Attribute | Type | Description | | -------------- | ------- | ------------------------------------------------------------------ | | `id` | String | Unique data provider identifier | | `name` | String | Data provider name (e.g., ADP, Chase, Gusto) | | `data_source` | String | Provider category: `payroll`, `financial_accounts`, or `insurance` | | `logo_url` | String | URL to the provider's logo | | `is_disabled` | Boolean | Whether the provider is currently disabled | | `success_rate` | String | Connection success classification: `"high"`, `"low"`, or `null` | *** ## Endpoints Retrieve all data providers filtered by product type and data source Get details for a specific data provider by ID *** ## Example response ```json theme={null} { "count": 123, "results": [ { "id": "adp", "name": "ADP", "data_source": "payroll", "logo_url": "https://citadelid-resources.s3-us-west-2.amazonaws.com/adp.png", "is_disabled": false, "success_rate": "high" } ], "next": "", "previous": "" } ``` # Retrieve a data provider Source: https://truv.com/docs/api-reference/data-providers/providers-detail GET /v1/providers/{id}/ This endpoint retrieves a data provider. # List all data providers Source: https://truv.com/docs/api-reference/data-providers/providers-list GET /v1/providers/ The endpoint returns a list of data providers filtered by the query parameter `product_type`. # Data Structure Source: https://truv.com/docs/api-reference/data-structure How Truv's core objects (Orders, Users, Links, and Tasks) relate to each other The Truv API is built around four core objects: **Orders**, **Users**, **Links**, and **Tasks**. Understanding how they connect is essential before integrating. ## Object relationships Every verification follows the same path through these objects: 1. **Order → User.** You create an [Order](/api-reference/orders/object) with the applicant's details. Truv automatically creates a [User](/api-reference/users/object), generates a Bridge Token, and builds a landing page with a unique `share_url`. You can also create Users directly via the API if you manage your own frontend flow. 2. **User → Bridge Token.** A [Bridge Token](/api-reference/bridge-token/users_tokens) is a short-lived credential scoped to a single User. It controls which products the User can access, supports [deeplinking](/developers/integration/embedded-orders/deeplinking) to pre-select a provider, and sets the customization template. Pass it to your frontend to initialize Truv Bridge. 3. **Bridge Token → Link.** When the User authenticates with a data provider (payroll system, bank, or tax portal) through Truv Bridge, the system creates a [Link](/api-reference/links/object), a persistent connection to that provider. The Link has an `access_token` for all subsequent data operations. If the same User reconnects with the same credentials to the same provider, Truv returns the existing Link rather than creating a duplicate. 4. **Link → Task.** Each data retrieval or action through a Link is a [Task](/api-reference/tasks/object): fetching income data, switching a direct deposit, or refreshing stale data. A single Link can have multiple Tasks over its lifetime. 5. **Task → Data.** When a Task completes successfully, the verification data becomes available through the Link's data endpoints. Listen for `task-status-updated` [webhooks](/api-reference/webhooks/object) to know when data is ready. For the simplest integration, create an Order and let Truv handle everything: User creation, Bridge Token generation, and invite delivery. Use the lower-level User and Bridge Token APIs only when you need full control over the frontend experience. *** ## Orders An [Order](/api-reference/orders/object) is the starting point for every verification. Creating an Order automatically creates a User, generates a Bridge Token, and produces a landing page for the user to connect their account. | Attribute | Type | Description | | -------------- | ------ | ------------------------------- | | `id` | string | Unique identifier for the Order | | `status` | string | Current order status | | `product_type` | string | Verification product type | | `share_url` | string | Landing page URL for the user | | `bridge_token` | string | Token to initialize Truv Bridge | *** ## Users A [User](/api-reference/users/object) represents a person connecting their accounts through Truv Bridge. Each User can have multiple Links across different providers. | Attribute | Type | Description | | ------------------ | ------ | ------------------------------ | | `id` | string | Unique identifier for the User | | `external_user_id` | string | Your internal identifier | | `first_name` | string | First name (required) | | `last_name` | string | Last name (required) | | `email` | string | User email | | `phone` | string | User phone number | | `ssn` | string | Social Security Number | *** ## Links A [Link](/api-reference/links/object) is a persistent connection to a data provider for a specific User. Reusing the same credentials for the same provider returns the same Link. | Attribute | Type | Description | | --------------- | ------ | ---------------------------------------------- | | `id` | string | Unique identifier for the Link | | `access_token` | string | Token for retrieving data from this connection | | `provider_id` | string | The data provider the user connected to | | `status` | string | Current connection status | | `tracking_info` | string | Optional tracking information | *** ## Tasks A [Task](/api-reference/tasks/object) is an individual action performed through a Link: fetching verification data, switching direct deposits, or refreshing a connection. Each Task progresses through a defined status flow from `new` to `done` or `error`. See [Task Lifecycle](/api-reference/tasks/lifecycle) for the full status diagram, processing times, and error handling. *** ## Data retrieval by source After a Task completes, the endpoint you use to retrieve data depends on the `data_source` value on the employer or financial account suborder. | `data_source` | Description | Retrieval endpoint | | -------------------- | ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- | | `payroll` | Payroll provider parsing | `GET /v1/links/{link_id}/income/report/` for income data, `GET /v1/links/{link_id}/employment/report/` for employment-only data | | `docs` | User-uploaded documents | Pre-signed URLs returned in the document upload response. Access the `file` field on each statement or W-2 object. | | `financial_accounts` | Bank account data (VOA) | `POST /v1/users/{user_id}/assets/reports/` to generate an asset report, or use the income insights endpoints for transaction-based income analysis | | `insurance` | Insurance provider data | Retrieved through the insurance suborder on the Order object | | `tax` | Tax documents | Retrieved through the tax document endpoints on the Link | | `scoring_attributes` | Transaction scoring attributes | Retrieved through the scoring attributes report endpoints | For `payroll` sources, the `income` product automatically includes employment data. You do not need to make a separate employment request if you already requested income. *** ## Field constraints Numeric fields across Truv's API use a consistent precision format. All monetary and quantity fields are stored as `DecimalField(max_digits=12, decimal_places=2)`, meaning up to 10 digits before the decimal point and exactly 2 digits after. | Field | Object | Format | Max value | | --------------- | -------------------------------------- | -------------------------------- | --------------- | | `gross_pay` | Statements, Annual income summary, W2s | Decimal string, 2 decimal places | `9999999999.99` | | `net_pay` | Statements, Annual income summary | Decimal string, 2 decimal places | `9999999999.99` | | `hours` | Statements | Decimal string, 2 decimal places | `9999999999.99` | | `income` | Employments | Decimal string, 2 decimal places | `9999999999.99` | | `pay_rate` | Employments | Decimal string, 2 decimal places | `9999999999.99` | | `bonus` | Statements, Annual income summary | Decimal string, 2 decimal places | `9999999999.99` | | `commission` | Statements, Annual income summary | Decimal string, 2 decimal places | `9999999999.99` | | `overtime` | Statements, Annual income summary | Decimal string, 2 decimal places | `9999999999.99` | | `regular` | Statements, Annual income summary | Decimal string, 2 decimal places | `9999999999.99` | | `other_pay` | Statements, Annual income summary | Decimal string, 2 decimal places | `9999999999.99` | | `deposit_value` | Bank accounts | Decimal string, 2 decimal places | `9999999999.99` | | `wages` | W2s | Decimal string, 2 decimal places | `9999999999.99` | All numeric values are returned as **strings** (e.g., `"70000.00"`), not as JSON numbers. Parse them as decimals in your application to avoid floating-point precision issues. # Retrieve a deposit switch report Source: https://truv.com/docs/api-reference/dds-reports/dds-report-retrieve GET /v1/users/{user_id}/deposit_switch/report/ The endpoint retrieves a deposit switch report for a user. # Retrieve a direct deposit switch report for a link Source: https://truv.com/docs/api-reference/deposit-switch/link_detail_reports_dds GET /v1/links/{link_id}/direct_deposit/report/ The endpoint returns the DDS report for a link # Retrieve a paycheck linked loan report Source: https://truv.com/docs/api-reference/deposit-switch/link_detail_reports_pll GET /v1/links/{link_id}/pll/report/ The endpoint returns the PLL report. # The Deposit Switch object Source: https://truv.com/docs/api-reference/deposit-switch/object Learn about the values for reports for Direct Deposit Switch (DDS). Direct Deposit Switch (**DDS**) reports contain the attributes in the tables below. ## Attributes The values below cover attributes for the Deposit Switch Report. | Attribute | Type | Description | | :---------------- | :----- | :--------------------------------------------------------------------------------------------------------------- | | id | string | Unique identifier | | status | string | Status from Connection Lifecycle | | finished\_at | string | Time when report was finished | | completed\_at | string | ~~Time when report was completed~~ **(Deprecated, invalid datetime format)** | | access\_token | string | Access token for Link to payroll provider | | tracking\_info | string | Information passed to Truv Bridge from partner | | deposit\_details | object | Bank account info, for Direct Deposit Switch (DDS) and Paycheck Linked Lending (PLL), see Deposit details object | | initial\_accounts | object | List of initial accounts, see Initial accounts object | ### Deposit details object This table has information for the deposit details object. | Attribute | Type | Description | | :-------------- | :----- | :-------------------------------------------------------------------------------------------------------------------------- | | account\_number | string | Account number | | account\_type | string | Account type: `checking` - Checking account, `savings` - Savings account | | routing\_number | string | Routing number | | bank\_name | string | Bank name | | deposit\_type | string | Deposit type: `entire` - Entire paycheck, `percent` - Percentage of the paycheck, `amount` - Fixed amount from the paycheck | | deposit\_value | string | Deposit value | ### Initial accounts object The information below is for the initial accounts object attributes. | Attribute | Type | Description | | :-------------- | :----- | :------------- | | account\_number | string | Account number | | routing\_number | string | Routing number | *** ## Endpoints Use the following endpoints to get information for Deposit Switch Reports. * Retrieve a direct deposit switch report for a link * Retrieve a paycheck linked loan report *** ## Example response The sample below is a JSON response for the endpoint. ```json theme={null} { "id": "24d7e80942ce4ad58a93f70ce4115f5c", "status": "new", "finished_at": "2021-04-06T11:30:00Z", "completed_at": "2021-04-06 11:30:00+00:00", "access_token": "48427a36d43c4d5aa6324bc06c692456", "tracking_info": "user123456", "deposit_details": { "account_number": "16002600", "account_type": "checking", "routing_number": "123456789", "bank_name": "TD Bank", "deposit_type": "percent", "deposit_value": "50.00" }, "initial_accounts": [ { "account_number": "16001234", "routing_number": "55999876" } ] } ``` # Create a new document collection Source: https://truv.com/docs/api-reference/document-collections/collections_create POST /v1/documents/collections/ The endpoint creates a new document collection and uploads documents in a single request. Documents are provided as base64-encoded content in JSON format. The uploaded files are automatically validated and queued for AI-powered categorization. # Delete a document collection Source: https://truv.com/docs/api-reference/document-collections/collections_delete DELETE /v1/documents/collections/{collection_id}/ The endpoint soft-deletes a document collection and all its associated files. The collection and files are marked as deleted but not physically removed from storage. # Finalize a collection Source: https://truv.com/docs/api-reference/document-collections/collections_finalize_create POST /v1/documents/collections/{collection_id}/finalize/ The endpoint finalizes a document collection by creating or updating links for all matched documents and users. Optionally accepts a subset of document IDs to finalize. If no document_ids provided, all recognized documents in the collection will be finalized. # Get collection finalization results Source: https://truv.com/docs/api-reference/document-collections/collections_finalize_retrieve GET /v1/documents/collections/{collection_id}/finalize/ Returns the current finalization results for the collection: the users involved, their links, and the documents associated with each link. This endpoint does not expose a top-level status; use the presence and contents of users/links/documents to inspect the result. # List all document collections Source: https://truv.com/docs/api-reference/document-collections/collections_list GET /v1/documents/collections/ The endpoint returns a paginated list of document collections for the authenticated user. # Get document collection details Source: https://truv.com/docs/api-reference/document-collections/collections_retrieve GET /v1/documents/collections/{collection_id}/ The endpoint returns detailed information about a specific collection, including all uploaded files and recognized documents with their categorization results. # Upload files to existing collection Source: https://truv.com/docs/api-reference/document-collections/collections_upload POST /v1/documents/collections/{collection_id}/upload/ The endpoint uploads additional files to an existing collection. Documents are provided as base64-encoded content in JSON format. Each uploaded file is automatically validated and queued for AI-powered categorization. # Delete an uploaded file Source: https://truv.com/docs/api-reference/document-collections/collections_uploaded_file_delete DELETE /v1/documents/collections/{collection_id}/upload/{uploaded_file_id}/ The endpoint soft-deletes a specific uploaded file from a collection. The file is marked as deleted but not physically removed from storage. # Get uploaded file details Source: https://truv.com/docs/api-reference/document-collections/collections_uploaded_file_retrieve GET /v1/documents/collections/{collection_id}/upload/{uploaded_file_id}/ The endpoint returns details about a specific uploaded file, including its processing status and any recognized documents. # The Document Collections object Source: https://truv.com/docs/api-reference/document-collections/object Find more information about document collections API. Document Collections provide a way to upload, process, and manage multiple documents in a single workflow. Documents are automatically validated and processed using AI-powered categorization to identify document types such as paystubs, W2s, 1099s, and more. # Quickstart We recommend using Python (works on all platforms): ```python theme={null} # save as prepare_request.py import base64, json, sys with open(sys.argv[1], 'rb') as f: content = base64.b64encode(f.read()).decode() json.dump({ "documents": [{ "mime_type": "application/pdf", "content": content, "filename": sys.argv[1] }] }, open('request.json', 'w')) ``` Run it: ```bash theme={null} python prepare_request.py mydocument.pdf curl -X POST https://prod.truv.com/v1/documents/collections/ \ -H "Content-Type: application/json" \ -d @request.json ``` # Collection Attributes The table below covers the attributes returned when listing document collections. | Attribute | Type | Description | | :--------------- | :-------- | :------------------------------------------------- | | collection\_id | string | Unique identifier for the collection | | created\_at | date-time | Date and time when the collection was created | | updated\_at | date-time | Date and time when the collection was last updated | | files\_count | integer | Number of uploaded files in the collection | | documents\_count | integer | Number of recognized documents in the collection | | users\_count | integer | Number of users associated with the collection | # Uploaded File Attributes The table below covers the attributes for uploaded files within a collection. | Attribute | Type | Description | | :----------------- | :----------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------- | | file\_id | string | Unique identifier for the uploaded file | | filename | string | Name of the uploaded file | | mime\_type | string | MIME type of the file, valid values: `application/pdf`, `image/jpeg`, `image/png`, `image/tiff`, `image/webp`, `image/x-ms-bmp`, `image/heic`, `image/heif` | | status | string | Processing status of the file, valid values: `pending`, `validating`, `validated`, `invalid`, `duplicate`, `processing`, `successful`, `failed` | | validations | object, null | File validation results containing `is_viable_size`, `is_supported_type`, `is_accessible`, `is_valid`, `is_readable`, `is_unique` | | user\_id | string, null | Truv user ID associated with this file | | external\_user\_id | string, null | External system user ID associated with this file | # Recognized Document Attributes The table below covers the attributes for documents recognized within uploaded files. | Attribute | Type | Description | | :----------------- | :----------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | document\_id | string | Unique identifier for the recognized document | | file\_id | string | ID of the uploaded file containing this document | | document\_type | string | Type of the document, valid values: `PAYSTUB`, `W2`, `F1099`, `F1040`, `BANK_STATEMENT`, `PASSPORT`, `GREEN_CARD`, `DRIVER_LICENSE`, `LETTER_OF_VERIFICATION`, `UTILITY_BILL`, `LEASE_AGREEMENT`, `INSURANCE_HOME_POLICY`, `INSURANCE_AUTO_POLICY`, `VOLUNTEER_LETTER`, `OTHER` | | document\_subtype | string, null | Subtype of the document, valid values: `F1099_MISC`, `F1099_NEC`, `F1099_DIV`, `F1099_INT`, `F1099_G`, `F1099_R`, `F_SSA1099`, `VOL_TRANSCRIPT`, `VOL_HOURS_LOG` | | status | string | Processing status of the document, valid values: `successful`, `failed`, `rejected` | | first\_name | string, null | First name extracted from the document | | last\_name | string, null | Last name extracted from the document | | user\_id | string, null | Truv user ID associated with this document | | external\_user\_id | string, null | External system user ID associated with this document | | start\_page | integer | Starting page number of the document within the file | | end\_page | integer | Ending page number of the document within the file | # Finalization After documents in a collection have been processed and categorized, use the finalize endpoint to create links for the recognized documents. This step converts the pre-processed documents into usable Truv links for retrieving income and employment data. ## Finalize request attributes The finalize endpoint returns a response containing users with their associated links and documents. ### User Object | Attribute | Type | Description | | :----------------- | :----------- | :--------------------------------------------- | | id | string | Truv user ID | | external\_user\_id | string, null | External system user ID (optional) | | links | array | List of links created or updated for this user | ### Link Object | Attribute | Type | Description | | :-------- | :----- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | link\_id | string | Truv link ID | | status | string | Current status of the link, valid values: `new`, `parse`, `full_parse`, `done`, `no_data`, `config_error`, `error`, `unavailable`. Final statuses (processing complete): `done`, `no_data`, `config_error`, `error`, `unavailable` | | documents | array | List of documents associated with this link | ### Document Object (in Finalize Response) | Attribute | Type | Description | | :---------------- | :----------- | :------------------------------------------------------ | | id | string | Recognized document ID | | document\_type | string | Type of the document (uppercase), e.g., `PAYSTUB`, `W2` | | document\_subtype | string, null | Subtype of the document (uppercase, optional) | # Endpoints Use the endpoints below to manage document collections. * [List all document collections](/api-reference/document-collections/collections_list) * [Create a new document collection](/api-reference/document-collections/collections_create) * [Get document collection details](/api-reference/document-collections/collections_retrieve) * [Delete a document collection](/api-reference/document-collections/collections_delete) * [Upload files to existing collection](/api-reference/document-collections/collections_upload) * [Get uploaded file details](/api-reference/document-collections/collections_uploaded_file_retrieve) * [Delete an uploaded file](/api-reference/document-collections/collections_uploaded_file_delete) * [Finalize a collection](/api-reference/document-collections/collections_finalize_create) * [Get collection finalization results](/api-reference/document-collections/collections_finalize_retrieve) # Example responses *** ## Collection detail response ```json theme={null} { "collection_id": "a1b2c3d4e5f6478899aabbccddeeff00", "created_at": "2025-11-11T10:00:00Z", "updated_at": "2025-11-11T10:05:00Z", "uploaded_files": [ { "file_id": "f1234567890abcdef1234567890abcde", "filename": "paystub.pdf", "mime_type": "application/pdf", "status": "successful", "validations": { "is_viable_size": true, "is_supported_type": true, "is_accessible": true, "is_valid": true, "is_readable": true, "is_unique": true }, "user_id": "a1b2c3d4e5f6478899aabbccddeeff00", "external_user_id": null } ], "documents": [ { "document_id": "d0c1234567890abcdef1234567890abc", "file_id": "f1234567890abcdef1234567890abcde", "document_type": "PAYSTUB", "document_subtype": null, "status": "successful", "first_name": "John", "last_name": "Doe", "user_id": "a1b2c3d4e5f6478899aabbccddeeff00", "external_user_id": null, "start_page": 1, "end_page": 2 } ], "users": [ { "id": "a1b2c3d4e5f6478899aabbccddeeff00", "external_user_id": "ext_user_789", "first_name": "John", "last_name": "Doe" } ] } ``` *** ## Finalization response ```json theme={null} { "users": [ { "id": "a1b2c3d4e5f6478899aabbccddeeff00", "external_user_id": "ext_user_789", "links": [ { "link_id": "c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9", "status": "done", "documents": [ { "id": "d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6", "document_type": "PAYSTUB", "document_subtype": null } ] } ] } ] } ``` # Employment Webhook Events Source: https://truv.com/docs/api-reference/employment/events Webhook events for employment data creation and updates. Subscribe to these events via [Webhooks](/api-reference/webhooks/object) to receive notifications when employment data becomes available or changes during a refresh. All webhook payloads include the [common fields](/api-reference/webhooks/object#webhook-payload-structure) plus the event-specific fields below. *** ## employment-created Fires when employment data has been extracted. This occurs once per [Link](/api-reference/links/object) for each non-refresh [Task](/api-reference/tasks/object) completion. Multiple responses are sent when additional employments are found. **Additional fields:** | Field | Description | | --------------- | ---------------------------------------------------- | | `object_id` | The employment record ID | | `task_id` | The associated Task | | `tracking_info` | Custom metadata passed via `bridge_token` (nullable) | ```json theme={null} { "webhook_id": "984e2cf9b69e4bc29acea714f1d5a554", "task_id": "c32fb957ec7246828da56be7516da765", "link_id": "9915c50cc047413bb810767f218390f8", "product": "employment", "data_source": "payroll", "tracking_info": null, "event_type": "employment-created", "event_created_at": "2022-08-23T17:32:19.307951Z", "object_id": "427abebd8590457e8332fdff77fc412f", "user_id": "88fef4cea64c40b5ad6727cc9b0b9fdc", "template_id": null } ``` *** ## employment-updated Fires when employment data has changed during a refresh Task. **Additional fields:** Same as `employment-created` (`object_id`, `task_id`, `tracking_info`). ```json theme={null} { "webhook_id": "984e2cf9b69e4bc29acea714f1d5a554", "task_id": "c32fb957ec7246828da56be7516da765", "link_id": "9915c50cc047413bb810767f218390f8", "product": "employment", "data_source": "payroll", "tracking_info": null, "event_type": "employment-updated", "event_created_at": "2022-08-23T17:32:19.307951Z", "object_id": "427abebd8590457e8332fdff77fc412f", "user_id": "88fef4cea64c40b5ad6727cc9b0b9fdc", "template_id": null } ``` # List all employments Source: https://truv.com/docs/api-reference/employment/link-employments GET /v1/links/{link_id}/employments/ The endpoint returns a list of all employments. # Retrieve an employment Source: https://truv.com/docs/api-reference/employment/link-last-employment GET /v1/links/{link_id}/employment/ Get the most recent employment data # The Employment object Source: https://truv.com/docs/api-reference/employment/object Find information related to user employment with the endpoints in this section. Employment objects track the most recent user employment data, such as employer name, manager name, employer address, and other information. The employment data is associated with the `link_id` from Truv's Income and Employment product type. The `employments[]` array can contain multiple entries. These may represent **different employers** or **multiple positions at the same employer**. Multiple positions at the same employer occur when an employee is rehired after an absence -- each employment period appears as a separate entry. This is distinct from a promotion or title change, which updates the existing entry rather than creating a new one. When multiple entries exist for the same employer, use `original_hire_date` to identify the very first hire date at that employer and `start_date` to identify when the current (or most recent) employment period began. If the employee was never rehired, these two dates are the same. **Sandbox testing:** Use `multiple.employments` to test multiple entries from different employers, and `multiple.employments2` to test multiple positions at the same employer (rehire scenario). ## Attributes The values in this table cover attributes for the employment endpoints. | Attribute | Type | Description | | :---------------------- | :--------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | id | string | Unique ID of selected employee | | is\_active | boolean | Status of active employment | | job\_title | string | Job title of employee | | job\_type | string | Job types of employee: `F` - Full Time, `P` - Part Time, `S` - Seasonal, `D` - Daily, `C` - Contract, `V` - Volunteer | | start\_date | date | Start of the current employment period. For rehires, this is the date the employee was most recently hired back. | | original\_hire\_date | date | The very first hire date at this employer. Differs from `start_date` when the employee was rehired after a separation. | | end\_date | date | Employee's employment end date | | income | string | Base income amount, not including commission or bonuses | | income\_unit | string | Pay interval for income field reference: `YEARLY` - Annual income, `MONTHLY` - Monthly income, `WEEKLY` - Weekly income, `DAILY` - Daily income, `HOURLY` - Hourly income | | pay\_rate | string | Payment rate per pay cycle | | pay\_frequency | string | Pay frequency: `M` - Monthly, `SM` - Semi-Monthly, `W` - Weekly, `BW` - Bi-Weekly, `A` - Annually, `C` - Commission | | external\_last\_updated | date | Indicates date of last update for employment data from payroll provider | | derived\_fields | array of strings | Array of derived fields | | missing\_data\_fields | array of strings | List of missing data fields from payroll response | | manager\_name | string | Supervisor name of employee | | company | object | [Company object](#company-object) | ### Company object This table covers values within the company object. | Attribute | Type | Description | | :-------- | :----- | :-------------------------------- | | name | string | Company name | | address | object | [Address object](#address-object) | | phone | string | Company phone number | | ein | string | Employer Identification Number | #### Address object The values in this table are for the address object of the company. | Attribute | Type | Description | | :-------- | :----- | :---------- | | street | string | Street | | city | string | City | | state | string | State | | zip | string | Zip | | country | string | Country | *** ## Endpoint View the available endpoint for employment below. * [Retrieve an employment](/api-reference/employment/link-employments) *** ## Example response The JSON object below is the sample response for the endpoint. ```json theme={null} { "id": "24d7e80942ce4ad58a93f70ce4115f5c", "income": "70000.00", "income_unit": "YEARLY", "pay_rate": "6500.00", "pay_frequency": "M", "is_active": false, "job_title": "PR associate", "job_type": "F", "start_date": "2018-01-01", "original_hire_date": "2017-06-21", "end_date": "2022-12-11", "external_last_updated": "2022-12-11", "derived_fields": [ "is_active" ], "missing_data_fields": [ "w2s" ], "manager_name": "Jenny McDouglas", "company": { "name": "Facebook Demo", "address": { "street": "1 Morgan Ave", "city": "Los Angeles", "state": "CA", "zip": "90210", "country": "US" }, "phone": "6503087300", "ein": "12-345678" } } ``` # Identity Webhook Events Source: https://truv.com/docs/api-reference/identity/events Webhook events for identity profile creation and updates. Subscribe to these events via [Webhooks](/api-reference/webhooks/object) to receive notifications when identity data becomes available or changes during a refresh. All webhook payloads include the [common fields](/api-reference/webhooks/object#webhook-payload-structure) plus the event-specific fields below. *** ## profile-created Fires when identity and profile information has been extracted. This occurs once per [Link](/api-reference/links/object) for each non-refresh [Task](/api-reference/tasks/object) completion. **Additional fields:** | Field | Description | | --------------- | ---------------------------------------------------- | | `object_id` | The identity profile record ID | | `task_id` | The associated Task | | `tracking_info` | Custom metadata passed via `bridge_token` (nullable) | ```json theme={null} { "webhook_id": "81e4552a215d4f4695bc6fae2675aeee", "task_id": "c32fb957ec7246828da56be7516da765", "link_id": "9915c50cc047413bb810767f218390f8", "product": "employment", "data_source": "payroll", "tracking_info": null, "event_type": "profile-created", "event_created_at": "2022-08-23T17:32:19.295569Z", "object_id": "25d588c7cc1c43178375bdc1bc9852ac", "user_id": "88fef4cea64c40b5ad6727cc9b0b9fdc", "template_id": null } ``` *** ## profile-updated Fires when identity and profile information has changed during a refresh Task. **Additional fields:** Same as `profile-created` (`object_id`, `task_id`, `tracking_info`). ```json theme={null} { "webhook_id": "81e4552a215d4f4695bc6fae2675aeee", "task_id": "c32fb957ec7246828da56be7516da765", "link_id": "9915c50cc047413bb810767f218390f8", "product": "employment", "data_source": "payroll", "tracking_info": null, "event_type": "profile-updated", "event_created_at": "2022-08-23T17:32:19.295569Z", "object_id": "25d588c7cc1c43178375bdc1bc9852ac", "user_id": "88fef4cea64c40b5ad6727cc9b0b9fdc", "template_id": null } ``` # Retrieve an identity Source: https://truv.com/docs/api-reference/identity/link-identity GET /v1/links/{link_id}/identity/ Get the identity data for the user # The Identity object Source: https://truv.com/docs/api-reference/identity/object View information and details about the user's identity. Identity includes details about the user's personal identifiable information, such as the user's name, address, contact information, and other information. The information about the user is connected to the `link_id` of Truv's product types. ## Attributes The values in the table below cover attributes for identity. | Attribute | Type | Description | | :--------------- | :----- | :------------------------------------------------------------ | | id | string | Unique user ID | | created\_at | string | ISO 8601 value for first time retrieving user's identity info | | updated\_at | string | ISO 8601 value for last time retrieving user's identity info | | first\_name | string | First name | | last\_name | string | Last name | | full\_name | string | Full name | | middle\_initials | string | Middle initials | | email | string | Email address | | ssn | string | Social Security Number | | date\_of\_birth | date | Date of birth | | home\_address | object | [Address object](#address-object) | ### Address object The values in this table are for the address object of the user. | Attribute | Type | Description | | :-------- | :----- | :---------- | | street | string | Street | | city | string | City | | state | string | State | | zip | string | Zip | | country | string | Country | *** ## Endpoint The item below is the available endpoint for Identity. * [Retrieve an identity](/api-reference/identity/link-identity) *** ## Example response The response below is the JSON object for the endpoint. ```json theme={null} { "id": "710097b33ec14f898df3644b563430e1", "created_at": "2022-08-10T09:30:48.520089Z", "updated_at": "2022-08-10T09:30:48.520114Z", "first_name": "John", "last_name": "Doe", "full_name": "John Doe", "middle_initials": null, "email": "john.doe@gmail.com", "ssn": "221122112", "date_of_birth": "1992-03-03", "home_address": { "zip": "94062", "city": "Redwood City", "state": "CA", "street": "35 Dry Ridge Rd", "country": "US" } } ``` # Retrieve the most recent bank income report Source: https://truv.com/docs/api-reference/income-insights/bank-income-report-retrieve GET /v1/links/{link_id}/income/transactions/reports/ Retrieves the most recent bank income report for the specified link. This endpoint returns the latest generated report containing transaction-based income analysis and verification data. # Create a user bank income insights report Source: https://truv.com/docs/api-reference/income-insights/income-insights-report-create POST /v1/users/{user_id}/income_insights/reports/ The endpoint creates a bank income insights report for the user. # Retrieve a user bank income insights report Source: https://truv.com/docs/api-reference/income-insights/income-insights-report-retrieve GET /v1/users/{user_id}/income_insights/reports/{report_id}/ The endpoint retrieves a bank income insights report for the user. # The User Income Insights object Source: https://truv.com/docs/api-reference/income-insights/object Find more information on data returned by the user-level bank income report. The Income Insights report analyzes transaction data across a user's connected bank accounts to detect income sources, calculate averages, and forecast future income. # Attributes Values, data types, and descriptions for the report-level metadata in the response. | Attribute | Type | Description | | :-------------------- | :--------------- | :------------------------------------------------------------------------------------------------- | | report\_id | string | Unique identifier of the report | | created\_at | date-time | Timestamp when report was created | | completed\_at | date-time | Timestamp when report was completed | | days\_requested | integer | Number of days for requested transactions history | | links | array of objects | List of financial institutions connected, see [Link object](#link-object) | | bank\_income\_summary | object | Summary of income over all accounts, see [Bank Income Summary object](#bank-income-summary-object) | # Link object The information in this table is for values in the Links object. | Attribute | Type | Description | | :-------------------- | :--------------- | :---------------------------------------------------------------------------------- | | link\_id | string | Unique identifier of the link | | created\_at | date-time | Timestamp when the link was first created | | updated\_at | date-time | Timestamp of the most recent update made to the link | | provider | string | ID of the financial institution | | provider\_name | string | Name of the financial institution | | tracking\_info | string | Additional (optional) identifier passed by the user | | accounts | array of objects | List of demand-deposit accounts connected, see [Account object](#account-object) | | bank\_income\_sources | array of objects | List of income sources, see [Bank Income Source object](#bank-income-source-object) | ## Account object The information in this table is for values in the Accounts object. | Attribute | Type | Description | | :-------- | :--------------- | :--------------------------------------------------------------- | | id | string | Unique identifier of the account | | mask | string | The masked banking account number associated with the account | | nickname | string | An alternate name for the account | | type | enum | The type of account, see [Account Type enum](#account-type-enum) | | subtype | string | The sub-type of the account | | owners | array of objects | List of owners on the account, see [Owner object](#owner-object) | *** ## Owner object The information in this table is for values in the Owner object. | Attribute | Type | Description | | :------------- | :----- | :---------------------------------------------- | | id | string | Unique identifier of the owner | | full\_name | string | Account owner's full name | | email | string | Account owner's email address | | phone | string | Account owner's phone number | | address | object | Account owner's physical address | | relation\_type | string | The relationship this person has to the account | *** ## Bank income source object The information in this table is for values in the Bank Income Source object. | Attribute | Type | Description | | :------------------------------------------ | :--------------- | :--------------------------------------------------------------------------------------------------------------- | | start\_date | date | Earliest transaction date for this source | | end\_date | date | Latest transaction date for this source | | account\_id | string | Unique identifier of the associated account | | income\_description | string | A human-readable shorthand for the underlying transaction descriptions | | income\_category | string | The category of the income source, see [Income Category enum](#income-category-enum) | | pay\_frequency | enum | The rate at which income is deposited, see [Pay Frequency enum](#pay-frequency-enum) | | total\_amount | string | The sum of earnings for this income source, observed over the transaction history | | iso\_currency\_code | string | The ISO 4217 currency code for amounts in this source | | transaction\_count | integer | Number of income transactions for this source | | historical\_summary | array of objects | List of monthly summaries, see [Historical Summary object](#historical-summary-object) | | historical\_average\_monthly\_income | string | Historical average income deposited into the account, per calendar month, typically net of taxes and deductions. | | historical\_average\_monthly\_gross\_income | string | Historical average gross payment amount, per calendar month, predicted based on the transaction data. | | forecasted\_average\_monthly\_income | string | Forecasted income deposited into the account, per calendar month. | | employer | object | The normalized employer for the income source, see [Employer object](#employer-object) | *** ## Historical summary object The information in this table is for values in the Historical summary object. | Attribute | Type | Description | | :------------------ | :--------------- | :--------------------------------------------------------------------------------------------------------------------------------- | | start\_date | date | The first date of this monthly period; will be the first day of the month unless the transaction history does not go back that far | | end\_date | date | The last date of this monthly period; will be the first day of the month unless such date is in the future | | total\_amount | string | Total amount of earnings for this monthly period | | iso\_currency\_code | string | The ISO 4217 currency code for amounts in this period | | transactions | array of objects | List of transactions, see [Transaction object](#transaction-object) | *** ## Transaction object The information in this table is for values in the Transaction object. | Attribute | Type | Description | | :------------------ | :------ | :---------------------------------------------------------- | | transaction\_id | string | Unique identifier for the transaction | | amount | string | Deposit amount | | iso\_currency\_code | string | The ISO 4217 currency code for this transaction | | date | date | Date the amount was posted to the account | | check\_number | string | The check number for the transaction | | description | string | A human-readable description for the transaction | | pending | boolean | True if the status of the transaction is pending or not set | *** ## Employer object The information in this table is for values in the Employer object. | Attribute | Type | Description | | :-------- | :----- | :--------------------------------- | | id | string | Unique identifier for the employer | | name | string | Name of the employer | | logo\_url | string | URL for the employer's logo image | # Bank Income Summary object The information in this table is for values in the Bank Income Summary object. | Attribute | Type | Description | | :------------------------------------------ | :--------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | start\_date | string | Earliest transaction date among all income sources | | end\_date | string | Latest transaction date among all income sources | | income\_sources\_count | integer | Number of income sources for this user | | income\_categories\_count | integer | Number of income categories for this user | | income\_transactions\_count | integer | Number of income transactions for this user | | total\_amounts | array of objects | Total amount of income observed in the transaction history, over all sources. One per currency. See [Total Amount object](#total-amount-object) | | historical\_average\_monthly\_income | array of objects | Total monthly average income earned historically, over all sources. One per currency. See [Total Amount object](#total-amount-object) | | historical\_average\_monthly\_gross\_income | array of objects | Total monthly average gross income earned historically, over all sources. One per currency. Gross amounts are estimated from transactions. See [Total Amount object](#total-amount-object) | | forecasted\_average\_monthly\_income | array of objects | Total forecasted monthly average income, over all sources. One per currency. See [Total Amount object](#total-amount-object) | | historical\_annual\_gross\_income | array of objects | Annualized gross income earned historically, over all sources. One per currency. See [Total Amount object](#total-amount-object) | | historical\_annual\_income | array of objects | Annualized income earned historically, over all sources. One per currency. See [Total Amount object](#total-amount-object) | | forecasted\_annual\_income | array of objects | Annualized forecasted income, over all sources. One per currency. See [Total Amount object](#total-amount-object) | *** ## Total amount object The information in this table is for values in the Total Amount object. | Attribute | Type | Description | | :------------------ | :----- | :---------------------------------------- | | amount | string | Total amount | | iso\_currency\_code | string | The ISO 4217 currency code for the amount | # Enumerated Types The following sets show the available values that an enum attribute could take. *** ## Account type enum | Attribute | Type | | :-------- | :----- | | CHECKING | string | | SAVINGS | string | | PREPAID | string | *** ## Income category enum | Value | Description | Grossed up | | :--------------------- | :--------------------------- | :--------- | | PAYCHECK | Regular paycheck deposits | Yes | | RETIREMENT | Retirement income | Yes | | GOVERNMENT\_EMPLOYMENT | Government employment income | Yes | | EWA\_PAYROLL | Earned wage access payroll | Yes | | GIG\_ECONOMY | Gig economy income | No | | GOVERNMENT\_BENEFITS | Government benefits | No | | RENTAL | Rental income | No | | UNEMPLOYMENT | Unemployment benefits | No | | PRIVATE\_BENEFITS | Private benefits | No | | CASH\_OR\_CHECK | Cash or check deposits | No | | TAX\_CREDITS | Tax credit payments | No | | P2P\_TRANSFER | Peer-to-peer transfers | No | *** ## Pay frequency enum | Attribute | Type | | :---------- | :----- | | MONTHLY | string | | SEMIMONTHLY | string | | BIWEEKLY | string | | WEEKLY | string | | ANNUAL | string | | SEMIANNUAL | string | | COMMISSION | string | ## Permissible purpose enum A permissible purpose is required when creating an Income Insights report. This identifies why you are requesting the consumer's financial data. | Value | Use case | | :------------------------------------------ | :--------------------------------------- | | `ACCOUNT_REVIEW_CREDIT` | Reviewing an existing credit account | | `ACCOUNT_REVIEW_NON_CREDIT` | Reviewing an existing non-credit account | | `EMPLOYMENT` | Employment verification | | `EXTENSION_OF_CREDIT` | Evaluating a credit application | | `LEGITIMATE_BUSINESS_NEED_TENANT_SCREENING` | Tenant screening | | `LEGITIMATE_BUSINESS_NEED_OTHER` | Other legitimate business need | | `WRITTEN_INSTRUCTION_PREQUALIFICATION` | Prequalification with written consent | | `WRITTEN_INSTRUCTION_OTHER` | Other use with written consent | # Endpoints View more information about the available endpoints for Income Insights reports. * Create an income-insights report * Retrieve an income-insights report # Example response The JSON below is a sample response for the endpoint. ```json theme={null} { "report_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "created_at": "2022-05-04T11:30:00Z", "completed_at": "2022-05-04T12:00:00Z", "days_requested": 61, "links": [ { "link_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "created_at": "2022-05-04T11:30:00Z", "updated_at": "2022-05-04T12:00:00Z", "provider": "Chase", "tracking_info": "string", "accounts": [ { "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "mask": "****1234", "nickname": "My account", "type": "CHECKING", "subtype": "MONEY_MARKET", "owners": [ { "id": "2b623fa2fa9e49cea17d9692caa884c5", "full_name": "John Doe", "email": "john.doe@example.com", "phone": "14155554193", "address": { "street": "1 Morgan Ave", "city": "Los Angeles", "state": "CA", "zip": "90210", "country": "US" }, "relation_type": "AUTHORIZED_USER" } ] } ], "bank_income_sources": [ { "start_date": "2022-05-04", "end_date": "2022-05-04", "account_id": "24d7e80942ce4ad58a93f70ce4115f5c", "income_description": "Paycheck", "income_category": "PAYCHECK", "pay_frequency": "SM", "total_amount": "200.31", "iso_currency_code": "USD", "transaction_count": 1, "historical_summary": [ { "start_date": "2022-05-04", "end_date": "2022-05-04", "total_amount": "200.31", "iso_currency_code": "USD", "transactions": [ { "amount": "200.31", "iso_currency_code": "USD", "date": "2022-05-04", "check_number": "string", "description": "string", "pending": true, "transaction_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6" } ] } ], "historical_average_monthly_income": "10000.00", "historical_average_monthly_gross_income": "12000.00", "forecasted_average_monthly_income": "10000.00", "employer": { "id": "meta", "name": "Meta", "logo_url": "string" } } ] } ], "bank_income_summary": { "start_date": "2022-05-04", "end_date": "2022-05-04", "income_sources_count": 1, "income_categories_count": 1, "income_transactions_count": 1, "total_amounts": [ { "amount": "200.31", "iso_currency_code": "USD" } ], "historical_average_monthly_gross_income": [ { "amount": "200.31", "iso_currency_code": "USD" } ], "historical_average_monthly_income": [ { "amount": "200.31", "iso_currency_code": "USD" } ], "forecasted_average_monthly_income": [ { "amount": "200.31", "iso_currency_code": "USD" } ], "historical_annual_gross_income": [ { "amount": "200.31", "iso_currency_code": "USD" } ], "historical_annual_income": [ { "amount": "200.31", "iso_currency_code": "USD" } ], "forecasted_annual_income": [ { "amount": "200.31", "iso_currency_code": "USD" } ] } } ``` # Retrieve an insurance report Source: https://truv.com/docs/api-reference/insurance/link_detail_reports_insurance GET /v1/links/{link_id}/insurance/report/ The endpoint returns the Insurance report. # Retrieve an auto insurance report Source: https://truv.com/docs/api-reference/insurance/link_detail_reports_insurance_auto GET /v1/links/{link_id}/insurance/report/auto/ The endpoint returns the auto insurance report. # Retrieve an home insurance report Source: https://truv.com/docs/api-reference/insurance/link_detail_reports_insurance_home GET /v1/links/{link_id}/insurance/report/home/ The endpoint returns the home insurance report. # The Insurance object Source: https://truv.com/docs/api-reference/insurance/object View the comprehensive reference information for insurance data responses. ## Attributes The information in the table below covers the values for insurance report responses. | Attribute | Type | Description | | :------------- | :----- | :--------------------------------------------- | | id | string | Unique identifier | | status | string | Status from Connection Lifecycle | | finished\_at | string | Time report was finished | | access\_token | string | Access token for Link to payroll provider | | tracking\_info | string | Information passed to Truv Bridge from partner | | insurance | object | List of insurances, see Insurance object | | provider | string | Insurance Provider ID | | identity | object | Person's identity information | | pdf\_report | uri | Insurance report in PDF format | ### Insurance object These values are for the insurance object field. | Attribute | Type | Description | | :--------------- | :----- | :---------------------- | | policies | object | List of policies | | drivers | object | List of drivers | | addresses | object | List of addresses | | driving\_records | object | List of driving records | | agents | object | List of agents | #### Policies object View the policies object values in the table below. | Attribute | Type | Description | | :-------------------------- | :--------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | id | string | Policy ID | | policy\_type | string | Type of policy `AUTO` `BOAT` `CONDO` `FARMOWNER` `FLOOD` `HOMEOWNERS` `LANDLORD` `LIFE` `MOTORCYCLETERM_LIFE` `UNIVERSAL_LIFE` `WHOLE_LIFE` `RENTERS` `SNOWMOBILE` `UMBRELLARECREATIONAL_VEHICLE` `FIRE` `TRAILER` `PERSONAL_ARTICLES` `EARTHQUAKEBUSINESS_OWNERS` `COMMERCIAL_UMBRELLA` `COMMERCIAL_AUTO` `COMMERCIAL_FIRECOMBO` `OFFROAD_VEHICLE` `WORKERS_COMPENSATION` `MOBILE_HOME` `PETPERSONAL_LIABILITY` `GENERAL_LIABILITY` `ERRORS_AND_OMISSIONS` `INLAND_MARINEGARAGE` `EXCESS_LIABILITY` `CYBER` `IDENTITY_THEFT` `NAMED_NON_OWNERCLASSIC_CAR` | | name | string | Human-friendly name | | description | string | Human-friendly description | | carrier\_policy\_number | string | Carrier policy number | | effective\_date | date-time | Policy effective date | | expiry\_date | date-time | Policy expiration date | | renewal\_date | date-time | Policy renewal date | | canceled\_date | date-time | Policy canceled date | | total\_premium\_cents | integer | Total policy premium in cents | | deductible\_cents | integer | Commercial policy deductible in cents | | carrier\_name | string | Insurance carrier name | | status | string | Policy status `ACTIVE` `CANCELLED` `EXPIRED` `UNVERIFIED` `PENDING_ACTIVATION` `PENDING_CANCELLATION` | | paid\_in\_full | Boolean | Status of policy fully paid | | dwellings | array of objects | List of dwellings, see [Dwellings object](#dwellings-object) | | vehicles | array of objects | List of vehicles, see [Vehicles object](#vehicles-object) | | commercial\_named\_insureds | array of objects | List of commercial named insureds, see [Commercial named insureds object](#commercial-named-insureds-object) | | named\_insureds | array of objects | List of named insureds, see [Named insureds object](#named-insureds-object) | | claims | array of objects | List of claims, see [Claims object](#claims-object) | | loss\_events | array of objects | List of loss events, see [Loss events object](#loss-events-object) | | documents | array of objects | List of documents, see [Documents object](#documents-object) | ##### Dwellings object The values in this table are for the dwellings object. | Attribute | Type | Description | | :----------------------- | :--------------- | :---------------------------------------------------------------------------------------- | | id | string | Dwelling ID | | address | object | Address object | | replacement\_cost\_cents | integer | Replacement cost in cents | | cash\_value\_cents | integer | Cash value in cents | | coverages | array of objects | List of dwelling coverages, see [Dwellings coverages object](#dwellings-coverages-object) | | mortgagees | array of objects | List of mortgagee objects, see [Mortgagees object](#dwellings-mortgagees-object) | ###### Dwellings coverages object Find the information for the dwellings coverages object below. | Attribute | Type | Description | | :-------------------------- | :------ | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | id | string | Dwelling coverage ID | | name | string | Name of coverage item `BASE` `DWELLING` `OTHER_STRUCTURE` `PERSONAL_PROPERTY` `BUSINESS_PROPERTY` `LOSS_OF_USE` `LOSS_ASSESSMENTS` `PERSONAL_LIABILITY` `PREMISES_LIABILITY` `REPLACEMENT_COST_FULL_VALUE` `REPLACEMENT_COST_DWELLING` `REPLACEMENT_COST_CONTENTS` `GUEST_MEDICAL_PROTECTION` `DAMAGE_TO_PROPERTY_OF_OTHERS` `MEDICAL_PAYMENTS` `ADDITIONAL_LIVING_EXPENSE` `FAMILY_LIABILITY_PROTECTION` `BUILDING_CODES` `WINDSTORM_OR_HAIL` `HURRICANE` `ALL_OTHER_PERILS` `ALL_PERILS` `EARTHQUAKE` `PORTABLE_ELECTRONICS` `FASHION_ITEMS` `FINE_ART` `BICYCLE` `CAMERA` `JEWELRY` `MUSICAL_INSTRUMENT` `BUILDINGCONTENTS` `ICC` | | premium\_cents | integer | Premium paid for coverage item, in cents | | per\_person\_limit\_cents | integer | Per-person limit, in cents | | per\_incident\_limit\_cents | integer | Per-incident limit, in cents | | deductible\_cents | integer | Deductible, in cents | | is\_declined | Boolean | Status of coverage item | ###### Dwellings mortgagees object The mortgagees object values for dwellings are in the table below. | Attribute | Type | Description | | :----------- | :----- | :----------------------------------------- | | id | string | ID of mortgagee | | name | string | Name of mortgagee | | type | string | Type of mortgagee `FIRST` `SECOND` `THIRD` | | loan\_number | string | Mortgage loan number | | address | object | Address object | ##### Vehicles object View the information for the vehicles object below. | Attribute | Type | Description | | :-------------------- | :--------------- | :------------------------------------------------------------------------------------- | | id | string | Vehicle ID | | year | integer | Year | | make | string | Manufacturer | | model | string | Model | | series | string | Series | | series2 | string | Series 2 | | type | string | Vehicle type | | annual\_mileage | integer | Annual mileage | | vin | string | Vehicle identification number | | purchase\_date | date-time | Purchase date | | is\_removed | Boolean | Status of vehicle policy | | lien\_holder | string | Vehicle lien holder name | | garaging\_address | object | Address object | | lien\_holder\_address | object | Address object | | coverages | array of objects | List of vehicle coverages, see [Vehicles coverages object](#vehicles-coverages-object) | ###### Vehicles coverages object The values in the table below are for the vehicle coverages object. | Attribute | Type | Description | | :----------------------------------- | :------ | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | id | string | Vehicle coverage ID | | name | string | Name of coverage item `SINGLE_LIMIT_LIABILITY` `BODILY_INJURY_LIABILITY` `PROPERTY_DAMAGE_LIABILITY` `SUPPLEMENTAL_SPOUSAL_LIABILITY` `PERSONAL_INJURY_PROTECTION` `COMPREHENSIVE` `FULL_GLASS` `COLLISION_DEDUCTIBLE_WAIVER` `COLLISION` `UNINSURED_MOTORISTS` `UNINSURED_MOTORIST_BODILY_INJURY_LIABILITY` `UNINSURED_MOTORIST_PROPERTY_DAMAGE_LIABILITY` `UNINSURED_MOTORIST_BODILY_INJURY_AND_PROPERTY_DAMAGE_LIABILITY` `UNDERINSURED_MOTORISTS` `UNDERINSURED_MOTORIST_BODILY_INJURY_LIABILITY` `UNDERINSURED_MOTORIST_PROPERTY_DAMAGE_LIABILITY` `UNDERINSURED_MOTORIST_BODILY_INJURY_AND_PROPERTY_DAMAGE_LIABILITY` `UNINSURED_AND_UNDERINSURED_MOTORISTS` `UNINSURED_AND_UNDERINSURED_MOTORIST_BODILY_INJURY_LIABILITY` `UNINSURED_AND_UNDERINSURED_MOTORIST_PROPERTY_DAMAGE_LIABILITY` `UNINSURED_AND_UNDERINSURED_MOTORIST_BODILY_INJURY_AND_PROPERTY_DAMAGE_LIABILITY` `TOWING_AND_LABOR LOAN_OR_LEASE_ASSISTANCE` `RIDESHARE_GAP_PROTECTION` `MEDICAL_PAYMENTS` `ADDITIONAL_LIVING_EXPENSE` `FAMILY_LIABILITY_PROTECTION` `BUILDING_CODES` `EMERGENCY_ROAD_SERVICE` `RENTAL_REIMBURSEMENT` `CAR_RENTAL_AND_TRAVEL_EXPENSES` `MECHANICAL_BREAKDOWN` `SUPPLEMENTAL_UNINSURED_AND_UNDERINSURED_MOTORISTS` `EMERGENCY_EXPENSE` `REPLACEMENT_COST_PERSONAL_EFFECTS` `VACATION_LIABILITY_COVERAGE` `RV_MEDICAL` `EXTENDED_BENEFITS` `WAGE_EARNER_DISABILITY_BENEFITS` `ESSENTIAL_SERVICES_DISABILITY_BENEFITS` `DEATH_BENEFIT` `CAR_REPLACEMENT_ASSISTANCE` `FULL_TORT` `LIMITED_TORT` `COMBINED_SINGLE_LIMIT` | | per\_day\_limit\_cents | integer | Per-day limit, in cents | | per\_mile\_premium\_tenth\_of\_cents | integer | Premium per mile, in tenth of cents | | premium\_cents | integer | Premium paid for coverage item, in cents | | per\_person\_cents | integer | Per-person limit, in cents | | per\_incident\_limit\_cents | integer | Per-incident limit, in cents | | deductible\_cents | integer | Deductible, in cents | | is\_declined | Boolean | Status of coverage item | ###### Vehicles drivers object The values below are for the vehicle drivers object. | Attribute | Type | Description | | :------------------------ | :------ | :--------------------------------------------------------------------------------------------------- | | id | string | Driver ID | | first\_name | string | First name | | middle\_name | string | Middle name | | last\_name | string | Last name | | drivers\_license | string | License number | | drivers\_license\_state | string | Driver license state | | date\_of\_birth\_str | string | Date of birth | | gender | string | Gender `MALE` `FEMALE` `NONBINARY` | | marital\_status | string | Marital status `SINGLE` `MARRIED` `DIVORCED` `WIDOWED` `SEPARATED` `CIVIL_UNION` | | relationship\_to\_insured | string | Relationship to the insured `INSURED` `SPOUSE` `BROTHER` `SISTER` `FATHER` `MOTHER` `DAUGHTER` `SON` | | is\_excluded | Boolean | Status of driver from the policy or vehicle | ##### Commercial named insureds object Use the table below for information about the commercial named insureds object. | Attribute | Type | Description | | :----------------- | :------ | :---------------------------------------------------------------------------------------------------------------------------------------------------------- | | id | string | Commercial named insured ID | | name | string | Name of insured | | form\_of\_business | string | Form of business `INDIVIDUAL` `PARTNERSHIP` `LIMITED_LIABILITY_COMPANY` `S_CORPORATION` `CORPORATION` `JOINT_VENTURE` `NOT_FOR_PROFIT_ORGANIZATION` `TRUST` | | gl\_code | string | General liability class code | | sic\_code | string | Standard industrial classification code | | naics\_code | string | North American Industry Classification System code | | fein | string | Federal Employer Identification number | | ssn | string | Social Security Number | | is\_primary | Boolean | Status of insured as primary | | address | object | Address object | ##### Named insureds object The values in this table are for the named insureds object. | Attribute | Type | Description | | :----------- | :------ | :--------------------------- | | id | string | Named insured ID | | first\_name | string | First name | | middle\_name | string | Middle name | | last\_name | string | Last name | | full\_name | string | Full name | | is\_primary | Boolean | Status of insured as primary | ##### Claims object The claims object values are in the table below. | Attribute | Type | Description | | :------------------------- | :-------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | id | string | Claim ID | | dwelling\_id | string | Dwelling ID | | vehicle\_id | string | Vehicle ID | | driver\_id | string | Driver ID | | carrier\_claim\_identifier | string | Carrier claim identifier | | date\_occurred | date-time | Date claim occurred | | type | string | Claim type `WIND_AND_HAIL_DAMAGE` `WATER_DAMAGE_AND_FREEZING` `FIRE_AND_LIGHTNING_DAMAGE` `OTHER_PROPERTY_DAMAGE` `PERSONAL_LIABILITY` `POWER_OUTAGE_OR_SURGE` `THEFT` `CAR_ACCIDENT` `WINDSHIELD_DAMAGE` `ANIMAL_COLLISION` `VANDALISM` `WEATHER` `EMERGENCY_ROADSIDE_ASSISTANCE` `MEDICAL` `HURRICANE_DAMAGE` `SEWAGE_BACKUP` | | status | string | Status `OPEN` `CLOSED` | | date\_closed | date-time | Date claim was closed | | payout\_cents | integer | Payout in cents | | representative\_name | string | Representative name | | representative\_phone | string | Representative phone number | | representative\_email | string | Representative email address | | address | object | Address object | ##### Loss events object Use the table below for information about the loss events object. | Attribute | Type | Description | | :---------------------- | :-------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | id | string | Loss event ID | | date\_of\_occurrence | date-time | Date loss event occurred | | date\_of\_claim | date-time | Date of claim | | type | string | Loss event type `BURGLARY_AND_THEFT` `WATER_DAMAGE_AND_FREEZING_DAMAGE` `WIND_AND_HAIL_DAMAGE` `FIRE` `CUSTOMER_SLIPS_AND_FALLS` `CUSTOMER_INJURY_AND_DAMAGE` `PRODUCT_LIABILITY` `STRUCK_BY_AN_OBJECT` `REPUTATIONAL_HARM` `VEHICULAR_ACCIDENT` `WINDSHIELD_DAMAGE` | | amount\_paid\_cents | integer | Amount paid in cents | | amount\_reserved\_cents | integer | Amount reserved in cents | | is\_subrogation | Boolean | Status of subrogation | | is\_claim\_open | Boolean | Status of claim | ##### Documents object The documents object values are in the table below. | Attribute | Type | Description | | :------------- | :-------- | :------------------------------------------------------------------------------------------------------------------------------------ | | id | string | Document ID | | title | string | Document title | | document\_type | string | Document type `INSURANCE_APPLICATION` `INSURANCE_BINDER` `DECLARATIONS` `ENDORSEMENT` `INSURANCE_ID_CARD` `VERIFICATION_OF_INSURANCE` | | date\_added | date-time | Document effective date | | file | string | File URL | #### Drivers object This table is a reference for the drivers object. | Attribute | Type | Description | | :------------------------ | :----- | :--------------------------------------------------------------------------------------------------- | | id | string | Driver ID | | first\_name | string | First name | | middle\_name | string | Middle name | | last\_name | string | Last name | | drivers\_license | string | License number | | drivers\_license\_state | string | Driver license state | | date\_of\_birth\_str | string | Date of birth | | gender | string | Gender `MALE` `FEMALE` `NONBINARY` | | marital\_status | string | Marital status `SINGLE` `MARRIED` `DIVORCED` `WIDOWED` `SEPARATED` `CIVIL_UNION` | | relationship\_to\_insured | string | Relationship to the insured `INSURED` `SPOUSE` `BROTHER` `SISTER` `FATHER` `MOTHER` `DAUGHTER` `SON` | #### Addresses object These values are for the address object. | Attribute | Type | Description | | :-------- | :----- | :---------- | | id | string | Address ID | | country | string | Country | | street | string | Street | | city | string | City | | state | string | State | | zip | string | Zip code | #### Driving records object The values below are within the driving records object. | Attribute | Type | Description | | :-------------- | :-------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | id | string | Driving record ID | | driver\_id | string | Driver ID | | incident\_date | date-time | Date incident occurred | | incident\_type | string | Incident type `ACCIDENT` `VIOLATION` | | violation\_type | string | The violation\_type is only available if `incident_type = VIOLATION` `MOVING` `SPEEDING` `RECKLESS_DRIVING` `DRIVING_WITHOUT_VALID_LICENSE` `HIT_AND_RUN` `DISTRACTED_DRIVING` `DRIVING_UNDER_INFLUENCE` `FAILURE_TO_YIELD` `TAILGATING` `OPEN_CONTAINER_OF_ALCOHOL` | | is\_at\_fault | Boolean | Status of driver at fault | #### Agents object For information about the agents object, view the table and values below. | Attribute | Type | Description | | :---------------- | :--------------- | :---------------------------------------------------------- | | id | string | Agent info record ID | | address\_id | string | Address ID of agent or agency location | | agency\_name | string | Name of agency, `agency_name` or `agent_full_name` required | | agent\_full\_name | string | Name of agent, `agency_name` or `agent_full_name` required | | phone\_number | string | Phone number for the agent or agency | | email | string | Email for the agent or agency | | policy\_ids | array of strings | List of Policy IDs associated to agent | ### Identity object Use this table for values from the identity object. | Attribute | Type | Description | | :--------------- | :----- | :-------------------------------------------------------------- | | id | string | ID of object | | created\_at | string | ISO 8601 value for first time retrieving person's identity info | | updated\_at | string | ISO 8601 value for last time retrieving person's identity info | | first\_name | string | First name | | last\_name | string | Last name | | full\_name | string | Full name | | middle\_initials | string | Middle initials | | email | string | Email address | | ssn | string | Social Security Number, full or last 4 digits | | date\_of\_birth | date | Date of birth | | home\_address | object | Address object | *** ## Endpoints Use the endpoint below to collect information from insurance reports. * [Retrieve an insurance report](/api-reference/insurance/link_detail_reports_insurance) *** ## Example response The sample below is a JSON response for the endpoint. ```json theme={null} { "id": "24d7e80942ce4ad58a93f70ce4115f5c", "status": "new", "finished_at": "2021-04-06T11:30:00Z", "access_token": "48427a36d43c4d5aa6324bc06c692456", "tracking_info": "user123456", "insurance": { "policies": [ { "id": "53c5ce0d-fb79-4f1c-bc27-32181b368fc7", "policy_type": "AUTO", "name": "AUTO AU192837", "description": "Effective 11/03/2021 - 11/03/2022", "carrier_policy_number": "HO132654", "effective_date": "2021-11-03T00:00:00Z", "expiry_date": "2021-11-03T00:00:00Z", "renewal_date": "2021-11-03T00:00:00Z", "canceled_date": "2021-11-03T00:00:00Z", "total_premium_cents": "150319", "deductible_cents": 0, "carrier_name": "progressive", "status": "ACTIVE", "paid_in_full": true, "dwellings": [ { "id": "b7a53a67-7266-42b6-a20e-97e8fc723bbc", "address": { "id": "a497f96b-94be-443e-88bb-c8289085c922", "address_nature": "MAILING", "country": "US", "street": "344 Clinton St, Apartment 3D", "city": "Brooklyn", "state": "NY", "zip": "11231" }, "replacement_cost_cents": 2600, "cash_value_cents": 2600, "coverages": [ { "id": "b9087b71-c1b1-482d-be9f-92a2cf81fbb3", "name": "PERSONAL_PROPERTY", "premium_cents": 18514, "per_person_limit_cents": 0, "per_incident_limit_cents": 0, "deductible_cents": 50000, "is_declined": true } ], "mortgagees": [ { "id": "26a4ce3a-0b9f-4c3d-96c0-1c76529e3b52", "name": "string", "type": "FIRST", "loan_number": "string", "address": { "id": "a497f96b-94be-443e-88bb-c8289085c922", "address_nature": "MAILING", "country": "US", "street": "344 Clinton St, Apartment 3D", "city": "Brooklyn", "state": "NY", "zip": "11231" } } ] } ], "vehicles": [ { "id": "26a4ce3a-0b9f-4c3d-96c0-1c76529e3b52", "year": 2010, "make": "CHEVROLET", "model": "Camaro", "series": "ZL1", "series2": "string", "type": "PASSENGER CAR", "annual_mileage": 26000, "vin": "1G1FK1R62J0158884", "purchase_date": "2010-10-02T12:00:00.000Z", "is_removed": true, "lien_holder": "Manhattan Bank", "garaging_address": { "id": "a497f96b-94be-443e-88bb-c8289085c922", "address_nature": "MAILING", "country": "US", "street": "344 Clinton St, Apartment 3D", "city": "Brooklyn", "state": "NY", "zip": "11231" }, "lien_holder_address": { "id": "a497f96b-94be-443e-88bb-c8289085c922", "address_nature": "MAILING", "country": "US", "street": "344 Clinton St, Apartment 3D", "city": "Brooklyn", "state": "NY", "zip": "11231" }, "coverages": [ { "id": "111da3f8-20b0-4839-81d7-6473437e493e", "name": "PROPERTY_DAMAGE_LIABILITY", "per_day_limit_cents": 0, "per_mile_premium_tenth_of_cents": 0, "premium_cents": 18514, "per_person_limit_cents": 0, "per_incident_limit_cents": 0, "deductible_cents": 50000, "is_declined": true } ], "drivers": [ { "id": "8857f648-c6ce-44df-8fa4-78eee16e9bb4", "first_name": "John", "middle_name": "Joseph", "last_name": "Doe", "drivers_license": "SUP1234012", "drivers_license_state": "DC", "date_of_birth_str": "05/03/1988", "gender": "MALE", "marital_status": "SINGLE", "relationship_to_insured": "INSURED", "is_excluded": true } ] } ], "commercial_named_insureds": [ { "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "name": "Sample Business LLC", "form_of_business": "INDIVIDUAL", "gl_code": "10010", "sic_code": "6411", "naics_code": "524210", "fein": "123456789", "ssn": "123456789", "is_primary": true, "address": { "id": "a497f96b-94be-443e-88bb-c8289085c922", "address_nature": "MAILING", "country": "US", "street": "344 Clinton St, Apartment 3D", "city": "Brooklyn", "state": "NY", "zip": "11231" } } ], "named_insureds": [ { "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "first_name": "string", "middle_name": "string", "last_name": "string", "full_name": "string", "is_primary": true } ], "claims": [ { "id": "", "dwelling_id": "", "vehicle_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "driver_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "carrier_claim_identifier": "string", "date_occurred": "2023-04-29T04:59:15.973Z", "type": "WIND_AND_HAIL_DAMAGE", "status": "OPEN", "date_closed": "2022-05-03T00:00:00Z", "payout_cents": 180111, "representative_name": "string", "representative_phone": "string", "representative_email": "string", "address": { "id": "a497f96b-94be-443e-88bb-c8289085c922", "address_nature": "MAILING", "country": "US", "street": "344 Clinton St, Apartment 3D", "city": "Brooklyn", "state": "NY", "zip": "11231" } } ], "loss_events": [ { "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "date_of_occurrence": "2022-05-03T00:00:00Z", "date_of_claim": "2022-05-03T00:00:00Z", "type": "BURGLARY_AND_THEFT", "amount_paid_cents": 123323, "amount_reserved_cents": 0, "is_subrogation": true, "is_claim_open": true } ], "documents": [ { "id": "55ad7bb6-f5a3-4ebf-91fb-2802391eb261", "title": "11-03-2021 - Auto - Automobile Policy Renewal Declarations", "document_type": "INSURANCE_APPLICATION", "date_added": "2022-05-03T00:00:00Z", "file": "https://truv-statements.s3.amazonaws.com/insurance/example_file" } ] } ], "drivers": [ { "id": "8857f648-c6ce-44df-8fa4-78eee16e9bb4", "first_name": "John", "middle_name": "Joseph", "last_name": "Doe", "drivers_license": "SUP1234012", "drivers_license_state": "DC", "date_of_birth_str": "05/03/1988", "gender": "MALE", "marital_status": "SINGLE", "relationship_to_insured": "INSURED" } ], "addresses": [ { "id": "a497f96b-94be-443e-88bb-c8289085c922", "address_nature": "MAILING", "country": "US", "street": "344 Clinton St, Apartment 3D", "city": "Brooklyn", "state": "NY", "zip": "11231" } ], "driving_records": [ { "id": "da9d46ad-8ddb-4b4b-bc7e-7a381a738f7d", "driver_id": "da9d46ad-8ddb-4b4b-bc7e-7a381a738f7c", "incident_date": "2021-04-23T00:00:00.000Z", "incident_type": "ACCIDENT", "violation_type": "MOVING", "is_at_fault": true } ], "agents": [ { "id": "da9d46ad-8ddb-4b4b-bc7e-7a381a738f7d", "address_id": "da9d46ad-8ddb-4b4b-bc7e-7a381a738f7c", "agency_name": "string", "agent_full_name": "string", "phone_number": "string", "email": "string", "policy_ids": [ "3fa85f64-5717-4562-b3fc-2c963f66afa6" ] } ] }, "provider": "progressive", "identity": { "id": "48427a36d43c4d5aa6324bc06c692456", "created_at": "2022-06-07T15:00:00Z", "updated_at": "2022-06-31T15:00:00Z", "first_name": "John", "last_name": "Doe", "full_name": "John Doe", "middle_initials": "K", "email": "john.doe@example.com", "ssn": "123456789", "date_of_birth": "1992-03-03", "home_address": { "street": "1 Morgan Ave", "city": "Los Angeles", "state": "CA", "zip": "90210", "country": "US" } }, "pdf_report": "https://citadelid-resources.s3-us-west-2.amazonaws.com/report.pdf" } ``` # Retrieve liabilities Source: https://truv.com/docs/api-reference/liabilities/link_liabilities GET /v1/links/{link_id}/liabilities/ The endpoint returns liability accounts including credit cards and loans with detailed balance and payment information. # The Liabilities object Source: https://truv.com/docs/api-reference/liabilities/object Retrieve user liability data from connected financial accounts. Use the Liabilities endpoints to retrieve liability data from a user's connected financial accounts. This includes information about loans, credit cards, and other debt obligations held at financial institutions. # Attributes ## Credit liabilities Credit cards and lines of credit. | Attribute | Type | Description | | :----------------------- | :------ | :-------------------------- | | `account_id` | string | Unique account identifier | | `purchases_apr` | decimal | APR for purchases | | `advances_apr` | decimal | APR for cash advances | | `credit_line` | decimal | Total credit line | | `current_balance` | decimal | Current outstanding balance | | `available_credit` | decimal | Available credit | | `available_cash` | decimal | Available cash advance | | `minimum_payment_amount` | decimal | Minimum payment due | | `next_payment_amount` | decimal | Next payment amount | | `next_payment_date` | date | Next payment due date | | `last_payment_amount` | decimal | Last payment made | | `last_payment_date` | date | Date of last payment | | `last_stmt_balance` | decimal | Last statement balance | | `last_stmt_date` | date | Last statement date | | `past_due_amount` | decimal | Amount past due | ## Loan liabilities Auto loans, student loans, personal loans, and mortgages. | Attribute | Type | Description | | :--------------------------- | :-------- | :------------------------------- | | `account_id` | string | Unique account identifier | | `original_principal` | decimal | Original loan principal | | `principal_balance` | decimal | Current principal remaining | | `interest_rate` | decimal | Current interest rate percentage | | `interest_rate_as_of` | date-time | Date rate was last updated | | `interest_paid_year_to_date` | decimal | Total interest paid YTD | | `loan_term` | string | Loan term in months | | `maturity_date` | date-time | Loan maturity date | | `escrow_balance` | decimal | Escrow balance (mortgages) | | `next_payment_amount` | decimal | Next payment amount | | `next_payment_date` | date-time | Next payment due date | | `last_payment_amount` | decimal | Last payment made | | `last_payment_date` | date-time | Date of last payment | ## Account types | Type | Subtypes | | ------------------------- | --------------------------------------------------------------------------------- | | `CREDIT_CARD` | Rewards, cashback, secured | | `LINE_OF_CREDIT` | HELOC, home equity | | `LOAN` | `AUTO`, `STUDENT`, `PERSONAL`, `PERSONAL_WITH_COLLATERAL`, `SMALL_BUSINESS`, `RV` | | `MORTGAGE` | Fixed-rate, adjustable-rate | | `CHECKING_LINE_OF_CREDIT` | Overdraft protection | ## Loan balance verification A common use case for liabilities data is **loan balance verification in refinance scenarios**. Lenders retrieve outstanding loan balances to confirm payoff amounts before closing. To access liabilities data, the member must first complete a [Verification of Assets (VOA)](/mortgage/products/assets) order and connect their bank account through Truv Bridge. Once the asset connection is established, the liabilities endpoint returns outstanding loan balances, credit obligations, and payment history associated with the connected accounts. Liabilities data is derived from the same financial institution connection used for asset verification. No separate connection step is required — set up VOA first, then query the liabilities endpoint for the same link. # Endpoints * [Retrieve liabilities](/api-reference/liabilities/link_liabilities) # Example response ```json theme={null} { "accounts": [ { "id": "24d7e80942ce4ad58a93f70ce4115f5c", "type": "CREDIT_CARD", "mask": "6789", "balances": { "currency_code": "USD", "balance": "2407.16", "available_balance": "92.84", "credit_limit": "2500.00" } } ], "liabilities": { "credit": [ { "account_id": "24d7e80942ce4ad58a93f70ce4115f5c", "purchases_apr": "23.49", "credit_line": "2500.00", "current_balance": "2407.16", "available_credit": "92.00", "minimum_payment_amount": "0.00", "next_payment_date": "2025-08-23", "last_payment_amount": "300.00", "last_payment_date": "2025-08-13" } ], "loans": [] } } ``` # Delete a link Source: https://truv.com/docs/api-reference/links/delete_link_by_link_id DELETE /v1/links/{link_id}/ The endpoint removes a link and all associated data. # Account Link Webhook Events Source: https://truv.com/docs/api-reference/links/events Webhook events for Account Link connections, disconnections, and deletions Subscribe to these events via [Webhooks](/api-reference/webhooks/object) to track Account Link state changes in real time. All webhook payloads include the [common fields](/api-reference/webhooks/object#webhook-payload-structure) (`webhook_id`, `event_type`, `event_created_at`, `updated_at`, `user_id`, `template_id`) plus the event-specific fields below. *** ## link-connected Fires when a Link connection is successfully established. **Additional fields:** | Field | Description | | --------------- | -------------------------------------------------------------- | | `link_id` | The Link identifier | | `data_source` | `payroll`, `docs`, `insurance`, `financial_accounts`, or `tax` | | `tracking_info` | Custom metadata passed via `bridge_token` (nullable) | ```json theme={null} { "webhook_id": "e5f6a7b8c9d0e1f2a3b4c5d6a7b8c9d0", "event_type": "link-connected", "event_created_at": "2022-08-24T13:54:00.000000Z", "updated_at": "2022-08-24T13:54:00.000000+00:00", "link_id": "d39d86dcc20c46e0ae75ba9ab1311a21", "product": "income", "data_source": "payroll", "tracking_info": null, "user_id": "88fef4cea64c40b5ad6727cc9b0b9fdc", "template_id": null } ``` *** ## link-disconnected Fires when a Link connection fails during a refresh task. ```json theme={null} { "webhook_id": "f6a7b8c9d0e1f2a3b4c5d6a7b8c9d0e1", "event_type": "link-disconnected", "event_created_at": "2022-08-25T09:31:00.000000Z", "updated_at": "2022-08-25T09:31:00.000000+00:00", "link_id": "d39d86dcc20c46e0ae75ba9ab1311a21", "product": "income", "data_source": "payroll", "tracking_info": null, "user_id": "88fef4cea64c40b5ad6727cc9b0b9fdc", "template_id": null } ``` *** ## link-deleted Fires when personal data and credentials are removed from a Link. ```json theme={null} { "webhook_id": "a7b8c9d0e1f2a3b4c5d6a7b8c9d0e1f2", "event_type": "link-deleted", "event_created_at": "2022-08-26T10:00:00.000000Z", "updated_at": "2022-08-26T10:00:00.000000+00:00", "link_id": "d39d86dcc20c46e0ae75ba9ab1311a21", "product": "income", "data_source": "payroll", "tracking_info": null, "user_id": "88fef4cea64c40b5ad6727cc9b0b9fdc", "template_id": null } ``` *** ## Event summary | Event | Trigger | Key Fields | | ------------------- | ---------------------------- | ------------------------ | | `link-connected` | Successful connection | `link_id`, `data_source` | | `link-disconnected` | Refresh connection failure | `link_id`, `data_source` | | `link-deleted` | Data and credentials removed | `link_id`, `data_source` | # Retrieve a link token Source: https://truv.com/docs/api-reference/links/link_exchange_token_flow POST /v1/link-access-tokens/ Exchange a bridge public_token for a link access_token. # Retrieve a link Source: https://truv.com/docs/api-reference/links/links-item GET /v1/links/{link_id}/ # List all links Source: https://truv.com/docs/api-reference/links/links-list GET /v1/links/ # The Account Links object Source: https://truv.com/docs/api-reference/links/object Manage Links (persistent connections to user accounts) and refresh their data **Link**s have an ID value and an **access\_token**. Together, these retrieve data from a user's account. Exchange the **public\_token** value during authentication while implementing Truv Bridge. Access tokens are for sensitive operations, such as generating reports. ## Attributes | Attribute | Type | Description | | :----------------- | :----- | :------------------------------------------------------- | | id | string | Unique ID of Link | | created\_at | string | ISO 8601 value for when Link was created | | updated\_at | string | ISO 8601 value for when Link was last updated | | tracking\_info | string | Optional tracking information provided by a partner | | status | string | Status from Connection Lifecycle related to account Link | | user\_external\_id | bool | External ID of user provided by a partner | | provider\_id | string | Data provider ID | | link\_hash | string | Unique hash for user credentials when creating link | *** ## Example response ```json theme={null} { "id": "48427a36d43c4d5aa6324bc06c692456", "created_at": "2022-06-07T15:00:00Z", "updated_at": "2022-06-31T15:00:00Z", "tracking_info": "user123456", "status": "new", "user_external_id": "user123456", "provider_id": "adp", "link_hash": "bc917458a3da4b2c8cc8282aa1707aaa" } ``` *** ## Refresh data Refresh data from an existing **Link** with the data refresh endpoints. These let the user bypass entering their payroll credentials a second time. ### Perform a data refresh 1. \[Optional] Subscribe to Webhooks for completed **Task**s with `done` status. Pull payroll data for the data refresh information. 2. Use the Create a data refresh task endpoint with the **access\_token** from the original connection. 3. Use webhooks, the Retrieve a data refresh status endpoint, or both to check the status of the refresh. Each data refresh **Task** is billed individually. ### Refresh rate intervals Truv has rate limits on each **access\_token** value. Within a 24-hour period, only an initial request and three refreshes are allowed. The `Refresh limit for the access_token exceeded` error occurs for any requests outside of the interval and limit. ### Data refresh task attributes | Attribute | Type | Description | | :-------- | :----- | :----------------------------------- | | task\_id | string | Unique ID for Link data refresh task | ### Data refresh status attributes | Attribute | Type | Description | | :------------ | :----- | :----------------------------------------------------------------- | | id | string | Unique refresh task ID | | created\_at | string | Time when refresh task was created | | refresh\_date | string | ~~Date of data refresh~~ **(Deprecated, invalid datetime format)** | | status | string | Data refresh task status | ### Refresh example responses **Create a data refresh** ```json theme={null} { "task_id": "48427a36d43c4d5aa6324bc06c692456" } ``` **Retrieve a data refresh** ```json theme={null} { "id": "24d7e80942ce4ad58a93f70ce4115f5c", "created_at": "2021-04-06T11:30:00Z", "refresh_date": "2020-03-10", "status": "new" } ``` *** ## Endpoints * [List all links](/api-reference/links/links-list) * [Retrieve a link](/api-reference/links/links-item) * [Retrieve a link token](/api-reference/links/link_exchange_token_flow) * [Delete a link](/api-reference/links/delete_link_by_link_id) * [Create a data refresh task](/api-reference/refresh/refresh_task_create) * [Retrieve a data refresh status](/api-reference/refresh/refresh_task) # Advanced Security & mTLS Source: https://truv.com/docs/api-reference/mtls Mutual TLS authentication for API and webhook communication Mutual TLS (mTLS) enhances standard TLS by requiring both the client and the server to authenticate each other using digital certificates. This ensures only trusted parties can establish communication with Truv's API. ## mTLS API endpoints | Environment | Endpoint | | -------------- | --------------------------- | | **Production** | `api-mtls.truv.com` | | **Sandbox** | `api-sandbox-mtls.truv.com` | *** ## Set up mTLS for APIs Create a Certificate Signing Request using X.509v3 format with RSA or ECDSA keys and SHA256: ``` CN: api-mtls..truv.com O: Truv Inc L: Miami ST: Florida C: US ``` Truv will issue a signed certificate valid for one year. ```bash theme={null} curl --cert $CERT.pem --key $PRIVATE_KEY.key https://api-mtls.truv.com/v1/orders/ ``` Allow Truv's IP addresses through your firewall: **Production:** `35.167.32.174`, `35.165.53.192`, `54.71.147.242` **Sandbox:** `44.235.37.104`, `35.83.220.165`, `52.38.209.190` Work with Truv Support to enable mTLS on your account. *** ## mTLS for webhooks Truv supports mTLS for webhook communication. Two authentication approaches are available: ### Truv's signed certificate Configure the public certificate from `mtls-prod.truv.com` on your webhook endpoint to verify that requests originate from Truv. ### Client-signed certificate Truv submits a CSR and you issue a signed certificate. Truv then uses your certificate when delivering webhooks to your endpoint. ### OAuth 2.0 (optional) Truv supports OAuth 2.0 authentication when invoking webhooks. Truv obtains access tokens for secure webhook delivery. Contact Truv Support to configure OAuth settings. ### Custom headers You can configure custom headers (Client ID and Client Secret) on webhook deliveries for an additional authentication layer. Work with Truv Support to configure. *** ## Originating IP addresses See [Webhook Security](/api-reference/security#originating-ip-addresses) for the full list of IP addresses used for webhook delivery. # OpenAPI Spec Source: https://truv.com/docs/api-reference/openapi Truv OpenAPI specification in YAML format [Open the Truv OpenAPI specification (YAML)](/openapi.yaml) to use with code generators, API explorers, or validation tools. # Order Webhook Events Source: https://truv.com/docs/api-reference/orders/events Webhook events for Order status changes and refresh failures Subscribe to these events via [Webhooks](/api-reference/webhooks/object) to track Order progress in real time. All webhook payloads include the [common fields](/api-reference/webhooks/object#webhook-payload-structure) (`webhook_id`, `event_type`, `event_created_at`, `updated_at`, `user_id`, `template_id`) plus the event-specific fields below. *** ## order-created Fires when an order is created, before any status transitions happen. The `link_id`, `data_source`, and `employer_id` fields are always `null` since the order hasn't been linked yet, and `status` is always `pending`. **Additional fields:** | Field | Description | | -------------- | --------------------------- | | `order_id` | The Order identifier | | `order_number` | Human-readable order number | | `employer_id` | Always `null` at creation | | `status` | Always `pending` | ```json theme={null} { "webhook_id": "0aac461e7b774a38a72fd9c7c0eef8ee", "event_type": "order-created", "event_created_at": "2024-07-11T21:40:48.424610Z", "updated_at": "2024-07-11T21:40:48.424655+00:00", "product": "income", "link_id": null, "user_id": "adbe707dddee4334bffaeb5866272740", "data_source": null, "order_id": "ddd192646b3c48be96651a0ff25cef85", "order_number": "4138538", "employer_id": null, "status": "pending", "template_id": null } ``` *** ## order-status-updated Fires for each change to an Order's status when related to a Task. Order status webhooks only reflect **successful** connections. To listen for all connection attempts (including failures), subscribe to [`task-status-updated`](/api-reference/tasks/events#task-status-updated) events where the `tracking_info` field matches the `employer_id` from the Order. A new VOIE or VOA report ID is generated after every additional connection reaches `completed` status. **Additional fields:** | Field | Description | | -------------- | ------------------------------ | | `order_id` | The Order identifier | | `order_number` | Human-readable order number | | `employer_id` | Associated employer (nullable) | | `status` | Current order status | ```json theme={null} { "webhook_id": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6", "event_type": "order-status-updated", "event_created_at": "2022-08-24T14:00:00.000000Z", "updated_at": "2022-08-24T14:00:00.000000+00:00", "order_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "order_number": "ORD-2024-001", "employer_id": "emp_abc123", "status": "completed", "user_id": "88fef4cea64c40b5ad6727cc9b0b9fdc", "template_id": null } ``` *** ## order-refresh-failed Fires when a refresh task fails for an Order. Use this to detect refresh failures. Unlike `link-disconnected`, this fires per-order and includes order context. **Additional fields:** | Field | Description | | -------------- | ------------------------------ | | `order_id` | The Order identifier | | `order_number` | Human-readable order number | | `employer_id` | Associated employer (nullable) | | `status` | The failure status | ```json theme={null} { "webhook_id": "d4e5f6a7b8c9d0e1f2a3b4c5d6a7b8c9", "event_type": "order-refresh-failed", "event_created_at": "2022-08-25T09:30:00.000000Z", "updated_at": "2022-08-25T09:30:00.000000+00:00", "order_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "order_number": "ORD-2024-001", "employer_id": "emp_abc123", "status": "login_error", "user_id": "88fef4cea64c40b5ad6727cc9b0b9fdc", "template_id": null } ``` *** ## Event summary | Event | Trigger | Key Fields | | ---------------------- | -------------------------------------------- | ------------------------------------------------------- | | `order-created` | Order first created (before any transitions) | `order_id`, `order_number`, `status` (always `pending`) | | `order-status-updated` | Order status changes | `order_id`, `order_number`, `status` | | `order-refresh-failed` | Refresh task fails for an order | `order_id`, `order_number`, `status` | # The Orders object Source: https://truv.com/docs/api-reference/orders/object Create verification requests, generate bridge tokens, and manage the full order lifecycle An **Order** is the starting point for every verification. When you create an Order, Truv automatically creates a [User](/api-reference/users/object), generates a [Bridge Token](/api-reference/users/object#bridge-tokens), and produces a personalized landing page for the user to connect their account. The following diagram illustrates the Order lifecycle. ```mermaid theme={null} %%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#EBF0FD', 'primaryBorderColor': '#2C64E3', 'primaryTextColor': '#111827', 'lineColor': '#9CA3AF', 'tertiaryColor': '#FFFFFF', 'edgeLabelBackground': '#FFFFFF'}}}%% sequenceDiagram participant Client participant API as Truv API participant User participant Bridge as Truv Bridge participant Server as Your Server Client->>API: POST /v1/orders/ API-->>Client: Order object (bridge_token) User->>Bridge: Complete verification API-->>Server: Webhook events Client->>API: GET /v1/orders/{id} ``` **Orders handle everything to get started**: creating an Order is all you need to initiate a verification. The Order creates the User, generates the Bridge Token, and tracks the entire lifecycle from creation to completion. ### What happens when you create an Order 1. **User is created** automatically from the provided applicant details 2. **Bridge Token is generated** for the Order 3. **Landing page is created** with a unique `share_url` for the user 4. **Invite is sent** (optional) via email, SMS, or both, or you can share the `share_url` directly 5. **User connects** through [Truv Bridge](/developers/integration/bridge-widget/overview) on the landing page 6. **Data is retrieved** and the Order status updates as Tasks complete ### Order lifecycle and webhooks Orders are **asynchronous**. The typical flow is: 1. You create an Order via the API or Dashboard. 2. The user authenticates with one or more employers through Truv Bridge. 3. Truv retrieves the data and fires a `task-status-updated` webhook for each employer/account as it completes. 4. When all connections in the order are finished, Truv fires a single `order-status-updated` webhook for the full order. 5. You retrieve the verification data using the Link endpoints. | Webhook | Scope | Use for | | ---------------------- | ------------------------------- | ------------------------------------------------------------------------ | | `task-status-updated` | Per employer/account connection | Monitoring individual connection progress, processing data as it arrives | | `order-status-updated` | Entire order | Knowing when all connections are complete, final order status | In a multi-employer order, you receive a separate `task-status-updated` webhook for each employer the user connects. The `order-status-updated` webhook fires once after all connections resolve. Use `task-status-updated` to process data incrementally and `order-status-updated` to confirm the full order is done. The `no_data` status means the user successfully connected to the provider, but the provider returned zero records. This is distinct from an `error` status, which indicates a connection failure. A `no_data` result typically means the provider has no history for the applicant, not that the connection failed. ### Create orders Create Orders through the [Truv Dashboard](https://dashboard.truv.com/app/orders) or programmatically via the [Create an Order](/api-reference/orders/orders_create) endpoint. Orders are customizable for these components: * Landing page * Text message (optional) * Email (optional) ## Attributes The attributes of Orders are below. **Report limits:** A single VOIE order supports a maximum of 5 employers, and a single VOA order supports a maximum of 5 financial institutions. If you need to verify more, create additional orders for the same user. | Attribute | Type | Description | | :--------------------------- | :--------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | id | string | Unique ID of order | | products | array | List of products selected for Order | | source | string | Type of platform: `floify`, `besmartee`, `lenderlogix`, `encompass_consumer_connect`, `byte`, `core_logic`, `xactus`, `constellation`, `banno`, `mx`, `q2`, `clutch`, `accio`, `encompass`, `tpo_connect`, `darkmatter`, `tazworks`, `internal`, `simplenexus`, `alkami`, `blue_sage`, `lodasoft`, `blend`, `tidalwave`, `external_webpage` | | order\_number | string | External ID from client | | custom\_field | string | Client-provided custom field for use in email, SMS, or landing page. *NOTE: Enable this field in the dashboard customization section.* | | client\_name | string | Verification agency name | | first\_name | string | First name | | last\_name | string | Last name | | user\_id | string | Unique ID of user | | bridge\_token | string | UUID value of bridge token for the Order | | share\_url | string | Landing page URL to share | | short\_share\_url | string | Shortened verification URL to share | | created\_at | string | ISO 8601 value for when Order was created | | updated\_at | string | ISO 8601 value for when Order was last updated | | completed\_at | string | ISO 8601 value for when Order was successfully completed | | canceled\_at | string | ISO 8601 value for when Order was canceled | | expired\_at | string | ISO 8601 value for Order expiration | | is\_expired | bool | Status of Order expiration | | user\_consent\_at | string | ISO 8601 value for when explicit user consent was given | | initial\_order | string | ID of origin Order, from Order data refresh action | | refresh\_order | string | ID of last refresh Order created by Order data refresh action | | employers | array of objects | List of user employers, see [Employers object](#employers-object) | | insurance | object | Insurance verification metadata, see [Insurance object](#insurance-object) | | financial\_accounts | array of objects | Financial accounts metadata, see [Financial accounts object](#financial-accounts-object) | | manager | array of objects | Associated Order manager info, see [Manager object](#manager-object) | | loan | object | Loan information, see [Loan object](#loan-object) | | cc\_emails | array of strings | Email addresses for CC on order status updates (max 15) | | notes | string | Free text field for notes (max 2000 characters) | | template\_id | string | ID of template | | voie\_report\_id | string | Income and employment verification report ID (accepted by Fannie Mae DU and Freddie Mac LPA) | | voa\_report\_id | string | Asset verification report ID | | income\_insights\_report\_id | string | Income Insights report ID | | aim\_check\_report\_id | string | AIM check report ID for income calculation based on uploaded documents | To get a PDF version of the report please use the corresponding report\_id along with the GET endpoint in the User Reports section. **voie\_report\_id auto-population:** The `voie_report_id` field is only populated automatically when an account-level setting is enabled. This setting generates a Fannie Mae DU / Freddie Mac LPA compatible report ID upon order completion. Contact [Truv support](mailto:support@truv.com) to enable this feature for your account. ### Company address object The values in this table are for the address object of the company. | Attribute | Type | Description | | :-------- | :----- | :---------- | | street | string | Street | | city | string | City | | state | string | State | | zip | string | Zip | | country | string | Country | ### Employers object View information for employer object field data below. | Attribute | Type | Description | | :--------------- | :--------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | id | string | Unique ID | | product\_type | string | Type of product, see values below: `income`, `employment`, `deposit_switch`, `pll` | | status | string | Order status, see values below: `pending`, `sent`, `completed`, `error`, `canceled`, `expired`, `no_data`, `skipped` | | suborder\_number | string | External ID | | created\_at | string | Date and time when Order was created | | bridge\_token | string | UUID value of **bridge\_token** | | link\_id | string | Link ID for connected account | | access\_token | string | Access token to perform data refresh | | pdf\_report | uri | Verification report in PDF format | | data\_source | string | Source of data, see values below: `payroll` - Payroll provider parsing, `docs` - User uploaded documents, `insurance` - Insurance data, `financial_accounts` - Bank data, `tax` - Tax documents, `scoring_attributes` - Transactions scoring attributes report | | provider | array of objects | Payroll or insurance provider, see [Provider object](#provider-object) | | is\_suspicious | Boolean | Status of data from source marked as suspicious, such as if detecting fraud in uploaded documents or user SSN does not match data | | start\_date | string | Employment start date | | end\_date | string | Employment end date | | company\_name | string | Company name | | company\_address | array of objects | Company address, see [Company address object](#company-address-object) | | company\_logo | uri | Company logo URL | | company\_domain | string | Company website domain | | employments | array of objects | List of employments, see [Employments object](#employments-object) | #### Provider object This table contains data for the provider object. | Attribute | Type | Description | | :-------- | :----- | :----------------- | | id | string | Provider unique ID | | name | string | Provider name | | logo\_url | uri | Provider logo url | #### Employments object The Employments object contains the values and descriptions below. | Attribute | Type | Description | | :---------------------- | :--------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | income | string | Income amount not including commission or bonuses, only for income product. Null for employment product | | income\_unit | string | Pay interval for income field, only for income product. `YEARLY` - Annual income, `MONTHLY` - Monthly income, `WEEKLY` - Weekly income, `DAILY` - Daily income, `HOURLY` - Hourly income. Null for employment product | | pay\_rate | string | Payment rate per pay cycle, only for income product. Null for employment product | | pay\_frequency | string | Pay frequency, only for income product. `M` - Monthly, `SM` - Semi-Monthly, `W` - Weekly, `BW` - Bi-Weekly, `A` - Annually, `SA` - Semiannually, `C` - Commission. Null for employment product | | statements | array of objects | List of paystubs received from a payroll provider, only for income product, see [Statements object](#statements-object). Null for employment product | | annual\_income\_summary | array of objects | Annual income summary by years, only for income product, see [Annual income summary object](#annual-income-summary-object). Null for employment product | | bank\_accounts | array of objects | List of bank accounts linked to employment, only for income product, see [Bank accounts object](#bank-accounts-object). Null for employment product | | w2s | array of objects | List of W-2 forms linked to employment, only for income product, see [W2s object](#w2s-object). Null for employment product | | id | string | Unique ID | | is\_active | Boolean | Status of active employment | | job\_title | string | Employee's job title | | job\_type | string | Employee's job type. `F` - Full Time, `P` - Part Time, `S` - Seasonal, `D` - Daily (per diem), `C` - Contract | | start\_date | date | Employee's hire date | | original\_hire\_date | date | Original hire date | | end\_date | date | Employee's end date | | external\_last\_update | date | Indicates date of last updated employment data from Payroll Provider | | derived\_fields | array of strings | Array of derived fields | | missing\_data\_fields | array of strings | List of missing data fields from payroll response | | manager\_name | string | Supervisor's name | | profile | object | Person's identity information | | company | object | [Company object](#company-object) | | gse\_accepted | Boolean | Status of provider eligibility from Fannie Mae Desktop Underwriter | ##### Statements object View the table below for information from the Statements object. | Attribute | Type | Description | | :-------------------- | :--------------- | :------------------------------------------------------------------ | | id | string | Unique ID | | check\_number | string | External ID of pay stub from payroll provider | | pay\_date | date | Pay date | | net\_pay | string | Net pay | | net\_pay\_ytd | string | Net pay year to date | | gross\_pay | string | Gross pay | | gross\_pay\_ytd | string | Gross pay year to date | | bonus | string | Bonus | | commission | string | Commission | | hours | string | Work hours during pay period | | basis\_of\_pay | string | Basis of pay. `S` - Salary, `H` - Hourly, `D` - Daily, `W` - Weekly | | period\_start | date | Period start | | period\_end | date | Period end | | regular | string | Regular pay | | regular\_ytd | string | Regular salary year to date | | other\_pay\_ytd | string | All other payment year to date | | bonus\_ytd | string | Bonus year to date | | commission\_ytd | string | Commission year to date | | overtime | string | Overtime pay | | overtime\_ytd | string | Overtime pay year to date | | other\_pay | string | All other payment | | earnings | array of objects | Earnings for this pay cycle by type | | earnings\_ytd | array of objects | Earnings year to date by type | | deductions | array of objects | Deductions for pay cycle by type | | deductions\_ytd | array of objects | Deductions year to date by type | | md5sum | string | MD5 hash value computed based on file content | | file | uri | Link to pay stub file, format is specified in the content-type | | derived\_fields | array of strings | Array of derived fields | | missing\_data\_fields | array of strings | List of missing data fields from payroll response | ##### Annual income summary object Find information for the attributes and values of the annual income summary object. | Attribute | Type | Description | | :--------- | :------ | :---------------------- | | id | string | Unique ID | | year | integer | Income report year | | regular | string | Regular salary | | bonus | string | Bonus | | commission | string | Commission | | overtime | string | Overtime pay | | other\_pay | string | All other payment forms | | net\_pay | string | Net pay | | gross\_pay | string | Gross pay | ##### Bank accounts object The table below covers the attributes within the bank accounts object. | Attribute | Type | Description | | :-------------- | :----- | :---------------------------------------------------------------------------------------------------------- | | account\_number | string | Account number | | routing\_number | string | Routing number | | account\_name | string | User friendly account name | | account\_type | string | Account type. `C` - Checking account, `S` - Savings account | | deposit\_type | string | Deposit type. `E` - Entire paycheck, `P` - Percentage of the paycheck, `A` - Fixed amount from the paycheck | | deposit\_value | string | Deposit value | | bank\_name | string | Bank name | ##### W2s object The values in this table are for the W-2s object field. | Attribute | Type | Description | | :---------------------- | :------ | :-------------------------------------------------------------- | | file | uri | Link to W2 report file, format is specified in the content-type | | md5sum | string | MD5 hash value computed based on file content | | year | integer | Year | | wages | string | Wages, tips, other compensation (Section 1) | | federal\_tax | string | Federal income tax withheld (Section 2) | | social\_security\_wages | string | Social security wages (Section 3) | | social\_security\_tax | string | Social security tax withheld (Section 4) | | medicare\_wages | string | Medicare wages (Section 5) | | medicare\_tax | string | Medicare tax withheld (Section 6) | | gross\_pay | string | Gross pay | ##### Company object This table covers values within the company object. | Attribute | Type | Description | | :-------- | :----- | :-------------------------------- | | name | string | Company name | | address | object | [Address object](#address-object) | | phone | string | Company phone number | | ein | string | Employer Identification Number | ###### Address object The values in this table are for the address object of the company. | Attribute | Type | Description | | :-------- | :----- | :---------- | | street | string | Street | | city | string | City | | state | string | State | | zip | string | Zip | | country | string | Country | ### Insurance object This table's values contain information for the insurance object. | Attribute | Type | Description | | :--------------- | :--------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | id | string | Unique ID | | product\_type | string | Type of product | | status | string | Order status | | suborder\_number | string | External ID | | created\_at | string | Date and time when Order was created | | bridge\_token | string | UUID value of **bridge\_token** | | link\_id | string | Link ID for connected account | | access\_token | string | Access token to perform data refresh | | pdf\_report | uri | Verification report file as a PDF | | data\_source | string | Source of data, see values below: `payroll` - Payroll provider parsing, `docs` - User uploaded documents, `insurance` - Insurance data, `financial_accounts` - Bank data, `tax` - Tax documents, `scoring_attributes` - Transactions scoring attributes report | | provider | array of objects | Payroll or insurance provider, see [Provider object](#provider-object) | | is\_suspicious | Boolean | Status of data from source marked as suspicious, such as if detecting fraud in uploaded documents or user SSN does not match data | | provider\_id | string | Pre-selected ID of insurance provider | ### Financial accounts object The financial accounts object attributes below have type information and descriptions. | Attribute | Type | Description | | :--------------- | :--------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | id | string | Unique ID | | product\_type | string | Type of product | | status | string | Order status | | suborder\_number | string | External ID | | created\_at | string | Date and time when Order was created | | bridge\_token | string | UUID value of **bridge\_token** | | link\_id | string | Link ID for connected account | | access\_token | string | Access token to perform data refresh | | pdf\_report | uri | Verification report file as a PDF | | data\_source | string | Source of data, see values below: `payroll` - Payroll provider parsing, `docs` - User uploaded documents, `insurance` - Insurance data, `financial_accounts` - Bank data, `tax` - Tax documents, `scoring_attributes` - Transactions scoring attributes report | | provider | array of objects | Payroll or insurance provider, see [Provider object](#provider-object) | | is\_suspicious | Boolean | Status of data from source marked as suspicious, such as if detecting fraud in uploaded documents or user SSN does not match data | | accounts | array of objects | List of connected accounts, see [Accounts object](#accounts-object-1) | #### Accounts object | Attribute | Type | Description | | :-------- | :----- | :--------------------------------------------------- | | id | string | Unique identifier of account | | type | string | Parent type of account, e.g. `CHECKING` or `SAVINGS` | | subtype | string | Account subtype, e.g. `MONEY_MARKET`, `HOME_EQUITY` | | mask | string | Masked account number | ### Manager object The manager object attributes below have information on type and description. | Attribute | Type | Description | | :-------- | :----- | :--------------------- | | email | string | Email of Order manager | | name | string | Name of Order manager | ### Loan object View the table below for type and description of the attributes in the loan object. | Attribute | Type | Description | | :--------------------- | :----- | :------------------------------- | | loan\_number | string | Loan identifier | | external\_id | string | External loan ID (e.g. from POS) | | originator\_name | string | Name of loan originator | | originator\_email | string | Email of loan originator | | loan\_processor\_name | string | Name of the loan processor | | loan\_processor\_email | string | Email of the loan processor | *** ## Endpoints The list below are the available endpoints for Orders. * [Create an order](/api-reference/orders/orders_create) * [Retrieve an order](/api-reference/orders/orders_read) * [Create a data refresh order](/api-reference/orders/orders_create_refresh_order) * [Update an order](/api-reference/orders/orders_partial_update) * [Cancel an order](/api-reference/orders/orders_cancel_create) * [Get list of orders by SSN](/api-reference/orders/orders_list_lookup) * [Add new employer to existing order](/api-reference/orders/order-add-new-employer) * [Retrieve an order invoice](/api-reference/orders/order_group_invoice_detail) * [Retrieve events for an order](/api-reference/orders/orders_events_list) * [Retrieve self-certification results](/api-reference/orders/orders_certifications_results) *** ## Example response The JSON object below is a sample response. ```json theme={null} { "id": "39aa1486ccca4bc19cda071ffc1ba392", "products": [ "income" ], "source": "floify", "order_number": "1534332", "custom_field": "string", "client_name": "Unnamed Verifications Inc.", "first_name": "John", "last_name": "Doe", "user_id": "99dd17074ac94aa9ace2621d657c7610", "bridge_token": "e4100fccdae94691b4414c7306220c06", "share_url": "https://cdn.truv.com/employment.html?bridge_token=63b4af88facb40e48f517c1e8c7abdf4&order_group_id=39aa1486ccca4bc19cda071ffc1ba392", "short_share_url": "https://truv.com/s/BIlEyh1A", "created_at": "2021-04-21T21:45:14.418542Z", "updated_at": "2021-04-21T21:45:14.418542Z", "canceled_at": "2021-04-22T21:45:14.418542Z", "completed_at": "2021-04-22T21:45:14.418542Z", "expired_at": "2021-04-24T21:45:14.418542Z", "is_expired": true, "user_consent_at": "2021-04-21T21:45:14.418542Z", "initial_order": "f5dc0239e2094dbc90ab2edc1918a9df", "refresh_order": "9b96606355b94e8abff8ed8d75aa2027", "employers": [ { "id": "ad9f14440d624ec3b0f66e81e44518c7", "product_type": "income", "status": "pending", "suborder_number": "133982343355", "created_at": "2021-04-21T22:12:59.346109Z", "bridge_token": "e4100fccdae94691b4414c7306220c06", "link_id": "e4100fccdae94691b4414c7306220c06", "access_token": "e4100fccdae94691b4414c7306220c06", "pdf_report": "https://cdn.truv.com/report.pdf", "data_source": "payroll", "provider": { "id": "truv_api", "name": "Sandbox Provider", "logo_url": "https://cdn.truv.com/providers/truv-blue.svg" }, "is_suspicious": true, "start_date": "2019-08-24", "end_date": "2019-11-27", "company_name": "Facebook Demo", "company_address": { "street": "1 Hacker Way", "city": "Menlo Park", "state": "CA", "zip": "94025" }, "company_logo": "https://cdn.truv.com/logos/facebook.svg", "company_domain": "facebook.com", "employments": [ { "income": "70000.00", "income_unit": "YEARLY", "pay_rate": "6500.00", "pay_frequency": "M", "statements": [ { "id": "24d7e80942ce4ad58a93f70ce4115f5c", "check_number": "29205182", "pay_date": "2018-05-15", "net_pay": "11500.32", "net_pay_ytd": "31980.64", "gross_pay": "13900.11", "gross_pay_ytd": "49200.00", "bonus": "100.00", "commission": "12000.00", "hours": "40.00", "basis_of_pay": "S", "period_start": "2018-05-01", "period_end": "2018-05-15", "regular": "1695.11", "regular_ytd": "23000.00", "other_pay_ytd": "700.00", "bonus_ytd": "1000.00", "commission_ytd": "24000.00", "overtime": "45.00", "overtime_ytd": "500.00", "other_pay": "60.00", "earnings": [ { "name": "Regular", "amount": "1935.77", "category": "regular", "rate": null, "units": null }, { "name": "Overtime", "amount": "60.58", "category": "overtime", "rate": "30.29", "units": "2" } ], "earnings_ytd": [ { "name": "Regular", "amount": "1935.77", "category": "regular", "rate": null, "units": null }, { "name": "Overtime", "amount": "60.58", "category": "overtime", "rate": "30.29", "units": "2" } ], "deductions": [ { "name": "Social Security Tax", "amount": "127.01", "category": "socialsec" }, { "name": "VA State Income Tax", "amount": "46.23", "category": "state" }, { "name": "Medicare Tax", "amount": "29.7", "category": "medicare" } ], "deductions_ytd": [ { "name": "Social Security Tax", "amount": "127.01", "category": "socialsec" }, { "name": "VA State Income Tax", "amount": "46.23", "category": "state" }, { "name": "Medicare Tax", "amount": "29.7", "category": "medicare" } ], "md5sum": "03639d6a6624f69a54a88ea90bd25e9d", "file": "https://cdn.truv.com/paystub_sample.pdf", "derived_fields": [ "basis_of_pay" ], "missing_data_fields": [ "earnings_ytd" ] } ], "annual_income_summary": [ { "id": "24d7e80942ce4ad58a93f70ce4115f5c", "year": 2018, "regular": "23000.00", "bonus": "1000.00", "commission": "24000.00", "overtime": "500.00", "other_pay": "700.00", "net_pay": "31980.64", "gross_pay": "49200.00" } ], "bank_accounts": [ { "account_number": "1234567890", "routing_number": "123456789", "account_name": "My Bank", "account_type": "C", "deposit_type": "A", "deposit_value": "200.00", "bank_name": "TD Bank" } ], "w2s": [ { "file": "https://cdn.truv.com/W2_sample.pdf", "md5sum": "f65e30c39124ad707ac4b3aeaee923a7", "year": 2020, "wages": "900.50", "federal_tax": "75.01", "social_security_wages": "900.50", "social_security_tax": "56.30", "medicare_wages": "900.50", "medicare_tax": "13.15", "gross_pay": "18211.48" } ], "id": "24d7e80942ce4ad58a93f70ce4115f5c", "is_active": false, "job_title": "PR associate", "job_type": "F", "start_date": "2018-01-01", "original_hire_date": "2017-06-21", "end_date": "2025-03-13", "external_last_updated": "2025-03-13", "dates_from_statements": false, "derived_fields": [ "is_active" ], "missing_data_fields": [ "w2s" ], "manager_name": "Jenny McDouglas", "profile": { "id": "48427a36d43c4d5aa6324bc06c692456", "created_at": "2022-06-07T15:00:00Z", "updated_at": "2022-06-31T15:00:00Z", "first_name": "John", "last_name": "Doe", "full_name": "John Doe", "middle_initials": "K", "email": "john.doe@example.com", "ssn": "123456789", "date_of_birth": "1992-03-03", "home_address": { "street": "1 Morgan Ave", "city": "Los Angeles", "state": "CA", "zip": "90210", "country": "US" } }, "company": { "name": "Facebook Demo", "address": { "street": "1 Morgan Ave", "city": "Los Angeles", "state": "CA", "zip": "90210", "country": "US" }, "phone": "6503087300", "ein": "12-345678" } } ] } ], "insurance": { "id": "ad9f14440d624ec3b0f66e81e44518c7", "product_type": "insurance", "status": "pending", "suborder_number": "133982343355", "created_at": "2021-04-21T22:12:59.346109Z", "bridge_token": "e4100fccdae94691b4414c7306220c06", "link_id": "e4100fccdae94691b4414c7306220c06", "access_token": "e4100fccdae94691b4414c7306220c06", "pdf_report": "https://cdn.truv.com/report.pdf", "data_source": "insurance", "provider": { "id": "truv_api", "name": "Sandbox Provider", "logo_url": "https://cdn.truv.com/providers/truv-blue.svg" }, "is_suspicious": true, "provider_id": "geico" }, "manager": { "email": "john.doe@example.com", "name": "John Doe" }, "financial_accounts": [ { "id": "ad9f14440d624ec3b0f66e81e44518c7", "product_type": "transactions", "status": "pending", "suborder_number": "133982343355", "created_at": "2021-04-21T22:12:59.346109Z", "bridge_token": "e4100fccdae94691b4414c7306220c06", "link_id": "e4100fccdae94691b4414c7306220c06", "access_token": "e4100fccdae94691b4414c7306220c06", "pdf_report": "https://cdn.truv.com/report.pdf", "data_source": "financial_accounts", "provider": { "id": "truv_api", "name": "Sandbox Provider", "logo_url": "https://cdn.truv.com/providers/truv-blue.svg" }, "is_suspicious": true, "accounts": [ { "id": "3aed25abdbc246138b84a2afd46cb05b", "type": "CHECKING", "subtype": null, "mask": "******0685" } ] } ], "loan": { "loan_number": "MUUT220700012", "originator_name": "John Doe", "originator_email": "john@example.com", "loan_processor_name": "John Doe", "loan_processor_email": "john@doe.com", "external_id": "c505e0f1-b413-4fdc-853f-c87e7d2cc4a5" }, "template_id": "9b96606355b94e8abff8ed8d75aa2027", "cc_emails": [ "user@example.com" ], "notes": "string", "voie_report_id": "b19c454a98594b4084b71e3b62873d29", "voa_report_id": "b19c454a98594b4084b71e3b62873d29", "income_insights_report_id": "b19c454a98594b4084b71e3b62873d29", "aim_check_report_id": "FM-1234-39aa1486ccca4bc19cda071ffc1ba392" } ``` # Add new employer to the existing order Source: https://truv.com/docs/api-reference/orders/order-add-new-employer POST /v1/orders/{id}/employers/ The endpoint allows to add new employer to the existing order. The order should not be expired or canceled. # Retrieve an order invoice Source: https://truv.com/docs/api-reference/orders/order_group_invoice_detail GET /v1/orders/{id}/invoice/ The endpoint returns an order invoice. # Cancel an order Source: https://truv.com/docs/api-reference/orders/orders_cancel_create POST /v1/orders/{id}/cancel/ The endpoint cancels the order. # Retrieve self-certification results for an order Source: https://truv.com/docs/api-reference/orders/orders_certifications_results GET /v1/orders/{id}/certifications/ The endpoint returns self-certification results for employments and accounts that have been reviewed and certified by the user. # Create an order Source: https://truv.com/docs/api-reference/orders/orders_create POST /v1/orders/ The endpoint creates an order # Create a data refresh order Source: https://truv.com/docs/api-reference/orders/orders_create_refresh_order POST /v1/orders/{id}/ The endpoint creates the new order with data populated from the existing order. # Retrieve events for an order Source: https://truv.com/docs/api-reference/orders/orders_events_list GET /v1/orders/{id}/events/ Returns a list of events for the specified order. # Get list of orders by SSN Source: https://truv.com/docs/api-reference/orders/orders_list_lookup POST /v1/orders/lookup/ The endpoint returns a list of orders by an applicant SSN # Update an order Source: https://truv.com/docs/api-reference/orders/orders_partial_update PATCH /v1/orders/{id}/ The endpoint updates the order. Update only available if all employers in one of statuses: pending, sent. # Retrieve an order Source: https://truv.com/docs/api-reference/orders/orders_read GET /v1/orders/{id}/ The endpoint returns the order. # List all parsed documents Source: https://truv.com/docs/api-reference/parsed-documents/list-parsed-documents GET /v1/links/{link_id}/parsed-documents/ The endpoint returns a list of parsed documents. Parsed documents contain structured data extracted from uploaded documents. **Note:** Currently, only volunteer letters are available through this endpoint. Support for additional document types (paystubs, etc.) will be added in future releases. You can filter, order, and paginate results using query parameters. # The Parsed Documents object Source: https://truv.com/docs/api-reference/parsed-documents/object Access parsed document data retrieved through Truv Bridge connections. Parsed Documents contain structured data extracted from documents that were uploaded and processed through Truv Bridge. Use these endpoints to retrieve the parsed results, including income, employment, and tax information extracted from uploaded paystubs, W2s, 1099s, and other supported document types. # Endpoints Use the endpoints below to get information on parsed documents. * [List parsed documents](/api-reference/parsed-documents/list-parsed-documents) * [Retrieve parsed document](/api-reference/parsed-documents/retrieve-parsed-document) # Retrieve parsed document Source: https://truv.com/docs/api-reference/parsed-documents/retrieve-parsed-document GET /v1/links/{link_id}/parsed-documents/{doc_id}/ The endpoint returns a parsed document with its extracted data. The `parsed_data` field contains structured information extracted from the document. **Note:** Currently, only volunteer letters are available through this endpoint. For volunteer letters, the `parsed_data` includes volunteer information such as total hours, dates (start_date, end_date), position title, and optionally detailed hour entries with dates, hours, and descriptions for each volunteer activity. # Postman Collection Source: https://truv.com/docs/api-reference/postman Get started with Truv APIs using the Postman collection The Truv Postman Collection lets you get started with your integration with little to no code. It includes pre-configured requests, environment variables, and sample workflows. Run in Postman *** ## Set up Postman Download and install [Postman](https://www.postman.com/downloads/). Click the **Run in Postman** button above to fork the Truv API collection into your workspace. This imports both the collection and the Sandbox environment. *** ## Configure Postman The Truv Postman collection uses [Postman environment variables](https://learning.postman.com/docs/sending-requests/variables/managing-environments/) to simplify each API request. In the top right corner of Postman, select the **Sandbox** environment. Click the eye icon to open the environment settings. Copy your Truv API keys from the [Dashboard API Keys page](https://dashboard.truv.com/app/development/keys) into the environment variables: * `client_id`: your Client ID * `access_key`: your Access Secret Save your changes and start making API requests. *** ## Sample workflow Requests have pre-configured pre-request and post-response scripts that pass data between steps automatically. ### VOIE verification Run **Create an Order - VOIE (Basic)**. In the response body, click the `shareURL` to complete the order in Truv Bridge. Run **Get an Order by ID**. The `orderId` from step 1 is stored as a variable and passed through automatically. Run **Get a VOIE Report by ID**. The `user_id` and `voie_report_id` variables from the prior response are stored and passed through automatically. # Privacy & Compliance Source: https://truv.com/docs/api-reference/privacy-compliance User consent, secure transport, data handling expectations, and compliance materials Truv's privacy and compliance documentation centers on three practical areas: * explicit end-user consent before data access * secure transport for all API communication * current audit reports, questionnaires, and supporting materials through the Trust Center and compliance contacts *** ## User consent Access to end-user data requires explicit user consent through the Truv connection flow. Users authenticate directly with their provider and authorize access to the requested data before Truv returns verification results. Use your implementation to make that consent flow clear to end users and request only the data required for your use case. *** ## Secure transport All API traffic must use HTTPS with TLS 1.2 or higher. For integrations with stricter authentication requirements, Truv also supports [mTLS](/api-reference/mtls) for public API traffic and webhook delivery. *** ## Data handling expectations Use the same controls you would apply to other sensitive verification data: * keep API credentials in environment variables or a secrets manager * restrict access to verification data to the systems and roles that need it * define retention windows that match your business and regulatory requirements * log access to sensitive data and security-relevant events for auditability Implementation details for credential handling and webhook verification live in [Webhook Security](/api-reference/security). *** ## Compliance highlights * SOC 2 Type II certified with continuous monitoring * Regular internal and external network penetration testing and third-party code reviews * Role-based access controls enforced at each layer of infrastructure * Multi-factor authentication required for access to Truv infrastructure * All application and user access logs stored centrally and monitored * Sensitive data encrypted with an additional layer beyond standard TLS ## Compliance materials For current security documents, questionnaires, and supporting materials, use the Truv Trust Center or contact the Truv compliance team. Current security documents, reports, and questionnaires. Request current compliance materials and supporting documentation. # The Task Refresh object Source: https://truv.com/docs/api-reference/refresh/object View information about data refresh endpoints for Links. Refresh data from an existing **Link** with the data refresh endpoints. These let the user bypass entering their payroll credentials a second time. ### Perform a data refresh Follow the steps below to perform a data refresh. 1. \[Optional] Subscribe to Webhooks for completed **Task**s with `done` status. Pull payroll data for the data refresh information. 2. Use the Create a data refresh task endpoint with the **access\_token** from the original connection. 3. Use webhooks, the Retrieve a data refresh status endpoint, or both to check the status of the refresh. Each data refresh **Task** is billed individually as a separate verification. ### Authorization validity The success of a refresh depends on whether the original connection is still authorized: | Connection type | Typical validity | Notes | | ------------------------------------------ | ------------------ | ---------------------------------------------------------------------------------------------------------- | | OAuth-based (e.g., most payroll providers) | \~180 days | Token expires after roughly 6 months. After expiration, the user must re-authenticate through Truv Bridge. | | Session-based | Varies by provider | Some providers maintain sessions for weeks, others for months. No fixed guarantee. | For programs with **quarterly review cycles**, refresh success rates are high because most connections remain active within the 180-day window. For **annual review cycles**, expect most connections to have expired, requiring the user to re-authenticate. ### VOA refreshes from POS integrations If the initial VOA verification was completed through a point-of-sale integration (e.g., SimpleNexus, Blend), the refresh still works via the Order Refresh API as long as the original connection is active. Use the `access_token` from the initial order to create the refresh task. ### Refresh rate limits Truv has rate limits on each **access\_token** value. Within a 24-hour period, only an initial request and 3 refreshes are allowed. The `Refresh limit for the access_token exceeded` error occurs for any requests outside of the interval and limit. ## Attributes The sections below cover values from Data Refresh endpoints. ### Data refresh task The information below is for the response from data refresh tasks for a Link. | Attribute | Type | Description | | :-------- | :----- | :----------------------------------- | | task\_id | string | Unique ID for Link data refresh task | ### Data refresh status The values in the table below are for the status of a data refresh. | Attribute | Type | Description | | :------------ | :----- | :----------------------------------------------------------------- | | id | string | Unique refresh task ID | | created\_at | string | Time when refresh task was created | | refresh\_date | string | ~~Date of data refresh~~ **(Deprecated, invalid datetime format)** | | status | string | Data refresh task status | *** ## Endpoints These endpoints are from the Data refresh API. * [Create a data refresh task](/api-reference/refresh/refresh_task_create) * [Retrieve a data refresh status](/api-reference/refresh/refresh_task) *** ## Example responses The JSON objects below are sample responses for the endpoints. **Create a data refresh** ```json theme={null} { "task_id": "48427a36d43c4d5aa6324bc06c692456" } ``` **Retrieve a data refresh** ```json theme={null} { "id": "24d7e80942ce4ad58a93f70ce4115f5c", "created_at": "2021-04-06T11:30:00Z", "refresh_date": "2020-03-10", "status": "new" } ``` # Retrieve a data refresh status Source: https://truv.com/docs/api-reference/refresh/refresh_task GET /v1/refresh/tasks/{task_id}/ The endpoint returns the refresh task status. # Create a data refresh task Source: https://truv.com/docs/api-reference/refresh/refresh_task_create POST /v1/refresh/tasks/ The endpoint creates a link data refresh task. # The Scoring Attributes Report object Source: https://truv.com/docs/api-reference/scoring-attributes/object View more information about scoring attribute reports. Scoring Attributes reports provide cash-flow metrics, derived income streams, and risk scores based on a consumer's bank transaction history. Use these reports for credit decisioning, underwriting verifications, and retroactive analytics. ## Attributes The report response includes the following attributes. | Attribute | Type | Description | | :------------------- | :--------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | report\_id | string | Unique guid generated by scoring attributes API for identifying report | | source\_guid | string | Only applicable for refresh reports and existing customer refresh reports, new customer reports return `null`, unique guid of prior Scoring Attributes report for customer, returns most recent successful report for customers with multiple reports, the Refresh Report endpoint uses this report's transactions as starting point | | refresh | Boolean | Status of refresh report | | lender\_reference | string | Value for lender to identify report request, e.g. loan application number | | customer\_identifier | string | Customer-level unique identifier, *NOTE: Do not use personally identifiable information such as SSN or government ID numbers.* | | purpose | string | Purpose of report, valid values are below:
`decisioning` - FCRA credit decisioning
`verification` - Non-FCRA underwriting verifications
`analytics` - Retroactive reports for analytical purposes only | | status | string | Terminal statuses are:
`success`, `failed`, `data_import_error`
A status of `processing` indicates that the report is still being processed. An additional call should be made to the GET endpoint until a terminal status is returned. | | cutoff\_date | string | Latest date of financial activity included in report, typically set to current date or application date, date is in the past for retro-scored reports | | created\_at | string | Date and time of report request | | updated\_at | string | Date and time of report update | | alerts | array of objects | Values present when notifying lender of specific conditions, conditions do not prevent report completion, see [Alerts object](#alerts-object) | | scores | array of objects | Generic or custom scores, only report purpose-applicable scores are returned, see [Scores object](#scores-object) | | metrics | array of objects | See [Metrics object](#metrics-object) | | derived\_incomes | array of objects | See [Derived Incomes object](#derived-incomes-object) | *** ## Alerts object Each alert includes the following fields. | Attribute | Type | Description | | :---------- | :------ | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | alert\_code | integer | Integer indicating alert type, see message field for valid values | | message | string | Message describing alert condition, valid values and alert codes below
`1` - No consistent income sources present
`2` - No consistent payment streams present
`3` - Short transaction history
`4` - Low transaction activity
`5` - Unable to calculate daily balances for all accounts
`6` - Accounts with stale ending balances are present
`7` - Low ratio of debit activity | *** ## Scores object Each score includes the following fields. | Attribute | Type | Description | | :-------- | :------ | :----------------- | | name | string | Model name | | version | float | Model version | | value | integer | Scaled score value | *** ## Metrics object Each metric includes the following fields. | Attribute | Type | Description | | :----------- | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | name | string | Metric name, not including period of time | | time\_period | string | Abbreviation for time period of metric, valid values below:
`1m_l0` - Last month
`2m_l0` - Last 2 months
`3m_l0` - Last 3 months
`4m_l0` - Last 4 months
`6m_l0` - Last 6 months
`1w_l0` - Last week
`2w_l0` - Last 2 weeks
`2m_l2` - 2 months (2 month delay)
`2m_l4` - 2 months (4 month delay)
`4m_l2` - 4 months (2 month delay)
`1m_l1` - 1 month (1 month delay)
`2w_l2` - 2 weeks (2 week delay)
`0m_l0` - Current snapshot
`0m_l2` - Snapshot from 2 months ago
`0m_l4` - Snapshot from 4 months ago
`lftm` - Lifetime
`2m_to_1m` - Change from 2 months ago to current month
`3m_to_1m` - Change from 3 months ago to current month | | short\_name | string | Abbreviated form of metric name combined with time period | | unit | string | Measurement type for metric, valid fields `dollars`, `percent`, `boolean`, `count` | | value | number | Numeric value of metric, can contain null values, `null` is not `0` and must be properly parsed
For amounts, returns dollar value with decimals indicating cents, such as `2.99`
For percentages, returns an integer, for example 5% is `5`
For Booleans, `True` is represented as `1` and `False` is represented as `0`
For `counts` such as number of consistent payments, returns integers | *** ## Derived incomes object Each derived income stream includes the following fields. | Attribute | Type | Description | | :------------------- | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | description | string | Normalized description for derived income stream, for sensitive information within description, such as health information, description returns as `REDACTED` | | frequency | string | Frequency of income stream, possible values are `monthly`, `semi_monthly`, `bi_weekly`, `weekly` | | days | array | Day or days of week or month for recurring deposits
For `monthly` and `semi-monthly` frequencies, returns day of the month and `-1` indicates end of month
For `weekly` and `bi_weekly` frequencies, returns day of week where `1` indicates Monday and `7` indicates Sunday | | formatted\_frequency | string | Frequency combined with recurrence days | | months | number | Longest period income stream has been recurring from report date
Income streams are only evaluated on whole months and 2, 3, 4 and 6 month intervals | | average\_amount | double | Average amount of each deposit in covered monthly interval | | monthly\_amount | double | Projected monthly amount based on average amount and occurrence frequency | *** ## Endpoints Use the endpoints below to get information on reports for scoring attributes. * [Create a scoring attributes report](/api-reference/scoring-attributes/scoring-attributes-report-create) * [Retrieve a scoring attributes report](/api-reference/scoring-attributes/scoring-attributes-report-retrieve) *** ## Example response ```json theme={null} { "report_id": "string", "source_guid": "2f918810e4b911edb5ea0242ac120002", "refresh": true, "lender_reference": "appl-1234", "customer_identifier": "cust-9999", "purpose": "decisioning", "status": "success", "cutoff_date": "2021-03-31T00:00:00.000Z", "created_at": "2022-03-16 12:56:15 -0700", "updated_at": "2022-03-16 12:56:17 -0700", "alerts": [ { "alert_code": 1, "message": "No consistent income sources present" } ], "scores": [ { "name": "Overdraft Risk Score", "version": 1, "value": 750 } ], "metrics": [ { "name": "derived_nsf_fee_amount", "time_period": "2m_l0", "short_name": "drvd_nsf_fee_amt_2m_l0", "unit": "dollars", "value": 23.99 } ], "derived_incomes": [ { "description": "direct deposit from xyz company", "frequency": "semi_monthly", "days": [15, -1], "formatted_frequency": "Semi-Monthly (15, eom)", "months": 3, "average_amount": 475.99, "monthly_amount": 1003.21 } ] } ``` # Create a scoring attributes report Source: https://truv.com/docs/api-reference/scoring-attributes/scoring-attributes-report-create POST /v1/scoring_attributes/reports # Retrieve a scoring attributes report Source: https://truv.com/docs/api-reference/scoring-attributes/scoring-attributes-report-retrieve GET /v1/scoring_attributes/reports/{report_id} # Webhook Security Source: https://truv.com/docs/api-reference/security Verify webhook deliveries, handle retries safely, and configure webhook security controls Use this page for the security and operational rules around webhook delivery: * verify every delivery with `X-WEBHOOK-SIGN` * respond within the supported timeout window * handle duplicate deliveries safely * process events using `updated_at` for sequencing * allowlist Truv IPs or configure mTLS when your network requires it Use [Webhook Events](/api-reference/webhook-events) only as the event catalog. Use [Webhooks](/api-reference/webhooks/object) for endpoint configuration and payload structure. *** ## Webhook signature verification Every webhook request from Truv includes an `X-WEBHOOK-SIGN` header containing an HMAC-SHA256 hash. Use this to verify that requests are authentic and haven't been tampered with. ### How it works 1. Truv computes an HMAC-SHA256 hash of the raw request body using your Access Secret 2. The hash is sent in the `X-WEBHOOK-SIGN` header with a `v1=` prefix 3. Your server recomputes the hash and compares it to the header value Use the **raw request body** (not parsed JSON) when computing the hash. Parsing and re-serializing may change the byte representation. ### Code examples ```python theme={null} import hashlib import hmac def verify_webhook(payload: str, signature: str, secret: str) -> bool: generated_hash = hmac.new( key=secret.encode('utf-8'), msg=payload.encode('utf-8'), digestmod=hashlib.sha256, ).hexdigest() expected = f'v1={generated_hash}' return hmac.compare_digest(expected, signature) ``` ```javascript theme={null} const crypto = require("crypto"); const express = require("express"); const bodyParser = require("body-parser"); const app = express(); app.use(bodyParser.json({ verify: (req, res, buf) => { req.rawBody = buf; } })); function verifyWebhook(rawBody, signature, secret) { const hash = crypto .createHmac("sha256", secret) .update(rawBody) .digest("hex"); const expected = `v1=${hash}`; return signature === expected; } app.post("/webhooks/truv", (req, res) => { const signature = req.headers["x-webhook-sign"]; const isValid = verifyWebhook(req.rawBody, signature, process.env.TRUV_SECRET); if (!isValid) { return res.status(401).send("Invalid signature"); } res.status(200).send("OK"); }); ``` ```go theme={null} import ( "crypto/hmac" "crypto/sha256" "encoding/hex" "fmt" ) func verifyWebhook(body string, signature string, secret string) bool { mac := hmac.New(sha256.New, []byte(secret)) mac.Write([]byte(body)) expected := fmt.Sprintf("v1=%s", hex.EncodeToString(mac.Sum(nil))) return hmac.Equal([]byte(expected), []byte(signature)) } ``` ```ruby theme={null} require 'openssl' def verify_webhook(body, signature, secret) digest = OpenSSL::Digest.new('sha256') expected = "v1=" + OpenSSL::HMAC.hexdigest(digest, secret, body) Rack::Utils.secure_compare(expected, signature) end ``` ```csharp theme={null} using System.Security.Cryptography; using System.Text; private bool VerifyWebhook(string body, string signature, string secret) { using (HMACSHA256 hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secret))) { byte[] hashValue = hmac.ComputeHash(Encoding.UTF8.GetBytes(body)); string expected = "v1=" + BitConverter.ToString(hashValue) .Replace("-", "").ToLower(); return expected == signature; } } ``` *** ## Delivery behavior Truv webhook deliveries follow these operating constraints: * endpoints should return a successful `2xx` response within 10 seconds * `3xx` redirects are accepted * non-success responses trigger retries * unsuccessful deliveries are retried up to 3 times with a 30-second gap between attempts Respond quickly, acknowledge receipt, and move heavier processing into an asynchronous job or queue. *** ## Ordering and idempotency Webhook deliveries are asynchronous, so your application should not assume arrival order alone is authoritative. * use the `updated_at` field to process status changes in sequence * implement idempotency using `webhook_id` so duplicate deliveries do not trigger duplicate work * fetch fresh data from the API when you need the latest full resource state *** ## Originating IP addresses Allowlist the current Truv webhook IP addresses if your network requires source filtering: * `34.212.57.93` * `44.224.243.166` * `52.25.14.79` For the webhook schema and delivery object details, see [Webhooks](/api-reference/webhooks/object). *** ## Additional authentication options Beyond webhook signature verification, Truv supports: * Truv-signed certificates for webhook mTLS * client-signed certificates for webhook mTLS * custom headers such as client ID and client secret, configured with Truv Use [mTLS](/api-reference/mtls) if you need mutual certificate-based authentication for webhook delivery. *** ## Webhook implementation checklist ```javascript theme={null} // Verify signature on the raw body // Return 200 quickly // Queue processing asynchronously // Deduplicate by webhook_id // Use updated_at for ordering checks ``` # Security Source: https://truv.com/docs/api-reference/security-overview Overview of Truv security, privacy, compliance, webhook security, and mTLS Truv supports security controls for regulated integrations, including webhook signature verification, mutual TLS (mTLS) for APIs and webhooks, and additional authentication options for webhook delivery. User consent, secure transport, compliance materials, and where to request documentation. Signature verification, delivery timing, retries, and webhook allowlisting guidance. Mutual TLS for Truv APIs and webhook delivery, including certificate setup paths. Current security documents, reports, and questionnaires. *** ## Navigate this section Use this section when you need to answer one of four practical questions: * How do I verify webhook deliveries from Truv? * When should I use mTLS instead of standard API authentication? * What privacy and compliance materials are available? * Where do I find the implementation details for webhook security and mTLS? For implementation details, start with the focused pages in this section and then use the endpoint reference pages for webhook configuration and event payloads. *** ## Webhook signature verification Every webhook request from Truv includes an `X-WEBHOOK-SIGN` header. Validate that signature against the raw request body with your Access Secret before you process the event. Use [Webhook Security](/api-reference/security) for verification examples, retry behavior, IP allowlisting, and handling guidance. *** ## mTLS for APIs and webhooks Truv supports mTLS for both public API traffic and webhook delivery: * **Public APIs:** `api-mtls.truv.com` for Production and `api-sandbox-mtls.truv.com` for Sandbox * **Webhooks:** Truv-signed certificates, client-signed certificates, and optional custom headers Use [mTLS](/api-reference/mtls) for the setup path, certificate options, and allowlisting details. *** ## Privacy and compliance All API requests must use HTTPS with TLS 1.2 or higher. Access to end-user data requires explicit user consent through the connection flow. Users authenticate directly with their provider and grant access to the requested data. Use [Privacy & Compliance](/api-reference/privacy-compliance) for current guidance on consent, transport security, retention planning, and how to request supporting documentation. *** ## Contact [security@truv.com](mailto:security@truv.com) [compliance@truv.com](mailto:compliance@truv.com) # Shift Webhook Events Source: https://truv.com/docs/api-reference/shifts/events Webhook events for shift data creation and updates. Subscribe to these events via [Webhooks](/api-reference/webhooks/object) to receive notifications when shift data becomes available or changes during a refresh. All webhook payloads include the [common fields](/api-reference/webhooks/object#webhook-payload-structure) plus the event-specific fields below. *** ## shifts-created Fires when shift schedule data has been extracted. This occurs for any successful non-refresh [Task](/api-reference/tasks/object). **Additional fields:** | Field | Description | | --------------- | -------------------------------- | | `employment_id` | The associated employment record | | `task_id` | The associated Task | | `objects_count` | Number of shifts retrieved | ```json theme={null} { "webhook_id": "f82ab0a92ddd4bb7b6117635159b366a", "task_id": "c32fb957ec7246828da56be7516da765", "link_id": "9915c50cc047413bb810767f218390f8", "product": "employment", "data_source": "payroll", "tracking_info": null, "event_type": "shifts-created", "event_created_at": "2022-08-23T17:32:24.812306Z", "objects_count": 1, "employment_id": "427abebd8590457e8332fdff77fc412f", "user_id": "88fef4cea64c40b5ad6727cc9b0b9fdc", "template_id": null } ``` *** ## shifts-updated Fires when the shift count changes during a refresh Task. For example, if a person had 8 shifts and now has 9. **Additional fields:** Same as `shifts-created` (`employment_id`, `task_id`, `objects_count`). ```json theme={null} { "webhook_id": "f82ab0a92ddd4bb7b6117635159b366a", "task_id": "c32fb957ec7246828da56be7516da765", "link_id": "9915c50cc047413bb810767f218390f8", "product": "employment", "data_source": "payroll", "tracking_info": null, "event_type": "shifts-updated", "event_created_at": "2022-08-23T17:32:24.812306Z", "objects_count": 1, "employment_id": "427abebd8590457e8332fdff77fc412f", "user_id": "88fef4cea64c40b5ad6727cc9b0b9fdc", "template_id": null } ``` # List all shifts Source: https://truv.com/docs/api-reference/shifts/link-shifts GET /v1/links/{link_id}/shifts/ The endpoint returns ongoing and completed work shifts. It includes time entries (clock in/clock out), the type of work, and earnings. # The Shifts object Source: https://truv.com/docs/api-reference/shifts/object Learn more about information related to ongoing and completed work shifts. The Shifts endpoint includes time entries such as clock in and clock out, the type of work, and earnings. Shifts is related to the `link_id` from Truv's Income and Employment API. ## Attributes The values in the table below cover attributes of Shifts. | Attribute | Type | Description | | :------------ | :--------------- | :--------------------------------------------------------------------------------------- | | count | integer | Total number of results | | next | string | Link to next page | | previous | string | Link to previous page | | results | array of objects | List of shifts | | id | string | Unique ID of shifts | | external\_id | string | External ID of selected shifts | | created\_at | string | Shift creation timestamp | | updated\_at | string | Shift update timestamp | | start\_date | string | Shift start date | | end\_date | string | Shift end date | | time\_entries | array of objects | List of shift-related time entries | | id | string | Unique time entry ID | | external\_id | string | Time entry external ID | | created\_at | string | Time entry creation timestamp | | updated\_at | string | Time entry update timestamp | | entry\_date | string | Entry date of event in time tracking system | | start | string | Date and time when work shift started | | end | string | Date and time when work shift ended | | earnings | array of objects | Aggregated earnings for shift | | type | string | Type of shift, four types of shifts available: `Other`, `Delivery`, `Rideshare`, `Shift` | *** ## Endpoint The item below is the available endpoint for Shifts. * [List all shifts](/api-reference/shifts/link-shifts) *** ## Example response The response object below is the returned JSON value. ```json theme={null} { "count": 0, "next": null, "previous": null, "results": [] } ``` # Pay Statement Webhook Events Source: https://truv.com/docs/api-reference/statements/events Webhook events for pay statement creation and updates. Subscribe to these events via [Webhooks](/api-reference/webhooks/object) to receive notifications when pay statements become available or change during a refresh. All webhook payloads include the [common fields](/api-reference/webhooks/object#webhook-payload-structure) plus the event-specific fields below. *** ## statements-created Fires when pay statements have been retrieved. This occurs once per [Link](/api-reference/links/object) for each non-refresh [Task](/api-reference/tasks/object) completion. **Additional fields:** | Field | Description | | --------------- | -------------------------------- | | `employment_id` | The associated employment record | | `task_id` | The associated Task | | `objects_count` | Number of statements retrieved | ```json theme={null} { "webhook_id": "f82ab0a92ddd4bb7b6117635159b366a", "task_id": "c32fb957ec7246828da56be7516da765", "link_id": "9915c50cc047413bb810767f218390f8", "product": "employment", "data_source": "payroll", "tracking_info": null, "event_type": "statements-created", "event_created_at": "2022-08-23T17:32:24.812306Z", "objects_count": 9, "employment_id": "427abebd8590457e8332fdff77fc412f", "user_id": "88fef4cea64c40b5ad6727cc9b0b9fdc", "template_id": null } ``` *** ## statements-updated Fires when the statement count changes during a refresh Task. For example, if a person had 31 pay stubs and now has 32. **Additional fields:** Same as `statements-created` (`employment_id`, `task_id`, `objects_count`). ```json theme={null} { "webhook_id": "f82ab0a92ddd4bb7b6117635159b366a", "task_id": "c32fb957ec7246828da56be7516da765", "link_id": "9915c50cc047413bb810767f218390f8", "product": "employment", "data_source": "payroll", "tracking_info": null, "event_type": "statements-updated", "event_created_at": "2022-08-23T17:32:24.812306Z", "objects_count": 10, "employment_id": "427abebd8590457e8332fdff77fc412f", "user_id": "88fef4cea64c40b5ad6727cc9b0b9fdc", "template_id": null } ``` # List all statements Source: https://truv.com/docs/api-reference/statements/link-statements GET /v1/links/{link_id}/statements/ The endpoint returns a list of pay statements with dates, gross pay, net pay and earnings with deductions breakdown. # The Pay Statements object Source: https://truv.com/docs/api-reference/statements/object View information from pay statements such as dates, gross pay, net pay, and earnings with deductions. The pay statement endpoints return a list of pay statements with attribute object breakdowns. The statement is related to the `link_id` from Truv's Income and Employment API. ## Attributes The table below covers the values for pay statements. | Attribute | Type | Description | | :-------------------- | :--------------- | :---------------------------------------------------------------------------------------------------- | | id | string | Unique ID of selected statement | | check\_number | string | External ID of pay stub from payroll provider | | pay\_date | date | Pay date | | net\_pay | string | Net pay | | net\_pay\_ytd | string | Net pay year to date | | gross\_pay | string | Gross pay | | gross\_pay\_ytd | string | Gross pay year to date | | bonus | string | Bonus amount | | commission | string | Commission amount | | hours | string | Total work hours during a pay period | | basis\_of\_pay | string | Basis of pay, includes four types of pay plans: `S` - Salary, `H` - Hourly, `D` - Daily, `W` - Weekly | | period\_start | date | Pay period start | | period\_end | date | Pay period end | | regular | string | Regular salary | | regular\_ytd | string | Regular salary year to date | | other\_pay\_ytd | string | All other pay forms year to date | | bonus\_ytd | string | Bonus year to date | | commission\_ytd | string | Commission year to date | | overtime | string | Overtime pay | | overtime\_ytd | string | Overtime pay year to date | | other\_pay | string | Other pay | | earnings | array of objects | Earnings for pay cycle by type | | earnings\_ytd | array of objects | Earnings year to date | | deductions | array of objects | Deductions for the pay cycle by type | | deductions\_ytd | array of objects | Deductions by type year to date | | md5sum | string | MD5 hash value computed based on file content | | file | url | Link to pay stub file (up to 2048 characters long) | | derived\_fields | array of strings | Array of derived fields | | missing\_data\_fields | array of strings | List of missing data fields from payroll response | *** ## Endpoints View the available endpoints for pay statements below. * [List all statements](/api-reference/statements/link-statements) * [Retrieve a statement](/api-reference/statements/retrieve-statement) *** ## Example response The JSON below is a sample response from the endpoint. ```json theme={null} { "id": "970c13c479b14f41b0b6a991ee8819f6", "pay_date": "2021-10-22", "net_pay": "1515.61", "net_pay_ytd": "35398.31", "gross_pay": "2153.85", "gross_pay_ytd": "45500.00", "bonus": null, "commission": null, "hours": "80.00", "basis_of_pay": "S", "period_start": "2021-10-03", "period_end": "2021-10-16", "regular": "2153.85", "regular_ytd": "42000.00", "bonus_ytd": "500.00", "commission_ytd": null, "overtime": null, "overtime_ytd": null, "other_pay": null, "other_pay_ytd": "3000.00", "earnings": [ { "name": "Regular", "category": "regular", "amount": "2153.85", "rate": "2153.85", "units": "72.00" } ], "earnings_ytd": [ { "name": "Regular", "category": "regular", "amount": "42000.00", "rate": null, "units": null }, { "name": "Spot Award", "category": "other_pay", "amount": "3000.00", "rate": null, "units": null }, { "name": "Bonus", "category": "bonus", "amount": "500.00", "rate": null, "units": null } ], "deductions": [ { "name": "Blue Ash Income Tax", "amount": "-26.94", "category": "local" }, { "name": "Medicare Tax", "amount": "-31.25", "category": "medicare" }, { "name": "CA State Income Tax", "amount": "-54.68", "category": "state" }, { "name": "Social Security Tax", "amount": "-133.63", "category": "socialsec" }, { "name": "Federal Income Tax", "amount": "-154.37", "category": "federal" }, { "name": "401K Dollars", "amount": "-237.37", "category": "retirement" } ], "deductions_ytd": [ { "name": "Federal Income Tax", "amount": "3639.64", "category": "federal" }, { "name": "Social Security Tax", "amount": "3090.03", "category": "socialsec" }, { "name": "401K Dollars", "amount": "2148.46", "category": "retirement" }, { "name": "CA State Income Tax", "amount": "1275.75", "category": "state" }, { "name": "Medicare Tax", "amount": "722.67", "category": "medicare" }, { "name": "Blue Ash Income Tax", "amount": "623.01", "category": "local" }, { "name": "Exp Repay", "amount": "-1397.87", "category": "benefit" } ], "md5sum": null, "file": null, "derived_fields": [], "missing_data_fields": [], "check_number": null } ``` # Retrieve a statement Source: https://truv.com/docs/api-reference/statements/retrieve-statement GET /v1/links/{link_id}/statements/{statement_id}/ Get the pay statement # Task Webhook Events Source: https://truv.com/docs/api-reference/tasks/events Webhook events for Task status changes and data object creation and updates Subscribe to these events via [Webhooks](/api-reference/webhooks/object) to track Task progress and data availability in real time. All webhook payloads include the [common fields](/api-reference/webhooks/object#webhook-payload-structure) (`webhook_id`, `event_type`, `event_created_at`, `updated_at`, `user_id`, `template_id`) plus the event-specific fields below. *** ## task-status-updated Fires for each Task status change during the connection lifecycle. This is the primary event for tracking verification progress. **Additional fields:** | Field | Description | | --------------- | -------------------------------------------------------------------------------- | | `task_id` | The Task identifier | | `link_id` | Account connection ID (use to retrieve `access_token`) | | `product` | `income`, `employment`, or `admin` | | `data_source` | `payroll`, `docs`, `insurance`, `financial_accounts`, or `tax` | | `tracking_info` | Custom metadata passed via `bridge_token` (nullable) | | `status` | Current task status (see [Connection Lifecycle](/api-reference/tasks/lifecycle)) | ```json theme={null} { "webhook_id": "488f424096d3461aa0e4cf11a985f6df", "task_id": "521442a087604e599c637db310d07402", "link_id": "d39d86dcc20c46e0ae75ba9ab1311a21", "product": "income", "data_source": "payroll", "tracking_info": null, "event_type": "task-status-updated", "event_created_at": "2022-08-24T13:55:12.845645Z", "updated_at": "2022-08-24T13:55:12.845666+00:00", "status": "done", "user_id": "88fef4cea64c40b5ad6727cc9b0b9fdc", "template_id": null } ``` When `status` is `done`, all data has been downloaded and processed. This is when you should fetch verification reports. *** ## Data object events: created These events fire once per Link for each non-refresh Task completion, indicating that data objects have been successfully retrieved for the first time. ### employment-created An employment record has been discovered and extracted. **Additional fields:** | Field | Description | | --------------- | -------------------------------- | | `object_id` | The employment object identifier | | `task_id` | The associated Task | | `tracking_info` | Custom metadata (nullable) | ```json theme={null} { "webhook_id": "b8c9d0e1f2a3b4c5d6a7b8c9d0e1f2a3", "event_type": "employment-created", "event_created_at": "2022-08-24T13:56:00.000000Z", "updated_at": "2022-08-24T13:56:00.000000+00:00", "object_id": "emp_obj_abc123", "task_id": "521442a087604e599c637db310d07402", "link_id": "d39d86dcc20c46e0ae75ba9ab1311a21", "product": "employment", "data_source": "payroll", "tracking_info": null, "user_id": "88fef4cea64c40b5ad6727cc9b0b9fdc", "template_id": null } ``` ### profile-created User profile information has been extracted. **Additional fields:** Same as `employment-created` (`object_id`, `task_id`, `tracking_info`). ### statements-created Pay statements have been retrieved. Fires once per Link for each non-refresh Task completion. **Additional fields:** | Field | Description | | --------------- | -------------------------------- | | `employment_id` | The associated employment record | | `task_id` | The associated Task | | `objects_count` | Number of statements retrieved | ```json theme={null} { "webhook_id": "c9d0e1f2a3b4c5d6a7b8c9d0e1f2a3b4", "event_type": "statements-created", "event_created_at": "2022-08-24T13:57:00.000000Z", "updated_at": "2022-08-24T13:57:00.000000+00:00", "employment_id": "emp_obj_abc123", "task_id": "521442a087604e599c637db310d07402", "link_id": "d39d86dcc20c46e0ae75ba9ab1311a21", "product": "income", "data_source": "payroll", "objects_count": 12, "user_id": "88fef4cea64c40b5ad6727cc9b0b9fdc", "template_id": null } ``` ### shifts-created Shift schedule data has been extracted. **Additional fields:** Same as `statements-created` (`employment_id`, `task_id`, `objects_count`). ### bank-accounts-created Connected bank accounts have been discovered. **Additional fields:** Same as `statements-created` (`employment_id`, `task_id`, `objects_count`). *** ## Data object events: updated These events fire after completing refresh Tasks. They only trigger when the `objects_count` value changes from the previous refresh. For example, if a person had 31 pay stubs and now has 32. ### employment-updated Employment data has been modified during a refresh. **Additional fields:** Same as `employment-created` (`object_id`, `task_id`, `tracking_info`). ### profile-updated Profile information has changed during a refresh. **Additional fields:** Same as `employment-created` (`object_id`, `task_id`, `tracking_info`). ### statements-updated New pay statements have been found during a refresh. **Additional fields:** Same as `statements-created` (`employment_id`, `task_id`, `objects_count`). ### shifts-updated Shift data has changed during a refresh. **Additional fields:** Same as `statements-created` (`employment_id`, `task_id`, `objects_count`). ### bank-accounts-updated Bank account data has changed during a refresh. **Additional fields:** Same as `statements-created` (`employment_id`, `task_id`, `objects_count`). *** ## Event summary | Event | Trigger | Key Fields | | ----------------------- | -------------------------------- | --------------------------------------------- | | `task-status-updated` | Task status transitions | `task_id`, `status`, `product`, `data_source` | | `employment-created` | First employment extraction | `object_id`, `task_id` | | `profile-created` | First profile extraction | `object_id`, `task_id` | | `statements-created` | First statement retrieval | `employment_id`, `objects_count` | | `shifts-created` | First shift extraction | `employment_id`, `objects_count` | | `bank-accounts-created` | First bank account discovery | `employment_id`, `objects_count` | | `employment-updated` | Employment changed on refresh | `object_id`, `task_id` | | `profile-updated` | Profile changed on refresh | `object_id`, `task_id` | | `statements-updated` | New statements on refresh | `employment_id`, `objects_count` | | `shifts-updated` | Shifts changed on refresh | `employment_id`, `objects_count` | | `bank-accounts-updated` | Bank accounts changed on refresh | `employment_id`, `objects_count` | # Task Lifecycle Source: https://truv.com/docs/api-reference/tasks/lifecycle How tasks progress through the flow: statuses, errors, and processing timelines When a user authenticates through [Truv Bridge](/developers/integration/bridge-widget/overview), the system creates a **Link**, a persistent connection to their payroll provider or bank. Each Link has a unique `access_token` that enables all subsequent data retrieval and modifications. **Tasks** are the individual actions performed through Links (e.g., fetching income data, switching direct deposits). Each task progresses through a defined status lifecycle. *** ## Task status flow The following diagram illustrates the flow. ```mermaid theme={null} %%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#EBF0FD', 'primaryBorderColor': '#2C64E3', 'primaryTextColor': '#111827', 'lineColor': '#9CA3AF', 'tertiaryColor': '#FFFFFF', 'edgeLabelBackground': '#FFFFFF'}}}%% flowchart TD N[new] --> LG[login] LG --> MFA[mfa] LG -->|no MFA required| P[parse] LG -->|login_error| E[error] MFA --> P MFA -->|mfa_error| E P --> FP[full_parse] P -->|parse_error| E FP --> D[done] FP -->|DDS only| SD[switch_deposit] SD --> D style N fill:#2C64E3,stroke:#1E4BB8,color:#FFFFFF style LG fill:#2C64E3,stroke:#1E4BB8,color:#FFFFFF style MFA fill:#2C64E3,stroke:#1E4BB8,color:#FFFFFF style P fill:#2C64E3,stroke:#1E4BB8,color:#FFFFFF style FP fill:#2C64E3,stroke:#1E4BB8,color:#FFFFFF style SD fill:#2C64E3,stroke:#1E4BB8,color:#FFFFFF style D fill:#2C64E3,stroke:#1E4BB8,color:#FFFFFF style E fill:#DC2626,stroke:#B91C1C,color:#FFFFFF ``` Tasks progress sequentially through these statuses: ``` new → login → mfa → parse → full_parse → done ``` Not all tasks go through every status. For example, a task may skip `mfa` if the provider doesn't require multi-factor authentication, or include `switch_deposit` for DDS tasks. *** ## Status definitions | Status | Description | | ------------------- | --------------------------------------------------------------------------------------------- | | **new** | Task initiated, queued for processing | | **login** | Attempting to log into the payroll provider or bank | | **mfa** | Completing multi-factor authentication | | **parse** | Collecting identity, employment, and paystub data | | **full\_parse** | Initial parse complete; downloading and parsing paystubs, W-2s, and additional income sources | | **switch\_deposit** | Processing direct deposit allocation changes (DDS tasks only) | | **done** | Task completed successfully | *** ## Error states Tasks may enter an error state at any point in the lifecycle: | Error Status | Description | | --------------------- | ------------------------------------------------------ | | **login\_error** | Authentication failed: incorrect credentials | | **mfa\_error** | Multi-factor authentication was not completed | | **config\_error** | Configuration issue requiring user or developer action | | **account\_locked** | The payroll or bank account is locked | | **unable\_to\_reset** | Failed to reset credentials at the provider | | **no\_data** | Provider connected successfully but returned no data | | **unavailable** | Provider service is temporarily inaccessible | | **error** | Generic connection failure | | **not\_supported** | Provider or HRIS system is not supported | Use [webhooks](/api-reference/webhooks/object) to get real-time notifications when tasks complete or encounter errors. See [Task Webhook Events](/api-reference/tasks/events) for the full list of task events. *** ## Data processing See [Data Processing](/api-reference/data-processing) for stage timing, median durations, data availability at each stage, and typical processing times. *** ## Relationship to Orders [Orders](/api-reference/orders/object) are the top-level containers for verification requests. When a user completes an Order: 1. The user authenticates through Bridge, creating a **Link** 2. A **Task** is created on that Link to retrieve the requested data 3. The Task progresses through the status lifecycle 4. On completion, data is available via the API and the order status updates A single Order can have multiple connections (e.g., a borrower connecting two employers), each with their own Link and Tasks. *** ## Monitor tasks ### Dashboard View task details in the Dashboard under **Activity > Tasks**. Filter by status, date, and provider. ### API Retrieve task status programmatically: ```bash theme={null} curl -X GET "https://prod.truv.com/v1/tasks/?query={link_id}" \ -H "X-Access-Client-Id: your_client_id" \ -H "X-Access-Secret: your_secret" ``` ### Webhooks Subscribe to task events for real-time monitoring: * `task-status-updated` with `status: done`: task finished successfully * `task-status-updated` with an error status: task encountered an error # The Tasks object Source: https://truv.com/docs/api-reference/tasks/object Track the status of individual verification connections within an order. Tasks track the status of individual verification connections within an order. Each task represents a single verification attempt and contains information about the connection type, data source, and current processing status. ## Attributes The attributes of Tasks are below. | Attribute | Type | Description | | :------------ | :------- | :--------------------------------------- | | id | string | Unique ID of the task | | status | string | Current status of the task | | created\_at | datetime | Timestamp when the task was created | | updated\_at | datetime | Timestamp when the task was last updated | | link\_id | string | ID of the associated Link | | product\_type | string | Type of product for the verification | | data\_source | string | Source of the verification data | *** ## Endpoints The list below contains available endpoints for task management. * [List tasks](/api-reference/tasks/tasks_list) * [Retrieve a task](/api-reference/tasks/tasks_read) # List all tasks Source: https://truv.com/docs/api-reference/tasks/tasks_list GET /v1/tasks/ The endpoint returns a list of Tasks. # Retrieve a task Source: https://truv.com/docs/api-reference/tasks/tasks_read GET /v1/tasks/{id}/ The endpoint returns a Task. # The Tax Documents object Source: https://truv.com/docs/api-reference/tax/object Learn more about the reference information for Tax Documents. # Attributes The table below has the values for Tax Document fields. | Attribute | Type | Description | | :---------------- | :------ | :---------------------------------------------------------------------------------------------- | | id | string | Unique identifier | | document\_type | string | Type of document | | document\_subtype | string | Subtype of document | | file | uri | Link to tax document file, format is specified in the content-type (up to 2048 characters long) | | md5sum | string | MD5 hash value computed based on file content | | year | integer | Tax document year | | fields | object | Additional metadata for a specific document type | # Endpoint The link below is the reference for the available Tax Document endpoint. * [List all tax documents](/api-reference/tax/tax-documents) # Example responses The sample below is a JSON response for the endpoint. The sections below have different document type examples. ```json theme={null} [ { "id": "string", "document_type": "W2", "file": "string", "md5sum": "string", "year": 2024, "fields": {...} // see below by form type } ] ``` ## W2 This payload response is an example of a W-2 form. ```json theme={null} { "federal_tax": "4102.75", "medicare_tax": "816.43", "medicare_wages": "58805.40", "social_security_tax": "3490.93", "social_security_wages": "58805.40", "wages": "56269.25" } ``` *** ## 1099 For all 1099 forms the year of the document along with user's information is provided. *** ## 1040 The 1040 tax document sample below is the example JSON payload. ```json theme={null} { "total_income": "1000.00" } ``` # Retrieve tax document Source: https://truv.com/docs/api-reference/tax/tax-document GET /v1/links/{link_id}/tax/{tax_id}/ The endpoint returns a tax document. # List all tax documents Source: https://truv.com/docs/api-reference/tax/tax-documents GET /v1/links/{link_id}/tax/ The endpoint returns a list of tax documents. # The Templates object Source: https://truv.com/docs/api-reference/templates/object Customization templates let you configure the design and text of Truv Bridge and your workflow. Find Truv **Templates** within the Customization section of your Dashboard. Configure Truv Bridge and your order flow for your specific product types when creating a customization template. For example, you can apply different branding and language according to your specific client needs. Your template configurations take priority over other settings, such as universal branding or those from **Truv Bridge** and **Order**s. ## Attributes View the payload for retrieving customizable template information. | Attribute | Type | Description | | :--------------------- | :------- | :--------------------------------------------------- | | id | string | Unique identifier of template | | name | string | Template name | | products | array | List of products with applied customizable templates | | default\_for\_products | boolean | Status of customizable template as product default | | bridge | object | Configuration object for Truv Bridge template | | branding | object | Configuration object for branding template | | orders | object | Configuration object for Orders template | | document\_upload | object | Configuration object for Document upload template | | created\_at | datetime | Timestamp for created customizable template | | updated\_at | datetime | Timestamp for updated customizable template | *** ## Endpoints The table below covers the available endpoints for customizable templates. * [List all customizable templates](/api-reference/templates/templates_list) - GET /templates/ * [Create a customizable template](/api-reference/templates/templates_create) - POST /templates/ * [Retrieve a customizable template](/api-reference/templates/templates_read) - GET /templates/\{template\_id}/ * [Update a customizable template](/api-reference/templates/templates_partial_update) - PATCH /templates/\{template\_id}/ * [Delete a customizable template](/api-reference/templates/templates_delete) - DELETE /templates/\{template\_id}/ *** ## What templates control Templates give you fine-grained control over the verification experience across several areas: | Area | Capabilities | | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Bridge UI** | Filter search results by provider category, restrict visible employers, customize search header text, toggle the Truv logo and support button | | **Branding** | Set company logo, accent and background colors, button styles, custom end-user agreement, and privacy policy link | | **Communications** | Customize or suppress Truv-sent email and SMS notifications using `suppress_user_notifications`. Configure reminder timing, subject lines, and message text independently for first-touch and follow-up messages | | **Data & products** | Control which products are available for the template, configure document upload requirements (types, counts, required vs optional), and set report return preferences | | **Order pages** | Customize the hosted order landing page header, body text, FAQ visibility, and the success/expired screen content | To suppress all Truv-sent notifications and handle communications yourself, enable `suppress_user_notifications` in the template's orders configuration. *** ## Example response View the JSON response example below. ```json theme={null} { "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "name": "My template", "products": [], "default_for_products": false, "bridge": { "texts": { "search_header": "string", "success_cta": "string" }, "hide_truv_logo": false, "hide_support_button": false }, "branding": { "company_name": "string", "accent_color": "#aabb00", "background_color": "rgba(0, 0, 255, 0.5)", "hide_confetti": false, "custom_end_user_agreement": { "header": "string", "url": "string" } }, "orders": { "link_expiration": "24", "custom_field_title": "string", "support_email": "user@example.com", "first_sms": { "text": "string", "apply_for_reminder": false }, "reminder_sms": { "text": "string" }, "first_email": { "subject": "string", "header": "string", "button": "string", "caption": "string", "apply_for_reminder": false }, "reminder_email": { "subject": "string", "header": "string", "button": "string", "caption": "string" }, "landing": { "header": "string", "body": "string", "hide_faq": false, "success_screen": { "header": "string", "body": "string" }, "expired_screen": { "header": "string", "body": "string" } }, "document_upload": { "is_enabled": true, "paystub": { "is_enabled": true, "is_required": true, "title": "Upload two most recent paystubs", "description": "PDF files only under 15 MB.", "button": "Upload", "submit_title": "Did you upload two most recent paystubs?", "min_count": 2, "max_count": 5 }, "w2": { "is_enabled": true, "is_required": false, "title": "Upload two most recent W2s", "description": "PDF files only under 15 MB.", "button": "Upload", "submit_title": "Did you upload two most recent W2s?", "min_count": 2, "max_count": 5 }, "f1099": { "is_enabled": true, "is_required": true, "title": "Upload two most recent 1099s", "description": "PDF files only under 15 MB.", "button": "Upload", "submit_title": "Did you upload two most recent 1099s?", "min_count": 1, "max_count": 1 }, "f1040": { "is_enabled": true, "is_required": true, "title": "Upload most recent 1040", "description": "PDF files only under 15 MB.", "button": "Upload", "submit_title": "Did you upload most recent 1040?", "min_count": 1, "max_count": 1 }, "insurance_home_policy": { "is_enabled": true, "is_required": true, "title": "Upload home insurance policy", "description": "PDF files only under 15 MB.", "button": "Upload", "submit_title": "Did you upload policy?", "min_count": 1, "max_count": 1 }, "insurance_auto_policy": { "is_enabled": true, "is_required": true, "title": "Upload auto insurance policy", "description": "PDF files only under 15 MB.", "button": "Upload", "submit_title": "Did you upload policy?", "min_count": 1, "max_count": 1 } } }, "created_at": "2022-05-04T11:30:00Z", "updated_at": "2022-05-04T12:00:00Z" } ``` # Create a customization template Source: https://truv.com/docs/api-reference/templates/templates_create POST /v1/templates/ The endpoint creates a customization template. # Delete a customization template Source: https://truv.com/docs/api-reference/templates/templates_delete DELETE /v1/templates/{template_id}/ The endpoint deletes a customization template. # List all customization templates Source: https://truv.com/docs/api-reference/templates/templates_list GET /v1/templates/ The endpoint returns a list of all customization templates for user. # Update a customization template Source: https://truv.com/docs/api-reference/templates/templates_partial_update PATCH /v1/templates/{template_id}/ The endpoint updates a customization template. # Retrieve a customization template Source: https://truv.com/docs/api-reference/templates/templates_read GET /v1/templates/{template_id}/ This endpoint retrieves a customization template. # List all bank transactions Source: https://truv.com/docs/api-reference/transactions/link-bank-data-transactions GET /v1/links/{link_id}/transactions/ The endpoint allows developers to receive user-authorized transaction data. # The Transactions object Source: https://truv.com/docs/api-reference/transactions/object Transaction history from connected financial accounts. # Attributes ## Accounts object Use the table below for reference to the account object values. | Attribute | Type | Description | | :---------- | :--------------- | :------------------------------------------------------------------- | | id | string | Unique identifier of account | | created\_at | date-time | Date and time account was created | | updated\_at | date-time | Date and time account was most recently updated | | type | string | Parent type of the account | | subtype | string | Account subtype | | mask | string | Masked banking account number associated with account | | nickname | string | Alternate name for account | | balances | array of objects | List of balance information, see [Balances object](#balances-object) | ### Balances object Find information about the balances object values in the table below. | Attribute | Type | Description | | :----------------- | :----- | :----------------------- | | currency\_code | string | Currency | | balance | string | Balance amount | | available\_balance | string | Available balance amount | | credit\_limit | string | Credit limit | *** ## Transactions object The values in this table have information from the transactions object. | Attribute | Type | Description | | :----------------------- | :--------------- | :--------------------------------------------------- | | id | string | Unique identifier of transaction | | created\_at | date-time | Timestamp when transaction was created in Truv | | updated\_at | date-time | Timestamp when transaction was last updated in Truv | | account\_id | string | account\_id | | external\_id | string | External system transaction identifier | | amount | string | Monetary amount of transaction | | currency\_code | string | Three-character ISO 4217 currency code | | check\_number | string | Check number for transaction | | categories | array of strings | List of categories assigned to this transaction | | description | string | Human-readable transaction description | | status | string | Status of transaction, either `POSTED` or `PENDING` | | type | string | Type of transaction, either `CREDIT` or `DEBIT` | | posted\_at | date-time | Timestamp for movement of funds | | transacted\_at | date-time | Timestamp when transaction occurred | | memo | string | Additional descriptive information about transaction | | merchant\_category\_code | string | ISO 18245 category code for transaction | | location | object | Location, see [Location object](#location-object) | ### Location object The two values in this table are for the location object. | Attribute | Type | Description | | :-------- | :---- | :---------- | | latitude | float | Latitude | | longitude | float | Longitude | # Endpoints Use the endpoint below for information about transactions in an account. * List all bank transactions # Example response The sample below is a JSON response for the endpoint. ```json theme={null} { "count": 0, "next": "string", "previous": "string", "accounts": [ { "id": "24d7e80942ce4ad58a93f70ce4115f5c", "created_at": "2022-05-04T11:30:00Z", "updated_at": "2022-05-04T12:00:00Z", "type": "CHECKING", "subtype": "MONEY_MARKET", "mask": "6789", "nickname": "My account", "balances": { "currency_code": "USD", "balance": "100.00", "available_balance": "50.99", "credit_limit": "200.00" } } ], "transactions": [ { "id": "24d7e80942ce4ad58a93f70ce4115f5c", "created_at": "2022-05-04T11:30:00Z", "updated_at": "2022-05-04T12:00:00Z", "account_id": "68a7e80942ce4ad58a93f70ce411549a", "external_id": "external_key_243901", "amount": "100.00", "currency_code": "USD", "check_number": "123456", "categories": [ "Transfer" ], "description": "Some transaction", "status": "POSTED", "type": "DEBIT", "posted_at": "2022-05-04T11:30:00Z", "transacted_at": "2022-05-04T11:30:00Z", "memo": "", "merchant_category_code": 5967, "location": { "latitude": "40.730610", "longitude": "-73.935242" } } ] } ``` ## Transaction categories | Category | Subcategories | | ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Auto & Transport | Auto Insurance, Auto Payment, Gas, Parking, Public Transportation, Service & Parts | | Bills & Utilities | Domain Names, Fraud Protection, Home Phone, Hosting, Internet, Mobile Phone, Television, Utilities | | Business Services | Advertising, Legal, Office Supplies, Printing, Shipping | | Education | Books & Supplies, Student Loan, Tuition | | Entertainment | Amusement, Arts, Movies & DVDs, Music, Newspapers & Magazines | | Fees & Charges | ATM Fee, Banking Fee, Finance Charge, Late Fee, Service Fee, Trade Commissions | | Financial | Financial Advisor, Life Insurance, BNPL, Payday Loan, EWA Lender, Loan Disbursement | | Food & Dining | Alcohol & Bars, Coffee Shops, Fast Food, Groceries, Restaurants | | Gifts & Donations | Charity, Gift | | Health & Fitness | Dentist, Doctor, Eyecare, Gym, Health Insurance, Pharmacy, Sports | | Home | Furnishings, Home Improvement, Home Insurance, Home Services, Home Supplies, Lawn & Garden, Mortgage & Rent | | Income | Bonus, Interest Income, Paycheck, Reimbursement, Rental Income, Returned Purchase, EWA Payroll, Retirement, Government Employment, Government Benefits, Private Benefits, Unemployment, Tax credits, Gig Economy | | Investments | Buy, Deposit, Dividend & Cap Gains, Sell, Withdrawal | | Kids | Allowance, Baby Supplies, Babysitter & Daycare, Child Support, Kids Activities, Toys | | Personal Care | Hair, Laundry, Spa & Massage | | Pets | Pet Food & Supplies, Pet Grooming, Veterinary | | Shopping | Books, Clothing, Hobbies, Sporting Goods | | Taxes | Federal Tax, Local Tax, Property Tax, Sales Tax, State Tax | | Transfer | Credit Card Payment, Transfer for Cash Spending, Mortgage Payment, P2P | | Travel | Air Travel, Hotel, Rental Car & Taxi, Vacation | | Uncategorized | Cash, Check | # List all documents Source: https://truv.com/docs/api-reference/uploaded-documents/list-documents GET /v1/links/{link_id}/documents/ The endpoint returns a list of documents. # The Uploaded Documents object Source: https://truv.com/docs/api-reference/uploaded-documents/object Find more information about the responses for uploaded documents. # Attributes The table below covers information from the response for uploaded documents. The response body is an array of objects and can include multiple document values. | Attribute | Type | Description | | :---------- | :----------- | :----------------------------------------------------------------------------------------------------------------------------- | | id | string | Document ID | | type | string | Document type, valid responses below `PAYSTUB`, `W2`, `F1099`, `F1040`, `INSURANCE_HOME_POLICY`, `INSURANCE_AUTO_POLICY` | | subtype | string, null | Document subtype, valid responses below `F1099_DIV`, `F1099_G`, `F1099_INT`, `F1099_MISC`, `F1099_NEC`, `F1099_R`, `F_SSA1099` | | file | uri | Document file link, file may be absent or partially uploaded (up to 2048 characters long) | | filename | string | Document file name | | mimetype | string | Document mimetype | | created\_at | date-time | Date when document was uploaded | | updated\_at | date-time | Date when document was updated | Document file URLs are **temporary pre-signed URLs that expire after 1 hour**. After expiry, the URL returns an access error. To get a fresh URL, make a new API request to the [Retrieve document](/api-reference/uploaded-documents/retrieve-document) endpoint. This does not trigger a data refresh or re-upload — it simply generates a new pre-signed URL for the same file. # Endpoints Use the endpoints below to get information on uploaded documents. * [List all documents](/api-reference/uploaded-documents/list-documents) * [Retrieve document](/api-reference/uploaded-documents/retrieve-document) # Example response The sample below is a JSON response for the endpoint. ```json theme={null} [ { "id": "24d7e80942ce4ad58a93f70ce4115f5c", "type": "W2", "subtype": null, "file": "https://citadelid-resources.s3.us-west-2.amazonaws.com/doc_upload/w2.pdf", "filename": "most.recent.paystub.pdf", "mimetype": "application/pdf", "created_at": "2023-08-03T23:52:12.751Z", "updated_at": "2023-08-03T23:52:12.751Z" } ] ``` # Retrieve document Source: https://truv.com/docs/api-reference/uploaded-documents/retrieve-document GET /v1/links/{link_id}/documents/{doc_id}/ The endpoint returns a document. # Create an assets report Source: https://truv.com/docs/api-reference/user-asset-verification-reports/assets-report-create POST /v1/users/{user_id}/assets/reports/ The endpoint creates an assets report for the user. # Retrieve an assets report Source: https://truv.com/docs/api-reference/user-asset-verification-reports/assets-report-retrieve GET /v1/users/{user_id}/assets/reports/{report_id}/ The endpoint retrieves an assets report for the user. # The User Asset Reports object Source: https://truv.com/docs/api-reference/user-asset-verification-reports/object User-level Verification of Assets (VOA) reports that aggregate asset and financial account data across all account links. User Reports aggregate asset and financial account data across all of a user's account links into a single report. For data from a single account link, see [Income Insights Reports](/api-reference/income-insights/object). # Attributes The tables below have the values, format, and descriptions for the responses. | Attribute | Type | Description | | :------------------------ | :----------------- | :-------------------------------------------------------------------------------- | | report\_id | string | Unique identifier of the report | | created\_at | date-time | Timestamp when report was created | | completed\_at | date-time | Timestamp when report was completed | | days\_requested | integer | Number of days for requested transactions | | large\_deposit\_threshold | integer (nullable) | Amount that must be met or exceeded for deposits to be marked as large | | is\_voe | boolean | Indicates whether the report is a Deposit-based Verification of Employment (DVOE) | | borrower | object | Borrower information, see [Borrower object](#borrower-object) | | links | array of objects | List of assets links, see [Links object](#links-object) | | summary | object | Balance summary information for account, see [Summary object](#summary-object) | ## Borrower object Information in the table below is for the borrower object. | Attribute | Type | Description | | :----------------- | :-------- | :----------------------------------- | | id | string | Unique ID of user | | external\_user\_id | string | External user ID | | first\_name | string | First name | | last\_name | string | Last name | | email | string | Email address | | phone | string | Phone number | | ssn | string | Social Security Number | | created\_at | date-time | Timestamp when user was created | | updated\_at | date-time | Timestamp when user was last updated | *** ## Links object The information in this table is for values in the Links object. | Attribute | Type | Description | | :------------- | :--------------- | :--------------------------------------------------------------- | | link\_id | string | Unique identifier of the link | | tracking\_info | string | Additional optional identifier passed by user | | provider | string | ID of the financial institution | | provider\_name | string | Name of the financial institution | | accounts | array of objects | List of assets accounts, see [Accounts object](#accounts-object) | ### Accounts object The table below covers values in the accounts object. | Attribute | Type | Description | | :------------------------------ | :--------------- | :-------------------------------------------------------------------------------- | | id | string | Unique identifier of account | | created\_at | date-time | Date and time account was created | | updated\_at | date-time | Date and time account was most recently updated | | type | string | Parent type of the account, example `CHECKING` or `SAVINGS` | | subtype | string | Account's subtype, example `PLAN_401_K`, `MONEY_MARKET`, or `HOME_EQUITY` | | mask | string | Masked banking account number associated with account | | routing\_number | string | Bank routing number associated with the account | | nickname | string | Alternate name for account | | days\_available | integer | Available number of days for transactions from `days_requested` | | balance\_as\_of | date-time | Timestamp for when balance was captured | | balances | object | List of balance information from account, see [Balances object](#balances-object) | | transactions | array of objects | List of transactions for account, see [Transactions object](#transactions-object) | | owners | array of objects | List of owners for account, see [Owners object](#owners-object) | | summary | array of objects | Balance summary information for account, see [Summary object](#summary-object) | | same\_owner\_as\_requested | boolean | Whether account owner matches the requested user | | direct\_deposit\_from\_employer | boolean | Whether account has direct deposit from employer | | nsf | integer | NSF (Non-sufficient funds) count | #### Balances object The information in the table below refers to values in the balances object. | Attribute | Type | Description | | :----------------- | :----- | :------------------------------------------------------------------------------------------------------------------------- | | currency\_code | string | Three-character ISO 4217 currency code | | balance | string | Current account balance | | available\_balance | string | Available balance for use in checking and savings asset accounts, `PENDING` transactions may not reflect available balance | | credit\_limit | string | Credit limit associated with account | #### Transactions object The values for the transactions object are in the table below. | Attribute | Type | Description | | :----------------------- | :--------------- | :-------------------------------------------------- | | id | string | Unique identifier of transaction | | external\_id | string | External system transaction identifier | | amount | string | Monetary amount of transaction | | currency\_code | string | Three-character ISO 4217 currency code | | check\_number | string | Check number for transaction | | categories | array of strings | List of categories assigned to this transaction | | description | string | Human-readable transaction description | | status | string | Status of transaction, either `POSTED` or `PENDING` | | type | string | Type of transaction, either `CREDIT` or `DEBIT` | | posted\_at | date-time | Timestamp when transaction was posted | | transacted\_at | date-time | Timestamp when transaction took place | | merchant\_category\_code | int32 | ISO 18245 category code for transaction | | ending\_daily\_balance | number | Daily ending balance for transaction | | is\_direct\_deposit | boolean | Whether transaction is direct deposit | | is\_subscription | boolean | Whether transaction is subscription | #### Owners object The values in this table are for the address object of the company. | Attribute | Type | Description | | :------------- | :----- | :--------------------------------------------------------------- | | id | string | ID of owner | | full\_name | string | Full name | | email | string | Email address | | phone | string | Phone number | | address | object | Address object with street, city, state, zip, and country fields | | relation\_type | string | Relationship type for account owner (see below) | ##### Relation types The table below contains valid relation types for account owners. | Relation Type | Description | | :--------------- | :----------------------------------------- | | PRIMARY | Primary account holder | | BUSINESS | Business account relationship | | JOINT | Joint account holder | | SECONDARY | Secondary account holder | | AUTHORIZED\_USER | Authorized user on the account | | FOR\_BENEFIT\_OF | Account held for benefit of another person | ## Account types and subtypes **Parent types:** | Type | Description | | ------------------------- | --------------------------------------- | | `ANY` | Not provided by data partner or invalid | | `CHECKING` | Checking account | | `SAVINGS` | Savings account | | `LOAN` | Loan account | | `CREDIT_CARD` | Credit card | | `INVESTMENT` | Investment account | | `LINE_OF_CREDIT` | Line of credit | | `MORTGAGE` | Mortgage | | `PROPERTY` | Property | | `CASH` | Cash account | | `INSURANCE` | Insurance | | `PREPAID` | Prepaid account | | `CHECKING_LINE_OF_CREDIT` | Checking with overdraft line | **Subtypes by parent:** | Subtype | Parent Type | | ------------------------------------------- | ----------- | | `MONEY_MARKET` | SAVINGS | | `CERTIFICATE_OF_DEPOSIT` | SAVINGS | | `AUTO` | LOAN | | `STUDENT` | LOAN | | `SMALL_BUSINESS` | LOAN | | `PERSONAL` | LOAN | | `PERSONAL_WITH_COLLATERAL` | LOAN | | `HOME_EQUITY` | LOAN | | `BOAT` | LOAN | | `POWERSPORTS` | LOAN | | `RV` | LOAN | | `HELOC` | LOAN | | `PLAN_401_K` | INVESTMENT | | `PLAN_403_B` | INVESTMENT | | `PLAN_529` | INVESTMENT | | `IRA` | INVESTMENT | | `ROLLOVER_IRA` | INVESTMENT | | `ROTH_IRA` | INVESTMENT | | `TAXABLE` | INVESTMENT | | `NON_TAXABLE` | INVESTMENT | | `BROKERAGE` | INVESTMENT | | `TRUST` | INVESTMENT | | `UNIFORM_GIFTS_TO_MINORS_ACT` | INVESTMENT | | `PLAN_457` | INVESTMENT | | `PENSION` | INVESTMENT | | `EMPLOYEE_STOCK_OWNERSHIP_PLAN` | INVESTMENT | | `SIMPLIFIED_EMPLOYEE_PENSION` | INVESTMENT | | `SIMPLE_IRA` | INVESTMENT | | `PLAN_ROTH_401_K` | INVESTMENT | | `FIXED_ANNUITY` | INVESTMENT | | `VARIABLE_ANNUITY` | INVESTMENT | | `HSA` | INVESTMENT | | `TAX_FREE_SAVINGS_ACCOUNT` | INVESTMENT | | `INDIVIDUAL` | INVESTMENT | | `REGISTERED_RETIREMENT_INCOME_FUND` | INVESTMENT | | `CASH_MANAGEMENT_ACCOUNT` | INVESTMENT | | `EMPLOYEE_STOCK_PURCHASE_PLAN` | INVESTMENT | | `REGISTERED_EDUCATION_SAVINGS_PLAN` | INVESTMENT | | `PROFIT_SHARING_PLAN` | INVESTMENT | | `UNIFORM_TRANSFER_TO_MINORS_ACT` | INVESTMENT | | `PLAN_401_A` | INVESTMENT | | `SARSEP_IRA` | INVESTMENT | | `FIXED_ANNUITY_TRADITIONAL_IRA` | INVESTMENT | | `VARIABLE_ANNUITY_TRADITIONAL_IRA` | INVESTMENT | | `SEPP_IRA` | INVESTMENT | | `INHERITED_TRADITIONAL_IRA` | INVESTMENT | | `FIXED_ANNUITY_ROTH_IRA` | INVESTMENT | | `VARIABLE_ANNUITY_ROTH_IRA` | INVESTMENT | | `INHERITED_ROTH_IRA` | INVESTMENT | | `COVERDELL` | INVESTMENT | | `ADVISORY_ACCOUNT` | INVESTMENT | | `BROKERAGE_MARGIN` | INVESTMENT | | `CHARITABLE_GIFT_ACCOUNT` | INVESTMENT | | `CHURCH_ACCOUNT` | INVESTMENT | | `CONSERVATORSHIP` | INVESTMENT | | `CUSTODIAL` | INVESTMENT | | `DEFINED_BENEFIT_PLAN` | INVESTMENT | | `DEFINED_CONTRIBUTION_PLAN` | INVESTMENT | | `EDUCATIONAL` | INVESTMENT | | `ESTATE` | INVESTMENT | | `EXECUTOR` | INVESTMENT | | `GROUP_RETIREMENT_SAVINGS_PLAN` | INVESTMENT | | `GUARANTEED_INVESTMENT_CERTIFICATE` | INVESTMENT | | `HRA` | INVESTMENT | | `INDEXED_ANNUITY` | INVESTMENT | | `INVESTMENT_CLUB` | INVESTMENT | | `IRREVOCABLE_TRUST` | INVESTMENT | | `JOINT_TENANTS_BY_ENTIRITY` | INVESTMENT | | `JOINT_TENANTS_COMMUNITY_PROPERTY` | INVESTMENT | | `JOINT_TENANTS_IN_COMMON` | INVESTMENT | | `JOINT_TENANTS_WITH_RIGHTS_OF_SURVIVORSHIP` | INVESTMENT | | `KEOUGH_PLAN` | INVESTMENT | | `LIFE_INCOME_FUND` | INVESTMENT | | `LIVING_TRUST` | INVESTMENT | | `LOCKED_IN_RETIREMENT_ACCOUNT` | INVESTMENT | | `LOCKED_IN_RETIREMENT_INVESTMENT_FUND` | INVESTMENT | | `LOCKED_IN_RETIREMENT_SAVINGS_ACCOUNT` | INVESTMENT | | `MONEY_PURCHASE_PLAN` | INVESTMENT | | `PARTNERSHIP` | INVESTMENT | | `PLAN_409_A` | INVESTMENT | | `PLAN_ROTH_403_B` | INVESTMENT | | `REGISTERED_DISABILITY_SAVINGS_PLAN` | INVESTMENT | | `REGISTERED_LOCKED_IN_SAVINGS_PLAN` | INVESTMENT | | `REGISTERED_PENSION_PLAN` | INVESTMENT | | `REGISTERED_RETIREMENT_SAVINGS_PLAN` | INVESTMENT | | `REVOCABLE_TRUST` | INVESTMENT | | `ROTH_CONVERSION` | INVESTMENT | | `SOLE_PROPRIETORSHIP` | INVESTMENT | | `SPOUSAL_IRA` | INVESTMENT | | `SPOUSAL_ROTH_IRA` | INVESTMENT | | `TESTAMENTARY_TRUST` | INVESTMENT | | `THRIFT_SAVINGS_PLAN` | INVESTMENT | | `INHERITED_ANNUITY` | INVESTMENT | | `CORPORATE_ACCOUNT` | INVESTMENT | | `LIMITED_LIABILITY_ACCOUNT` | INVESTMENT | | `VEHICLE_INSURANCE` | INSURANCE | | `DISABILITY` | INSURANCE | | `HEALTH` | INSURANCE | | `LONG_TERM_CARE` | INSURANCE | | `PROPERTY_AND_CASUALTY` | INSURANCE | | `UNIVERSAL_LIFE` | INSURANCE | | `TERM_LIFE` | INSURANCE | | `WHOLE_LIFE` | INSURANCE | | `ACCIDENTAL_DEATH_AND_DISMEMBERMENT` | INSURANCE | | `VARIABLE_UNIVERSAL_LIFE` | INSURANCE | #### Summary object Information in the table below are for the summary object. | Attribute | Type | Description | | :------------- | :----- | :------------------------------------- | | avg\_30 | string | Average balance for 30 days | | avg\_60 | string | Average balance for 60 days | | avg\_90 | string | Average balance for 90 days | | currency\_code | string | Three-character ISO 4217 currency code | # Endpoints Use the endpoints below to manage user-level asset reports. * [Create an assets report](/api-reference/user-asset-verification-reports/assets-report-create) * [Retrieve an assets report](/api-reference/user-asset-verification-reports/assets-report-retrieve) # Example response The JSON below is a sample response for the endpoint. ```json theme={null} { "report_id": "7d4fcb86b81a4880955beea558092391", "created_at": "2022-05-04T11:30:00Z", "completed_at": "2022-05-04T12:00:00Z", "days_requested": 60, "large_deposit_threshold": 500, "is_voe": true, "borrower": { "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "external_user_id": "12345", "first_name": "John", "last_name": "Doe", "email": "john.doe@example.com", "phone": "+14155554193", "ssn": "222233333", "created_at": "2022-05-04T11:30:00Z", "updated_at": "2022-05-04T12:00:00Z" }, "links": [ { "link_id": "150491a20bdb4292bb2a2ad8554fecba", "tracking_info": "string", "provider": "string", "provider_name": "string", "accounts": [ { "id": "4d601895417c46ec99633978db12a866", "created_at": "2022-05-04T11:30:00Z", "updated_at": "2022-05-04T12:00:00Z", "type": "string", "subtype": "string", "mask": "string", "routing_number": "55999876", "nickname": "string", "days_available": 0, "balance_as_of": "2025-05-04T12:00:00Z", "balances": { "currency_code": "string", "balance": "string", "available_balance": "string", "credit_limit": "string" }, "transactions": [ { "id": "7d4fcb86b81a4880955beea558092391", "external_id": "string", "amount": "string", "currency_code": "string", "check_number": "string", "categories": [ "string" ], "description": "string", "status": "POSTED", "type": "DEBIT", "posted_at": "2022-05-05T15:30:00Z", "transacted_at": "2022-05-04T12:00:00Z", "merchant_category_code": 0, "ending_daily_balance": 0, "is_direct_deposit": true, "is_subscription": true } ], "owners": [ { "id": "2b623fa2fa9e49cea17d9692caa884c5", "full_name": "John Doe", "email": "john.doe@example.com", "phone": "14155554193", "address": { "street": "1 Morgan Ave", "city": "Los Angeles", "state": "CA", "zip": "90210", "country": "US" }, "relation_type": "PRIMARY" } ], "summary": { "avg_30": "string", "avg_60": "string", "avg_90": "string", "currency_code": "string", "balance": "string" }, "same_owner_as_requested": true, "direct_deposit_from_employer": true, "nsf": 0 } ] } ], "summary": { "avg_30": "string", "avg_60": "string", "avg_90": "string", "currency_code": "string", "balance": "string" } } ``` # The User Income & Employment Reports object Source: https://truv.com/docs/api-reference/user-income-and-employment-reports/object User-level Verification of Income and Employment (VOIE) reports that aggregate income and employment data across all account links. User Reports aggregate income and employment data across all of a user's account links into a single report. For data from a single account link, see [Link Income and Employment Reports](/api-reference/account-link-income-and-employment-reports/object). **Link-level vs User-level reports:** Link-level reports (`GET /v1/links/{link_id}/income/report/`) contain data from a single payroll connection and include fields like `status`, `is_suspicious`, `access_token`, and `provider`. User-level reports (`POST /v1/users/{user_id}/income_and_employment/report/`) aggregate across all connections and include `report_id` and `gse_accepted` for GSE submission. Use user-level reports for mortgage/GSE workflows. # Attributes The tables below have the values, format, and descriptions for the responses. | Attribute | Type | Description | | :------------ | :--------------- | :---------------------------------------------------------- | | report\_id | string | Unique identifier of the report | | created\_at | date-time | Timestamp when the report was created | | completed\_at | date-time | Timestamp when the report was completed | | links | array of objects | List of employment links, see [Links object](#links-object) | ## Links object The information in this table is for values in the Links object. | Attribute | Type | Description | | :------------- | :--------------- | :------------------------------------------------------------------- | | link\_id | string | Unique identifier of the link | | tracking\_info | string | Additional optional identifier passed by user | | provider | string | Data provider ID | | provider\_name | string | Data provider name | | employments | array of objects | List of employee data, see [Employments object](#employments-object) | ### Employments object The Employments object contains the values and descriptions below. | Attribute | Type | Description | | :---------------------- | :--------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | income | string | Income amount not including commission or bonuses, only for income product. Null for employment product | | income\_unit | string | Pay interval for income field, only for income product: `YEARLY` - Annual income, `MONTHLY` - Monthly income, `WEEKLY` - Weekly income, `DAILY` - Daily income, `HOURLY` - Hourly income. Null for employment product | | pay\_rate | string | Payment rate per pay cycle, only for income product. Null for employment product | | pay\_frequency | string | Pay frequency, only for income product: `M` - Monthly, `SM` - Semi-Monthly, `W` - Weekly, `BW` - Bi-Weekly, `A` - Annually, `SA` - Semiannually, `C` - Commission. Null for employment product | | statements | array of objects | List of paystubs received from a payroll provider, only for income product, see [Statements object](#statements-object). Null for employment product | | annual\_income\_summary | array of objects | Annual income summary by years, only for income product, see [Annual income summary object](#annual-income-summary-object). Null for employment product | | bank\_accounts | array of objects | List of bank accounts linked to employment, only for income product, see [Bank accounts object](#bank-accounts-object). Null for employment product | | w2s | array of objects | List of W-2 forms linked to employment, only for income product, see [W2s object](#w2s-object). Null for employment product | | id | string | Unique ID | | is\_active | Boolean | Status of active employment | | job\_title | string | Employee's job title | | job\_type | string | Employee's job type: `F` - Full Time, `P` - Part Time, `S` - Seasonal, `D` - Daily (per diem), `C` - Contract | | start\_date | date | Employee's hire date | | original\_hire\_date | date | Original hire date | | end\_date | date | Employee's end date | | external\_last\_update | date | Indicates date of last updated employment data from Payroll Provider | | derived\_fields | array of strings | Array of derived fields | | missing\_data\_fields | array of strings | List of missing data fields from payroll response | | manager\_name | string | Supervisor's name | | profile | object | Person's identity information | | company | object | [Company object](#company-object) | | gse\_accepted | Boolean | Status of provider eligibility from Fannie Mae Desktop Underwriter | #### Company object This table covers values within the company object. | Attribute | Type | Description | | :-------- | :----- | :-------------------------------- | | name | string | Company name | | address | object | [Address object](#address-object) | | phone | string | Company phone number | | ein | string | Employer Identification Number | ##### Address object The values in this table are for the address object of the company. | Attribute | Type | Description | | :-------- | :----- | :---------- | | street | string | Street | | city | string | City | | state | string | State | | zip | string | Zip | | country | string | Country | #### Statements object View the table below for information from the Statements object. | Attribute | Type | Description | | :-------------------- | :--------------- | :------------------------------------------------------------------ | | id | string | Unique ID | | check\_number | string | External ID of pay stub from payroll provider | | pay\_date | date | Pay date | | net\_pay | string | Net pay | | net\_pay\_ytd | string | Net pay year to date | | gross\_pay | string | Gross pay | | gross\_pay\_ytd | string | Gross pay year to date | | bonus | string | Bonus | | commission | string | Commission | | hours | string | Work hours during pay period | | basis\_of\_pay | string | Basis of pay: `S` - Salary, `H` - Hourly, `D` - Daily, `W` - Weekly | | period\_start | date | Period start | | period\_end | date | Period end | | regular | string | Regular pay | | regular\_ytd | string | Regular salary year to date | | other\_pay\_ytd | string | All other payment year to date | | bonus\_ytd | string | Bonus year to date | | commission\_ytd | string | Commission year to date | | overtime | string | Overtime pay | | overtime\_ytd | string | Overtime pay year to date | | other\_pay | string | All other payment | | earnings | array of objects | Earnings for this pay cycle by type | | earnings\_ytd | array of objects | Earnings year to date by type | | deductions | array of objects | Deductions for pay cycle by type | | deductions\_ytd | array of objects | Deductions year to date by type | | md5sum | string | MD5 hash value computed based on file content | | file | uri | Link to pay stub file, format is specified in the content-type | | derived\_fields | array of strings | Array of derived fields | | missing\_data\_fields | array of strings | List of missing data fields from payroll response | #### Annual income summary object Find information for the attributes and values of the annual income summary object. | Attribute | Type | Description | | :--------- | :------ | :---------------------- | | id | string | Unique ID | | year | integer | Income report year | | regular | string | Regular salary | | bonus | string | Bonus | | commission | string | Commission | | overtime | string | Overtime pay | | other\_pay | string | All other payment forms | | net\_pay | string | Net pay | | gross\_pay | string | Gross pay | #### Bank accounts object The table below covers the attributes within the bank accounts object. | Attribute | Type | Description | | :-------------- | :----- | :---------------------------------------------------------------------------------------------------------- | | account\_number | string | Account number | | routing\_number | string | Routing number | | account\_name | string | User friendly account name | | account\_type | string | Account type: `C` - Checking account, `S` - Savings account | | deposit\_type | string | Deposit type: `E` - Entire paycheck, `P` - Percentage of the paycheck, `A` - Fixed amount from the paycheck | | deposit\_value | string | Deposit value | | bank\_name | string | Bank name | #### W2s object The values in this table are for the W-2s object field. | Attribute | Type | Description | | :---------------------- | :------ | :-------------------------------------------------------------- | | file | uri | Link to W2 report file, format is specified in the content-type | | md5sum | string | MD5 hash value computed based on file content | | year | integer | Year | | wages | string | Wages, tips, other compensation (Section 1) | | federal\_tax | string | Federal income tax withheld (Section 2) | | social\_security\_wages | string | Social security wages (Section 3) | | social\_security\_tax | string | Social security tax withheld (Section 4) | | medicare\_wages | string | Medicare wages (Section 5) | | medicare\_tax | string | Medicare tax withheld (Section 6) | | gross\_pay | string | Gross pay | # Endpoints Use the endpoints below to manage user-level reports. * [Create a report](/api-reference/user-income-and-employment-reports/users_reports) * [Retrieve a report](/api-reference/user-income-and-employment-reports/users_get_report) # Example response The sample below is a JSON response for the endpoint. ```json theme={null} { "report_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "created_at": "2022-05-04T11:30:00Z", "completed_at": "2022-05-04T12:00:00Z", "links": [ { "link_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "tracking_info": "string", "provider": "string", "employments": [ { "income": "70000.00", "income_unit": "YEARLY", "pay_rate": "6500.00", "pay_frequency": "M", "statements": [ { "id": "24d7e80942ce4ad58a93f70ce4115f5c", "check_number": "29205182", "pay_date": "2018-05-15", "net_pay": "11500.32", "net_pay_ytd": "31980.64", "gross_pay": "13900.11", "gross_pay_ytd": "49200.00", "bonus": "100.00", "commission": "12000.00", "hours": "40.00", "basis_of_pay": "S", "period_start": "2018-05-01", "period_end": "2018-05-15", "regular": "1695.11", "regular_ytd": "23000.00", "other_pay_ytd": "700.00", "bonus_ytd": "1000.00", "commission_ytd": "24000.00", "overtime": "45.00", "overtime_ytd": "500.00", "other_pay": "60.00", "earnings": [ { "name": "Regular", "amount": "1935.77", "category": "regular", "rate": null, "units": null }, { "name": "Overtime", "amount": "60.58", "category": "overtime", "rate": "30.29", "units": "2" } ], "earnings_ytd": [ { "name": "Regular", "amount": "1935.77", "category": "regular", "rate": null, "units": null }, { "name": "Overtime", "amount": "60.58", "category": "overtime", "rate": "30.29", "units": "2" } ], "deductions": [ { "amount": "127.01", "category": "socialsec", "name": "Social Security Tax" }, { "amount": "46.23", "category": "state", "name": "VA State Income Tax" }, { "amount": "29.7", "category": "medicare", "name": "Medicare Tax" } ], "deductions_ytd": [ { "amount": "127.01", "category": "socialsec", "name": "Social Security Tax" }, { "amount": "46.23", "category": "state", "name": "VA State Income Tax" }, { "amount": "29.7", "category": "medicare", "name": "Medicare Tax" } ], "md5sum": "03639d6a6624f69a54a88ea90bd25e9d", "file": "https://citadelid-resources.s3-us-west-2.amazonaws.com/paystub_sample.pdf", "derived_fields": [ "basis_of_pay" ], "missing_data_fields": [ "earnings_ytd" ] } ], "annual_income_summary": [ { "id": "24d7e80942ce4ad58a93f70ce4115f5c", "year": 2018, "regular": "23000.00", "bonus": "1000.00", "commission": "24000.00", "overtime": "500.00", "other_pay": "700.00", "net_pay": "31980.64", "gross_pay": "49200.00" } ], "bank_accounts": [ { "account_number": "1234567890", "routing_number": "123456789", "account_name": "My Bank", "account_type": "C", "deposit_type": "A", "deposit_value": "200.00", "bank_name": "TD Bank" } ], "w2s": [ { "file": "https://citadelid-resources.s3-us-west-2.amazonaws.com/W2_sample.pdf", "md5sum": "f65e30c39124ad707ac4b3aeaee923a7", "year": 2020, "wages": "900.50", "federal_tax": "75.01", "social_security_wages": "900.50", "social_security_tax": "56.30", "medicare_wages": "900.50", "medicare_tax": "13.15", "gross_pay": "18211.48" } ], "id": "24d7e80942ce4ad58a93f70ce4115f5c", "is_active": false, "job_title": "PR associate", "job_type": "F", "start_date": "2018-01-01", "original_hire_date": "2017-06-21", "end_date": "2023-04-29", "external_last_updated": "2023-04-29", "derived_fields": [ "is_active" ], "missing_data_fields": [ "w2s" ], "manager_name": "Jenny McDouglas", "profile": { "id": "48427a36d43c4d5aa6324bc06c692456", "created_at": "2022-06-07T15:00:00Z", "updated_at": "2022-06-31T15:00:00Z", "first_name": "John", "last_name": "Doe", "full_name": "John Doe", "middle_initials": "K", "email": "john.doe@example.com", "ssn": "123456789", "date_of_birth": "1992-03-03", "home_address": { "street": "1 Morgan Ave", "city": "Los Angeles", "state": "CA", "zip": "90210", "country": "US" } }, "company": { "name": "Facebook Demo", "address": { "street": "1 Morgan Ave", "city": "Los Angeles", "state": "CA", "zip": "90210", "country": "US" }, "phone": "6503087300", "ein": "12-345678" }, "gse_accepted": true } ] } ] } ``` # Retrieve an income and employment report Source: https://truv.com/docs/api-reference/user-income-and-employment-reports/users_get_report GET /v1/users/{user_id}/reports/{report_id}/ The endpoint retrieves a report for a user. # Create an income and employment report Source: https://truv.com/docs/api-reference/user-income-and-employment-reports/users_reports POST /v1/users/{user_id}/reports/ The endpoint creates a report for a user. # The Users object Source: https://truv.com/docs/api-reference/users/object Manage users and user tokens for Truv Bridge with the Users endpoint. User objects represent distinct users that would connect their accounts via Truv Bridge. ### User Attributes | Attribute | Type | Description | | :----------------- | :------- | :----------------------------------- | | id | string | Unique ID of user | | external\_user\_id | string | External user ID | | first\_name | string | First name\* | | last\_name | string | Last name\* | | email | string | User email | | phone | string | User phone number | | ssn | string | User SSN | | created\_at | datetime | Timestamp when user was created | | updated\_at | datetime | Timestamp when user was last updated | Full name is required Users and applicants require both `first_name` and `last_name` values when testing for Integrating Document Processing. ## Endpoints The list below contains available endpoints for user management. * [List all users](/api-reference/users/users_list) * [Create a user](/api-reference/users/users_create) * [Retrieve a user](/api-reference/users/users_read) * [Update a user](/api-reference/users/users_partial_update) * [Delete a user](/api-reference/users/users_delete) *** ## Example response View the example object from the `Create User` endpoint below. ```json theme={null} { "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "external_user_id": "12345", "first_name": "John", "last_name": "Doe", "email": "john.doe@example.com", "phone": "+14155554193", "ssn": "222233333", "created_at": "2022-05-04T11:30:00Z", "updated_at": "2022-05-04T12:00:00Z" } ``` # Create a user Source: https://truv.com/docs/api-reference/users/users_create POST /v1/users/ The endpoint creates a user. # Delete a user Source: https://truv.com/docs/api-reference/users/users_delete DELETE /v1/users/{user_id}/ The endpoint deletes a user. # List all users Source: https://truv.com/docs/api-reference/users/users_list GET /v1/users/ The endpoint returns a list of users. # Update a user Source: https://truv.com/docs/api-reference/users/users_partial_update PATCH /v1/users/{user_id}/ The endpoint updates a user. # Retrieve a user Source: https://truv.com/docs/api-reference/users/users_read GET /v1/users/{user_id}/ This endpoint retrieves a user. # Webhook Events Source: https://truv.com/docs/api-reference/webhook-events Index of webhook event types organized by object This page is the event catalog only. Use [Webhook Security](/api-reference/security) for signature verification, retries, ordering, and IP allowlisting. Use [Webhooks](/api-reference/webhooks/object) for endpoint setup and common payload fields. *** ## Events by object ### Orders | Event | Trigger | | ---------------------- | -------------------------------------------------- | | `order-created` | Order first created, before any status transitions | | `order-status-updated` | Order status changes | | `order-refresh-failed` | Refresh task fails for an order | See [Order Webhook Events](/api-reference/orders/events) for payloads and examples. ### Tasks | Event | Trigger | | ----------------------- | -------------------------------- | | `task-status-updated` | Task status transitions | | `employment-created` | First employment extraction | | `profile-created` | First profile extraction | | `statements-created` | First statement retrieval | | `shifts-created` | First shift extraction | | `bank-accounts-created` | First bank account discovery | | `employment-updated` | Employment changed on refresh | | `profile-updated` | Profile changed on refresh | | `statements-updated` | New statements on refresh | | `shifts-updated` | Shifts changed on refresh | | `bank-accounts-updated` | Bank accounts changed on refresh | See [Task Webhook Events](/api-reference/tasks/events) for payloads and examples. ### Links | Event | Trigger | | ------------------- | ---------------------------- | | `link-connected` | Successful connection | | `link-disconnected` | Refresh connection failure | | `link-deleted` | Data and credentials removed | See [Link Webhook Events](/api-reference/links/events) for payloads and examples. *** ## Timing and ordering Truv processes webhook events in status order. For example, `full_parse` events are always sent before `done` events for the same task. However, webhook deliveries may experience delays due to network latency, outages, or other external factors. Use the `updated_at` field to track event sequence. Do not rely on delivery order alone. Your webhook endpoint must respond with a `2xx` status within **10 seconds**. If your endpoint exceeds this timeout, the delivery is retried. *** Configure endpoints and review common payload fields Signature verification, retries, ordering, and allowlisting # Webhooks Source: https://truv.com/docs/api-reference/webhooks/object Receive real-time notifications when verification events occur Webhooks are HTTP POST requests sent automatically by Truv when events occur during the verification flow. They track Task status changes, Order updates, Link connections, and data object creation, keeping your system in sync as data progresses through processing stages. Configure webhook endpoints separately for Sandbox and Production. *** ## Set up webhooks Configure webhook endpoints in the [Truv Dashboard](https://dashboard.truv.com): 1. Navigate to **Development** → **Webhooks** 2. Enter your endpoint URL 3. Save the configuration Your endpoint will begin receiving webhook events for all activity in that environment. ### Test webhooks * Use **Truv Bridge** in the Dashboard Emulator to trigger webhook events in sandbox * Use tools like [ngrok](https://ngrok.com/) to expose a local development server: ```bash theme={null} ngrok http 3000 ``` Then configure the ngrok URL as your webhook endpoint in the Dashboard. *** ## Webhook payload structure All webhook requests include these standard fields: ### Headers | Header | Value | | ---------------- | -------------------------------------- | | `User-Agent` | `Truv-Webhook-Service/2.0` | | `X-WEBHOOK-SIGN` | HMAC-SHA256 signature for verification | HTTP header names are case-insensitive per RFC 7230. ### Body Fields Every webhook payload includes these common fields: | Field | Description | | ------------------ | ------------------------------------------------------------------------------ | | `webhook_id` | Unique identifier for this webhook request | | `event_type` | The event classification (see [Events Reference](/api-reference/tasks/events)) | | `event_created_at` | Timestamp when the event occurred | | `updated_at` | Timestamp for sequencing events | | `user_id` | Associated Truv user identifier | | `template_id` | Associated template, if applicable (nullable) | Additional fields vary by event type. See the event reference pages for [Orders](/api-reference/orders/events), [Tasks](/api-reference/tasks/events), and [Account Links](/api-reference/links/events). ### Example Payload ```json theme={null} { "webhook_id": "488f424096d3461aa0e4cf11a985f6df", "task_id": "521442a087604e599c637db310d07402", "link_id": "d39d86dcc20c46e0ae75ba9ab1311a21", "product": "income", "data_source": "payroll", "tracking_info": null, "event_type": "task-status-updated", "event_created_at": "2022-08-24T13:55:12.845645Z", "updated_at": "2022-08-24T13:55:12.845666+00:00", "status": "parse", "user_id": "88fef4cea64c40b5ad6727cc9b0b9fdc", "template_id": null } ``` *** ## Event types Truv sends webhooks for these categories of events. See the dedicated event reference pages for full payloads and field descriptions. `order-status-updated`, `order-refresh-failed` `task-status-updated` and all data object events (`employment-created`, `statements-created`, etc.) `link-connected`, `link-disconnected`, `link-deleted` *** ## Security Every webhook includes an `X-WEBHOOK-SIGN` header with an HMAC-SHA256 signature. Verify it against the raw request body using your Access Secret before processing the event. Always verify signatures using the **raw request body**, not parsed JSON. Parsing and re-serializing may change the byte representation. See [Webhook Security](/api-reference/security) for verification code examples in Python, Node.js, Go, Ruby, and C#, along with IP allowlisting and delivery behavior details. *** ## Timeouts and retries | Behavior | Detail | | ------------- | --------------------------------------------------------------------------------------- | | **Timeout** | Your endpoint must respond with a `2xx` status within **10 seconds** | | **Redirects** | `3xx` responses are followed | | **Retries** | `4xx` and `5xx` responses trigger up to **3 retry attempts** at **30-second intervals** | | **Blocking** | After 3 consecutive failures, webhook delivery to your endpoint is blocked | *** ## Event ordering Webhooks are delivered in event order. For example, `full_parse` fires before `done`. However, network conditions can cause delays in delivery. Use the `updated_at` field to sequence events correctly in your system, rather than relying on delivery order. *** ## Handle webhooks ### Best Practices Return a `200` response quickly. Process the webhook data asynchronously if needed: ```javascript theme={null} app.post("/webhooks/truv", (req, res) => { // Acknowledge immediately res.status(200).send("OK"); // Process asynchronously queue.add("process-webhook", req.body); }); ``` Webhooks may be delivered more than once. Use the `webhook_id` field for idempotency: ```javascript theme={null} async function handleWebhook(payload) { const exists = await db.webhooks.findOne({ webhookId: payload.webhook_id }); if (exists) return; // Already processed await processEvent(payload); await db.webhooks.insert({ webhookId: payload.webhook_id }); } ``` Never process a webhook without verifying the `X-WEBHOOK-SIGN` header. See [Security](#security) above. The `task-status-updated` event is the primary signal for monitoring connection progress. Key statuses to handle: * **`done`**: All data has been downloaded and processed. Fetch verification reports. * **`login_error`**: Authentication failed. The user may need to retry. * **`mfa_error`**: MFA verification failed. * **`config_error`**: Provider configuration issue. See [Connection Lifecycle](/api-reference/tasks/lifecycle) for the full status flow. *** ## Troubleshooting | Issue | Solution | | ------------------------------ | ---------------------------------------------------------------------------------------------- | | Not receiving webhooks | Verify your URL is configured under **Development** → **Webhooks** for the correct environment | | Signature verification failing | Ensure you're using your **Access Secret** (not Client ID) and hashing the raw body | | Timeouts | Respond with `200` immediately, process asynchronously | | Blocked endpoint | Check for 3+ consecutive failures. Fix the issue and reconfigure the endpoint | *** ## Endpoints Use the endpoints below to manage webhooks programmatically. * [Create a webhook](/api-reference/webhooks/webhooks_create) * [List webhooks](/api-reference/webhooks/webhooks_list) * [Retrieve a webhook](/api-reference/webhooks/webhooks_read) * [Update a webhook](/api-reference/webhooks/webhooks_partial_update) * [Delete a webhook](/api-reference/webhooks/webhooks_delete) *** ## Next steps Understand task status flow and error states # List webhook request history Source: https://truv.com/docs/api-reference/webhooks/webhook_requests_list GET /v1/webhook-requests/ Returns a paginated list of webhook requests filtered by the provided criteria. Only webhook requests from the last 30 days are available. # Create a webhook Source: https://truv.com/docs/api-reference/webhooks/webhooks_create POST /v1/webhooks/ The endpoint creates a webhook. # Delete a webhook Source: https://truv.com/docs/api-reference/webhooks/webhooks_delete DELETE /v1/webhooks/{webhook_id}/ The endpoint deletes a webhook. # List all webhooks Source: https://truv.com/docs/api-reference/webhooks/webhooks_list GET /v1/webhooks/ The endpoint returns a list of webhooks. # Update a webhook Source: https://truv.com/docs/api-reference/webhooks/webhooks_partial_update PATCH /v1/webhooks/{webhook_id}/ The endpoint updates a webhook. # Retrieve a webhook Source: https://truv.com/docs/api-reference/webhooks/webhooks_read GET /v1/webhooks/{webhook_id}/ This endpoint retrieves a webhook. # Direct Deposit Switch Source: https://truv.com/docs/banking/integration/dds Switch customer direct deposits to your bank using the Deposit Switch demo Switch a new customer's paycheck deposit to your bank by embedding Truv Bridge in your application. The customer connects their payroll provider, selects an allocation, and Truv handles the deposit switch automatically. **Integration pattern:** [Bridge Widget](/developers/integration/bridge-widget/overview) (User + Bridge Token flow) | **Products:** DDS | **Demo:** [Deposit Switch](https://github.com/truvhq/demo-apps) *** ## Get started Clone and run the [Deposit Switch demo](https://github.com/truvhq/demo-apps) to see the full direct deposit switch flow working locally. ```bash theme={null} git clone https://github.com/truvhq/demo-apps.git cd demo-apps npm install && npm start ``` Open `http://localhost:5173`, select **Retail Banking > Deposit Switch**, and walk through a switch using sandbox credentials (`goodlogin` / `goodpassword`). See [full setup instructions](/developers/quickstarts-overview#demo-apps) for ngrok and environment configuration. The demo follows this sequence: 1. **Create a user** — Your server calls [POST /v1/users/](/api-reference/users/users_create) to create a Truv user. 2. **Create a bridge token** — Your server calls [POST /v1/users//tokens/](/api-reference/bridge-token/users_tokens) with `product_type: "deposit_switch"` and an `account` object containing your bank's account details and allocation preferences. 3. **Initialize Bridge** — Your frontend opens [Truv Bridge](/developers/sdks/javascript) with the `bridge_token`. The customer connects their payroll provider and confirms the deposit switch. 4. **Receive webhooks** — Truv sends a `task-status-updated` [webhook](/api-reference/webhook-events) with status `done` when the switch completes. Verify the signature using the `X-Webhook-Sign` header with HMAC-SHA256. 5. **Retrieve the report** — Fetch the deposit switch confirmation with [GET /v1/users//deposit\_switch/report/](/api-reference/dds-reports/dds-report-retrieve). Each step maps to a specific file in the demo. Use these as reference when building your integration. | Step | Demo file | API reference | | --------------------- | -------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- | | User creation | [`server/routes/bridge.js`](https://github.com/truvhq/demo-apps/blob/main/server/routes/bridge.js) | [POST /v1/users/](/api-reference/users/users_create) | | Bridge token creation | [`server/routes/bridge.js`](https://github.com/truvhq/demo-apps/blob/main/server/routes/bridge.js) | [POST /v1/users//tokens/](/api-reference/bridge-token/users_tokens) | | Bridge initialization | [`src/demos/DepositSwitch.jsx`](https://github.com/truvhq/demo-apps/blob/main/src/demos/DepositSwitch.jsx) | [Bridge SDK](/developers/sdks/javascript) | | Webhook handling | [`server/webhooks.js`](https://github.com/truvhq/demo-apps/blob/main/server/webhooks.js) | [Webhook events](/api-reference/webhook-events) | | Report retrieval | [`server/routes/user-reports.js`](https://github.com/truvhq/demo-apps/blob/main/server/routes/user-reports.js) | [DDS report](/api-reference/dds-reports/dds-report-retrieve) | *** ## Configure account details Pass your bank's account details in the `account` object when creating the bridge token. These fields tell Truv where to route the customer's paycheck. | Field | Required | Description | | ---------------- | -------- | ---------------------------------------------------------------------------- | | `account_number` | Yes | Your bank account number (4-20 digits) | | `routing_number` | Yes | Your bank routing number (8-12 digits) | | `bank_name` | Yes | Your bank's display name | | `account_type` | Yes | `checking` or `savings` | | `deposit_type` | No | Allocation type: `entire`, `amount`, or `percent` | | `deposit_value` | No | Amount or percentage (required when `deposit_type` is `amount` or `percent`) | *** ## Set allocation type Control how much of the customer's paycheck routes to your bank. Choose one of three allocation types. | Allocation | `deposit_type` | `deposit_value` | Behavior | | ------------- | -------------- | ------------------------------- | ----------------------------------- | | Full paycheck | `entire` | Not required | Routes the entire paycheck | | Fixed amount | `amount` | Dollar amount (e.g. `"500.00"`) | Routes a specific dollar amount | | Percentage | `percent` | Percentage (e.g. `"50"`) | Routes a percentage of the paycheck | ### Full paycheck ```json theme={null} { "account_number": "16002600", "routing_number": "123456789", "bank_name": "Your Bank", "account_type": "checking", "deposit_type": "entire" } ``` ### Fixed amount ```json theme={null} { "account_number": "16002600", "routing_number": "123456789", "bank_name": "Your Bank", "account_type": "checking", "deposit_type": "amount", "deposit_value": "500.00" } ``` ### Percentage ```json theme={null} { "account_number": "16002600", "routing_number": "123456789", "bank_name": "Your Bank", "account_type": "checking", "deposit_type": "percent", "deposit_value": "50" } ``` *** ## Next steps Full implementation guide for the User + Bridge Token flow Test deposit switching in sandbox Handle task-status-updated and other webhook events Retrieve deposit switch confirmation reports # Retail Banking Source: https://truv.com/docs/banking/overview Direct deposit switching and paycheck-linked lending for banks and fintech Truv helps banks and fintech companies acquire customers through direct deposit switching and enable paycheck-linked lending for loan repayment. Automatically switch customer direct deposit to your bank Automatic loan repayment from paycheck Connect to most US payroll providers Changes take effect on next pay cycle *** ## Quick start Run the demo app to see deposit switching end-to-end, then follow the integration guide to build it into your app. [Clone the demo app →](https://github.com/truvhq/demo-apps) *** ## What you can do **Use cases:** * New account funding * Customer acquisition * Payroll deposit capture **How it works:** 1. Customer connects their payroll account 2. Truv updates direct deposit settings 3. Next paycheck deposits to your bank **Use cases:** * Consumer loan repayment * Earned wage access repayment * Subscription collection **How it works:** 1. Customer authorizes payroll deduction 2. Set repayment amount (fixed or percentage) 3. Payment automatically deducted each pay period *** ## Integration: User Token Flow Direct deposit switch via Truv Bridge **Deposit Switch and Paycheck Linked Lending use the [Bridge Widget](/developers/integration/bridge-widget/overview) flow** (User + Bridge Token). Other verification use cases use [Embedded Orders](/developers/integration/embedded-orders/overview). *** ## How it works ### Deposit Switch Flow ```mermaid theme={null} sequenceDiagram participant Customer participant Your App participant Truv participant Payroll Customer->>Your App: Open new account Your App->>Truv: Create bridge token Truv-->>Your App: bridge_token Your App->>Customer: Show Truv Bridge Customer->>Truv: Connect payroll Truv->>Payroll: Update direct deposit Payroll-->>Truv: Confirmed Truv-->>Your App: Webhook: task-status-updated (done) Note over Payroll: Next paycheck deposits to your bank ``` ### Paycheck Linked Lending Flow ```mermaid theme={null} sequenceDiagram participant Borrower participant Your App participant Truv participant Payroll Borrower->>Your App: Accept loan terms Your App->>Truv: Create bridge token Truv-->>Your App: bridge_token Borrower->>Truv: Connect payroll Your App->>Truv: Configure PLL deduction Truv->>Payroll: Set up deduction Note over Payroll: Each pay period Payroll->>Your App: Deduction sent ``` *** ## Implementation timeline | Integration Method | Timeline | Code Required | | --------------------------- | --------- | ------------- | | **Deposit Switch** | 2-4 weeks | Moderate | | **Paycheck Linked Lending** | 2-4 weeks | Moderate | *** ## Get started * Acquiring deposits? --> [Deposit Switch](/banking/products/dds) * Loan repayment? --> [Paycheck Linked Lending](/credit/products/pll) Switch customer deposits to your bank Set up paycheck-linked loan repayment Test with sandbox credentials before going live *** ## Next steps Implement deposit switching Complete API documentation Talk to our banking solutions team [support@truv.com](mailto:support@truv.com) # Transactions Source: https://truv.com/docs/banking/products/bank-aggregation Bank account and transaction data for fintech applications Bank Aggregation provides access to bank account balances and transaction data for fintech applications. Use it for account funding verification, balance checks, and cash flow analysis alongside Deposit Switch or Paycheck Linked Lending. *** ## Benefits Confirm account ownership and balances instantly Up to 2 years of categorized transactions Identify recurring payroll deposits automatically 30/60/90-day average balance calculations *** ## What you get | Data Point | Description | | ----------------------- | ------------------------------------------------------- | | **Account balances** | Current and available balances for checking and savings | | **Transaction history** | Individual transactions over the lookback period | | **Account ownership** | Verified account holder information | | **Cash flow analysis** | Deposit and withdrawal patterns | | **Account metadata** | Account type, institution name, routing number | *** ## Use cases Confirm that a new customer's bank account is real and funded before enabling Deposit Switch. Verify sufficient funds before initiating transfers or setting up Paycheck Linked Lending deductions. Analyze deposit and withdrawal patterns to assess customer financial health. Identify recurring payroll deposits as a complementary income signal. *** ## How to implement Bank Aggregation uses the **Embedded Orders** flow, unlike Deposit Switch and Paycheck Linked Lending which use the User Token flow. See [Embedded Orders](/developers/integration/embedded-orders/overview) for details. ```bash theme={null} curl --request POST \ --url https://prod.truv.com/v1/orders/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' \ --header 'Content-Type: application/json' \ --data '{ "products": ["transactions"], "first_name": "John", "last_name": "Doe", "external_user_id": "user-123" }' ``` *** ## Data coverage ### Financial Institutions Truv connects to major banks and credit unions: | Institution Type | Examples | | ---------------- | ----------------------------------------- | | National banks | Chase, Bank of America, Wells Fargo, Citi | | Regional banks | PNC, US Bank, TD Bank | | Credit unions | Navy Federal, State Employees CU | | Online banks | Ally, Marcus, Discover | | Neobanks | Chime, Current, Varo | *** ## API reference Create tokens for Truv Bridge Financial account details Account balance data Create and manage users *** ## Best practices Request enough transaction history to identify recurring patterns. 60 days of data is the default and typically sufficient for cash flow analysis and recurring deposit identification. Verify account funding before enabling Deposit Switch to ensure the customer's account is active and in good standing. Focus on recurring deposits to estimate stable income from bank transaction data. *** ## Next steps Integration guide for Bank Aggregation Direct Deposit Switch integration guide # Deposit Switch Source: https://truv.com/docs/banking/products/dds Automatically switch customer direct deposit to your bank Deposit Switch (DDS) enables you to redirect customer paychecks to your bank account by updating their payroll direct deposit settings. The process is fully digital -- customers connect their payroll account, and Truv handles the rest. **Try the demo** — Run the [Direct Deposit Switch demo](/banking/integration/dds) to see deposit switching working end-to-end. [Clone the demo app →](https://github.com/truvhq/demo-apps) *** ## How it works The customer authenticates with their employer's payroll system through Truv Bridge. You specify how much of the paycheck to redirect: full, partial percentage, or a fixed dollar amount. Truv automatically updates the direct deposit settings with the customer's payroll provider. Starting with the next pay cycle, the customer's paycheck deposits to your bank. *** ## Benefits Paychecks arrive automatically with no manual transfers Strong incentive for customers to switch primary banking Works with most US payroll providers No documents or manual forms needed *** ## Allocation types | Type | Description | Example | | --------- | ---------------------- | ------------------ | | `entire` | Full paycheck | 100% of paycheck | | `percent` | Percentage of paycheck | 50% of paycheck | | `amount` | Fixed dollar amount | \$500 per paycheck | Deposit Switch uses the **User Token flow** instead of Embedded Orders. This gives you direct control over the payroll connection and deposit allocation configuration. *** ## Data coverage ### Payroll Providers Truv connects to payroll providers covering 85%+ of US employees: | Provider | Coverage | | ------------- | ------------------- | | ADP | \~20% of US workers | | Paychex | \~10% of US workers | | Workday | Large enterprises | | UKG (Kronos) | Healthcare, retail | | Paylocity | Mid-market | | Gusto | Small business | | And 100+ more | | *** ## API reference Create tokens for Truv Bridge Deposit switch report DDS link detail report Create and manage users *** ## Best practices Starting with a partial deposit (e.g., 50%) reduces friction and increases conversion. Encourage full switching later once the customer is comfortable. After a successful webhook, inform the customer that their direct deposit has been updated and when they can expect the first deposit. Watch for `task-status-updated` webhooks to detect if the payroll provider rejects the change or the customer reverses it. *** ## Next steps Demo-first guide to implementing deposit switching Understand the User + Bridge Token integration flow # Document Processing Source: https://truv.com/docs/banking/products/document-processing AI-powered document upload and verification for banking and fintech Truv Document Processing lets you accept documents directly from users when a live payroll connection isn't possible. Truv's AI automatically splits, classifies, and extracts data from uploaded files, delivering the same structured output as a direct payroll connection. For banking and fintech, document upload supports account opening workflows, income verification for credit decisions, and identity verification when direct connections aren't available. *** ## Benefits Extract income, employment, and tax data from documents Paystubs, W-2s, 1099s, bank statements, and more Automatic document type and readability checks Seamless fallback when payroll connection unavailable *** ## Banking use cases Verify income and employment as part of new account onboarding Accept pay stubs and tax returns when payroll connection isn't available for income-based lending Extract and validate identity documents (driver's license, passport) alongside income documents When a user can't connect via payroll for deposit switching, verify employment through documents *** ## Supported document types ### Income & employment documents | Document | Type Code | | ---------------- | --------- | | Pay stubs | `PAYSTUB` | | W-2s | `W2` | | 1099s | `F1099` | | 1040 tax returns | `F1040` | ### Additional document types | Document | Type Code | | ----------------- | ---------------- | | Bank statements | `BANK_STATEMENT` | | Driver's licenses | `DRIVER_LICENSE` | | Passports | `PASSPORT` | | Green cards | `GREEN_CARD` | | Utility bills | `UTILITY_BILL` | *** ## How it works 1. **Create a document collection**: Initialize a container for the user's documents. Upload one or more files (Base64-encoded PDFs or images) in the same request, or add files incrementally. 2. **Truv validates and classifies**: Truv validates each file and classifies document types using AI. Fraud detection checks every document against 50M+ verified pay stubs. 3. **Finalize the collection**: Trigger processing for the full collection or selectively finalize specific documents. Truv generates Links with structured income and employment data. 4. **Retrieve verified data**: When the processing Task completes (`task-status-updated` webhook with `status: done`), fetch the report. Same format as a live payroll connection. *** ## API reference Upload and process documents via the Collections API Manage document collections Retrieve parsed data *** ## Next steps Platform-level document processing guide Full API reference for document collections # Smart Login Source: https://truv.com/docs/banking/smart-login Truv Smart Login presents the best authentication method for each user to maximize deposit switch and PLL conversion Truv's Smart Login has business logic in place to present the best authentication method with the highest likelihood of success based on: * Employer selected * Historical successes * Payroll system compatibility *** ## Authentication methods In-bridge redirect to payroll provider. A Truv patented solution available across some of the largest provider integrations to increase coverage and leverage password managers. Leverage employee credentials to access payroll systems. Truv has integrations to 64 SSO systems, enabling customers to log in the same way they do at work. Leverage trusted phone or email for one-time passcode. Currently supported by ADP and Paycom. For employers behind VPNs: iOS uses Apple's AppClip, Android uses Instant App. QR codes available for desktop users. Truv maps over 300,000 employers to payroll providers so customers don't need to make that selection. For unmapped employers, Truv recommends providers based on historical data and employer size distribution. *** ## Fallback options When primary authentication paths are unavailable, Truv provides fallback options for Deposit Switch and Paycheck Linked Lending flows: Customers can generate a prefilled, e-signed PDF with account number, routing number, and allocation information to download and send to HR. Truv displays the customer's account number, routing number, and bank details so they can manually enter the information in their payroll system. *** ## Why this matters for banking Smart Login is particularly important for Deposit Switch and Paycheck Linked Lending because: * **Higher conversion**: Presenting the right login method first reduces drop-off during the payroll authentication step * **Broader coverage**: Multiple authentication paths mean more employers are supported, expanding your eligible customer base * **Fallback safety net**: Even if a direct connection fails, eSigned PDF and manual entry options ensure the member can still complete the flow * **Reduced support burden**: Fewer authentication failures mean fewer support tickets and better member experience *** ## Next steps Implement Direct Deposit Switch Implement Paycheck Linked Lending # Document Processing Source: https://truv.com/docs/credit/data-sources/document-processing Collect and process documents for income and employment verification Collect user documents, extract structured data, and analyze them for fraud with Truv's document processing. Common use cases include: * **Fallback** for unsuccessful payroll connection attempts * **Standalone solution** to collect and parse documents into structured data **Try the demo** -- The [Smart Routing demo](/credit/integration/smart-routing) includes document upload as a fallback verification method. [Clone the demo app ->](https://github.com/truvhq/demo-apps) *** ## Supported document types * Paystubs * W-2s * 1099 tax forms (1099-DIV, 1099-G, 1099-INT, 1099-MISC, 1099-NEC, 1099-R, any year after 2021) *** ## Configure bridge token When creating a [Truv Bridge](/developers/sdks/javascript) [Token](/api-reference/bridge-token/users_tokens), include `product_type = income` and `data_sources = ["docs"]`: ```bash theme={null} curl -X POST https://prod.truv.com/v1/users/{user_id}/tokens/ \ -H "X-Access-Client-Id: YOUR_TRUV_CLIENT_ID" \ -H "X-Access-Secret: YOUR_TRUV_CLIENT_SECRET" \ -H "Content-Type: application/json" \ -d '{ "product_type": "income", "data_sources": ["docs"], "tracking_info": "any data for tracking" }' ``` *** ## Testing ### Successful Documents Upload these PDFs for successful sandbox responses: * [Most recent paystub](https://citadelid-resources.s3.us-west-2.amazonaws.com/doc_upload/most.recent.paystub.pdf) * [Next recent paystub](https://citadelid-resources.s3.us-west-2.amazonaws.com/doc_upload/next.recent.paystub.pdf) * [First paystub](https://citadelid-resources.s3.us-west-2.amazonaws.com/doc_upload/first.paystub.pdf) * [W2](https://citadelid-resources.s3.us-west-2.amazonaws.com/doc_upload/w2.pdf) ### 1099 Tax Forms * [1099-DIV](https://citadelid-resources.s3.us-west-2.amazonaws.com/doc_upload/1099div.pdf), [1099-G](https://citadelid-resources.s3.us-west-2.amazonaws.com/doc_upload/1099g.pdf), [1099-INT](https://citadelid-resources.s3.us-west-2.amazonaws.com/doc_upload/1099int.pdf), [1099-MISC](https://citadelid-resources.s3.us-west-2.amazonaws.com/doc_upload/1099misc.pdf), [1099-NEC](https://citadelid-resources.s3.us-west-2.amazonaws.com/doc_upload/1099nec.pdf), [1099-R](https://citadelid-resources.s3.us-west-2.amazonaws.com/doc_upload/1099r.pdf), [SSA-1099](https://citadelid-resources.s3.us-west-2.amazonaws.com/doc_upload/ssa1099.pdf) Test scenarios use the file name to return results. Testing ignores file contents in sandbox. *** ## Suspicious document detection ### Suspicious Flag (`is_suspicious`) When processing documents, Truv may flag them as suspicious while still completing the task. The `is_suspicious` flag indicates potential document manipulation that warrants additional review. #### When Documents Are Flagged Documents are flagged when PDF metadata indicates potential manipulation, including software like FoxitPDF, Adobe Scan, CamScanner, and other document editing applications. * **Too Early:** Pay date before the pay period start date * **Too Late:** Pay date 30+ days after the pay period end date Documents created through browser "Print to Save as PDF" on non-PDF files are flagged because the original content may have been modified before conversion. #### When Documents Are Failed In cases of high-confidence fraud, the task fails entirely: * **Known fraud templates**: Document matches a known fraudulent template * **Obvious manipulation tools**: PDF metadata indicates use of tools like iLovePDF, Canva, etc. Documents flagged as `is_suspicious = true` are still processed and results are returned. Failed documents do not return results and require resubmission. *** ## API reference Upload and process documents via the Collections API Manage document collections Retrieve parsed data Create tokens for Truv Bridge *** ## Next steps Tax return verification Full Document Processing API walkthrough # Tax Returns Source: https://truv.com/docs/credit/data-sources/tax-returns Verify income through tax preparation software connections Verify income instantly through tax preparation software connections. Skip the wait for IRS tax returns and 4506-C documents while improving conversion rates. Truv supports connections to major tax preparation software providers through [Truv Bridge](/developers/sdks/javascript), including F1040 document support. *** ## Configure bridge token When creating a [Bridge Token](/api-reference/bridge-token/users_tokens), include `product_type = income` and `data_sources = ["tax"]`: ```bash theme={null} curl -X POST https://prod.truv.com/v1/users/{user_id}/tokens/ \ -H "X-Access-Client-Id: YOUR_TRUV_CLIENT_ID" \ -H "X-Access-Secret: YOUR_TRUV_CLIENT_SECRET" \ -H "Content-Type: application/json" \ -d '{ "product_type": "income", "data_sources": ["tax"], "tracking_info": "any data for tracking" }' ``` *** ## Example response The JSON data below is a sample payload from the tax documents endpoint: ```json theme={null} [ { "id": "24d7e80942ce4ad58a93f70ce4115f5c", "document_type": "F1040", "document_subtype": "", "file": "https://example.com/tax_sample.pdf", "md5sum": "24d7e80942ce4ad58a93f70ce4115f5c", "year": 2019 } ] ``` *** ## Testing Use the credentials below for sandbox testing: | Username | Password | SSN | Scenario | | --------------- | -------------- | ------------- | ----------------------------------- | | `goodlogin.tax` | `goodpassword` | `991-91-9991` | Successful login with complete data | ### Error Scenarios | Username | Password | Scenario | | ------------ | ---------------- | --------------------------------- | | `error.user` | `login_error` | Incorrect login and password | | `error.user` | `mfa_error` | Multi-factor authentication issue | | `error.user` | `account_locked` | Locked account | | `error.user` | `no_data` | No data found | | `error.user` | `unavailable` | Provider maintenance | | `error.user` | `error` | Generic login error | *** ## API reference Tax document schema and endpoints Create tokens for Truv Bridge Create and manage users *** ## Next steps Upload and process documents # Bank Income Source: https://truv.com/docs/credit/integration/bank-income Verify applicant income from bank transactions using income insights Verify income by connecting to the applicant's bank account and analyzing transaction history. Truv generates an [income insights report](/api-reference/income-insights/income-insights-report-create) from deposit patterns, giving you income data even when payroll connections are unavailable. **Integration pattern:** [Bridge Widget](/developers/integration/bridge-widget/overview) | **Products:** Income Insights | **Demo:** [BankIncome](https://github.com/truvhq/demo-apps) *** ## Get started Clone and run the [BankIncome demo](https://github.com/truvhq/demo-apps) to see the full bank income verification flow working locally. ```bash theme={null} git clone https://github.com/truvhq/demo-apps.git cd demo-apps npm install && npm start ``` Open `http://localhost:5173`, select **Consumer Credit > Bank Income**, and walk through a verification using sandbox credentials (`goodlogin` / `goodpassword`). See [full setup instructions](/developers/quickstarts-overview#demo-apps) for ngrok and environment configuration. The demo follows this sequence: 1. **Search for financial institution** -- Your server calls [GET /v1/providers/](/api-reference/data-providers/providers-list) with `data_source=financial_accounts` to find the applicant's bank. The response returns a `provider_id`. 2. **Create a user** -- Your server calls [POST /v1/users/](/api-reference/users/users_create) to create a Truv user. 3. **Create a bridge token** -- Your server calls [POST /v1/users//tokens/](/api-reference/bridge-token/users_tokens) with `product_type: "income"`, `data_sources: ["financial_accounts"]`, and optionally `provider_id` to [deeplink](/developers/integration/bridge-widget/deeplinking) Bridge to the bank. 4. **Initialize Bridge** -- Your frontend opens [Truv Bridge](/developers/sdks/javascript) with the `bridge_token`. The applicant connects their bank account. 5. **Receive webhooks** -- Truv sends a `task-status-updated` [webhook](/api-reference/webhook-events) when verification completes. Verify the signature using the `X-Webhook-Sign` header with HMAC-SHA256. 6. **Retrieve the income insights report** -- Fetch the report with [POST /v1/users//income\_insights/reports/](/api-reference/income-insights/income-insights-report-create). The report contains income derived from bank transaction analysis. Each step maps to a specific file in the demo. Use these as reference when building your integration. | Step | Demo file | API reference | | --------------------- | -------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | | Institution search | [`src/components/CompanySearch.jsx`](https://github.com/truvhq/demo-apps/blob/main/src/components/CompanySearch.jsx) | [Providers List](/api-reference/data-providers/providers-list) | | User creation | [`server/routes/bridge.js`](https://github.com/truvhq/demo-apps/blob/main/server/routes/bridge.js) | [POST /v1/users/](/api-reference/users/users_create) | | Bridge token | [`server/routes/bridge.js`](https://github.com/truvhq/demo-apps/blob/main/server/routes/bridge.js) | [POST /v1/users//tokens/](/api-reference/bridge-token/users_tokens) | | Bridge initialization | [`src/demos/BankIncome.jsx`](https://github.com/truvhq/demo-apps/blob/main/src/demos/BankIncome.jsx) | [Bridge SDK](/developers/sdks/javascript) | | Webhook verification | [`server/webhooks.js`](https://github.com/truvhq/demo-apps/blob/main/server/webhooks.js) | [Webhook events](/api-reference/webhook-events) | | Report retrieval | [`server/routes/user-reports.js`](https://github.com/truvhq/demo-apps/blob/main/server/routes/user-reports.js) | [Income Insights Report](/api-reference/income-insights/income-insights-report-create) | *** ## Consumer Credit-specific configuration ### Bridge token for bank income Set `data_sources` to `["financial_accounts"]` to restrict Bridge to bank connections only: ```json theme={null} { "product_type": "income", "data_sources": ["financial_accounts"], "provider_id": "PROVIDER_ID" } ``` Pass `provider_id` from the [providers search](/api-reference/data-providers/providers-list) to deeplink Bridge directly to the bank. Without it, Bridge shows its own institution search. Bank income uses `provider_id` (not `company_mapping_id`). The `company_mapping_id` field is for payroll employers. Passing the wrong identifier type causes Bridge to show a generic search screen. ### Income insights report Bank income verification returns an [income insights report](/api-reference/income-insights/income-insights-report-create) instead of a standard VOIE report. Income insights are derived from transaction patterns rather than payroll data. The report includes: * Estimated annual income * Income streams and frequency * Transaction-level detail *** ## How bank income differs from payroll VOIE Bank income analyzes deposit transactions in the applicant's bank account to derive income. It does **not** connect to payroll systems. This means the data shape and coverage differ significantly from a standard [payroll income](/credit/integration/payroll-income) verification. ### Data comparison | Data point | Payroll VOIE | Bank income | | ---------------------- | ------------------------------------- | ------------------------------------------------------ | | Income amount | Exact gross/net from paystubs | Estimated from deposit patterns | | Employer name | From payroll provider | Not available (inferred from transaction descriptions) | | Pay frequency | Exact (`BW`, `SM`, `M`, etc.) | Estimated from deposit cadence | | Deductions breakdown | Federal/state taxes, benefits, 401k | Not available | | W-2 forms | Available when employer provides them | Not available (`w2s` is always null) | | Employment dates | From payroll records | Not available | | Bank account details | Not included under employments | Included in the income insights report | | Self-employment income | Not captured | Captured from deposit patterns | | Gig / on-demand income | Not captured | Captured from deposit patterns | | Government benefits | Requires SSA connection | Detected from deposit patterns | ### Report structure notes * The `bank_income_summary` arrays are structured to support multiple currencies, but in practice contain only USD entries. * Fields standard to payroll VOIE that are always null in bank income responses: `w2s`, `bank_accounts` under employments, and standard payroll deduction line items. * Income amounts are derived estimates, not exact figures from pay stubs. ### When to use bank income vs payroll | Scenario | Recommended approach | | ----------------------------------------- | ------------------------------------------------------------------------------ | | W-2 employee at a large employer | Payroll VOIE -- higher data quality and exact figures | | Self-employed or freelance | Bank income -- payroll VOIE has no coverage | | Gig worker (Uber, DoorDash, etc.) | Bank income -- deposits appear in bank transactions | | Government benefit recipient | Bank income or direct SSA connection | | Multiple income streams | Both -- payroll VOIE for the primary job, bank income for supplemental sources | | Employer not covered by payroll providers | Bank income as fallback | For the most complete income picture, include both `income` and `assets` products in your [order](/api-reference/orders/orders_create). The `income` product captures payroll-connected employment, while `assets` with `data_sources: ["financial_accounts"]` enables bank income analysis. The applicant connects both in a single Bridge session. *** ## Next steps Automatically recommend the best method based on employer coverage Verify income directly from payroll for higher data quality Full implementation guide for user creation, bridge tokens, and Bridge initialization Full API reference for income insights reports # Integration for Consumer Credit Source: https://truv.com/docs/credit/integration/implementation Choose the right verification method for your lending workflow Verify applicant income, employment, and assets by embedding [Truv Bridge](/developers/sdks/javascript) in your lending application. Choose the verification method that fits your use case. All Consumer Credit integrations use the [Bridge Widget](/developers/integration/bridge-widget/overview) flow. Create a [user](/api-reference/users/users_create) and [bridge token](/api-reference/bridge-token/users_tokens), then open Bridge for the applicant to connect. *** ## Choose your verification method | Method | What it does | Data source | Best for | Demo | | ---------------------------------------------------- | --------------------------------------------------- | ---------------------- | -------------------------------------- | ---------------------------------------------------------- | | [Smart Routing](/credit/integration/smart-routing) | Check employer coverage, recommend the fastest path | Payroll, bank, or docs | Most lending workflows | [SmartRouting](https://github.com/truvhq/demo-apps) | | [Bank Income](/credit/integration/bank-income) | Verify income from bank transactions | Financial accounts | Thin-file borrowers, gig workers | [BankIncome](https://github.com/truvhq/demo-apps) | | [Payroll Income](/credit/integration/payroll-income) | Verify income directly from payroll | Payroll | Employed borrowers with payroll access | [PayrollIncome](https://github.com/truvhq/demo-apps) | | [Paycheck-Linked Loans](/credit/integration/pll) | Set up automatic loan repayment from paycheck | Payroll | Post-approval repayment | [PaycheckLinkedLoans](https://github.com/truvhq/demo-apps) | *** ## API flow All Consumer Credit integrations follow the same User + Bridge Token flow: 1. **Create a user** -- Your server calls [POST /v1/users/](/api-reference/users/users_create). 2. **Create a bridge token** -- Your server calls [POST /v1/users//tokens/](/api-reference/bridge-token/users_tokens) with the `product_type` and `data_sources` for the chosen method. 3. **Open Bridge** -- Your frontend initializes [Truv Bridge](/developers/sdks/javascript) with the `bridge_token`. The applicant connects their provider. 4. **Receive webhooks** -- Truv sends a `task-status-updated` [webhook](/api-reference/webhook-events) when verification completes. 5. **Fetch the report** -- Your server retrieves the [VOIE report](/api-reference/user-income-and-employment-reports/users_reports) or [income insights report](/api-reference/income-insights/income-insights-report-create) depending on the method. *** ## Combine methods Most production implementations combine two or more approaches: * **Smart Routing + PLL**: Verify income during the application, then set up automatic repayment after approval. * **Payroll + Bank**: Try payroll first for the best data quality. Fall back to bank income when the employer has low payroll coverage. * **Any method + Documents**: Enable document upload as a fallback in Bridge when direct connections are unavailable. *** ## Next steps Automatically recommend the best verification method for each applicant Verify income from bank transactions when payroll is unavailable Connect directly to payroll for verified income and employment data Set up automatic loan repayment from the borrower's paycheck # Payroll Income Source: https://truv.com/docs/credit/integration/payroll-income Verify applicant income and employment directly from payroll providers Verify income and employment by connecting directly to the applicant's payroll provider. This delivers the highest data quality -- verified pay history, employer details, and current employment status -- for lending decisions. **Integration pattern:** [Bridge Widget](/developers/integration/bridge-widget/overview) | **Products:** VOIE | **Demo:** [PayrollIncome](https://github.com/truvhq/demo-apps) *** ## Get started Clone and run the [PayrollIncome demo](https://github.com/truvhq/demo-apps) to see the full payroll income verification flow working locally. ```bash theme={null} git clone https://github.com/truvhq/demo-apps.git cd demo-apps npm install && npm start ``` Open `http://localhost:5173`, select **Consumer Credit > Payroll Income**, and walk through a verification using sandbox credentials (`goodlogin` / `goodpassword`). See [full setup instructions](/developers/quickstarts-overview#demo-apps) for ngrok and environment configuration. The demo follows this sequence: 1. **Search for employer** -- Your server calls [GET /v1/company-mappings-search/](/api-reference/companies/company_autocomplete_search) to find the applicant's employer by name. The response returns a `company_mapping_id`. 2. **Create a user** -- Your server calls [POST /v1/users/](/api-reference/users/users_create) to create a Truv user. 3. **Create a bridge token** -- Your server calls [POST /v1/users//tokens/](/api-reference/bridge-token/users_tokens) with `product_type: "income"`, `data_sources: ["payroll"]`, and `company_mapping_id` to [deeplink](/developers/integration/bridge-widget/deeplinking) Bridge to the employer. 4. **Initialize Bridge** -- Your frontend opens [Truv Bridge](/developers/sdks/javascript) with the `bridge_token`. The applicant connects their payroll account. 5. **Receive webhooks** -- Truv sends a `task-status-updated` [webhook](/api-reference/webhook-events) when verification completes. Verify the signature using the `X-Webhook-Sign` header with HMAC-SHA256. 6. **Retrieve the VOIE report** -- Fetch the report with [POST /v1/users//reports/](/api-reference/user-income-and-employment-reports/users_reports). The report contains verified income and employment data from the payroll provider. Each step maps to a specific file in the demo. Use these as reference when building your integration. | Step | Demo file | API reference | | --------------------- | -------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | | Employer search | [`src/components/CompanySearch.jsx`](https://github.com/truvhq/demo-apps/blob/main/src/components/CompanySearch.jsx) | [Company Search](/api-reference/companies/company_autocomplete_search) | | User creation | [`server/routes/bridge.js`](https://github.com/truvhq/demo-apps/blob/main/server/routes/bridge.js) | [POST /v1/users/](/api-reference/users/users_create) | | Bridge token | [`server/routes/bridge.js`](https://github.com/truvhq/demo-apps/blob/main/server/routes/bridge.js) | [POST /v1/users//tokens/](/api-reference/bridge-token/users_tokens) | | Bridge initialization | [`src/demos/PayrollIncome.jsx`](https://github.com/truvhq/demo-apps/blob/main/src/demos/PayrollIncome.jsx) | [Bridge SDK](/developers/sdks/javascript) | | Webhook verification | [`server/webhooks.js`](https://github.com/truvhq/demo-apps/blob/main/server/webhooks.js) | [Webhook events](/api-reference/webhook-events) | | Report retrieval | [`server/routes/user-reports.js`](https://github.com/truvhq/demo-apps/blob/main/server/routes/user-reports.js) | [Income reports](/api-reference/user-income-and-employment-reports/users_reports) | *** ## Consumer Credit-specific configuration ### Bridge token for payroll income Set `data_sources` to `["payroll"]` to restrict Bridge to payroll connections only: ```json theme={null} { "product_type": "income", "data_sources": ["payroll"], "company_mapping_id": "COMPANY_MAPPING_ID" } ``` Pass `company_mapping_id` from the [company search](/api-reference/companies/company_autocomplete_search) to deeplink Bridge directly to the employer's payroll provider. Without it, Bridge shows a generic employer search screen. Payroll income uses `company_mapping_id` (not `provider_id`). The `provider_id` field is for financial institutions like banks. Passing the wrong identifier type causes Bridge to show a generic search screen. ### VOIE report Payroll income verification returns a standard [VOIE report](/api-reference/user-income-and-employment-reports/users_reports) containing: * Current and historical income (base pay, overtime, bonuses, commissions) * Employment details (employer name, hire date, status) * Pay frequency and YTD earnings The `income` product type includes employment data automatically. You do not need to request `employment` separately. *** ## Next steps Automatically recommend payroll, bank, or documents based on employer coverage Fall back to bank transactions when payroll coverage is low Full implementation guide for user creation, bridge tokens, and Bridge initialization Skip the employer search when you already know the company # Paycheck-Linked Loans Source: https://truv.com/docs/credit/integration/pll Set up automatic loan repayment directly from the borrower paycheck via payroll deduction Set up automatic loan repayment by connecting to the borrower's payroll provider. The borrower authenticates through [Truv Bridge](/developers/sdks/javascript), and Truv routes a fixed amount or percentage of each paycheck to your bank account. You also receive a verified income report alongside the deposit switch confirmation. **Integration pattern:** [Bridge Widget](/developers/integration/bridge-widget/overview) | **Products:** PLL (Paycheck-Linked Lending) | **Demo:** [PaycheckLinkedLoans](https://github.com/truvhq/demo-apps) *** ## Get started Clone and run the [PaycheckLinkedLoans demo](https://github.com/truvhq/demo-apps) to see the full paycheck-linked lending flow working locally. ```bash theme={null} git clone https://github.com/truvhq/demo-apps.git cd demo-apps npm install && npm start ``` Open `http://localhost:5173`, select **Consumer Credit > Paycheck-Linked Loans**, and walk through a verification using sandbox credentials (`goodlogin` / `goodpassword`). See [full setup instructions](/developers/quickstarts-overview#demo-apps) for ngrok and environment configuration. The demo follows this sequence: 1. **Search for employer** -- Your server calls [GET /v1/company-mappings-search/](/api-reference/companies/company_autocomplete_search) to find the borrower's employer by name. 2. **Create a user** -- Your server calls [POST /v1/users/](/api-reference/users/users_create) to create a Truv user. 3. **Create a bridge token** -- Your server calls [POST /v1/users//tokens/](/api-reference/bridge-token/users_tokens) with `product_type: "pll"` and optionally `company_mapping_id` to [deeplink](/developers/integration/bridge-widget/deeplinking) Bridge to the employer. Include the `account` object with your bank details and deduction configuration. 4. **Initialize Bridge** -- Your frontend opens [Truv Bridge](/developers/sdks/javascript) with the `bridge_token`. The borrower connects their payroll and confirms the deduction. 5. **Receive webhooks** -- Truv sends a `task-status-updated` [webhook](/api-reference/webhook-events) when the enrollment completes. Verify the signature using the `X-Webhook-Sign` header with HMAC-SHA256. 6. **Retrieve dual reports** -- Fetch the [VOIE report](/api-reference/user-income-and-employment-reports/users_reports) with `POST /v1/users/{user_id}/reports/` for income data. Fetch the [deposit switch report](/api-reference/dds-reports/dds-report-retrieve) with `GET /v1/users/{user_id}/deposit_switch/report/` for deduction confirmation. Each step maps to a specific file in the demo. Use these as reference when building your integration. | Step | Demo file | API reference | | --------------------- | ---------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | | Employer search | [`src/components/CompanySearch.jsx`](https://github.com/truvhq/demo-apps/blob/main/src/components/CompanySearch.jsx) | [Company Search](/api-reference/companies/company_autocomplete_search) | | User creation | [`server/routes/bridge.js`](https://github.com/truvhq/demo-apps/blob/main/server/routes/bridge.js) | [POST /v1/users/](/api-reference/users/users_create) | | Bridge token | [`server/routes/bridge.js`](https://github.com/truvhq/demo-apps/blob/main/server/routes/bridge.js) | [POST /v1/users//tokens/](/api-reference/bridge-token/users_tokens) | | Bridge initialization | [`src/demos/PaycheckLinkedLoans.jsx`](https://github.com/truvhq/demo-apps/blob/main/src/demos/PaycheckLinkedLoans.jsx) | [Bridge SDK](/developers/sdks/javascript) | | Webhook verification | [`server/webhooks.js`](https://github.com/truvhq/demo-apps/blob/main/server/webhooks.js) | [Webhook events](/api-reference/webhook-events) | | Income report | [`server/routes/user-reports.js`](https://github.com/truvhq/demo-apps/blob/main/server/routes/user-reports.js) | [Income reports](/api-reference/user-income-and-employment-reports/users_reports) | | Deposit switch report | [`server/routes/user-reports.js`](https://github.com/truvhq/demo-apps/blob/main/server/routes/user-reports.js) | [Deposit switch report](/api-reference/dds-reports/dds-report-retrieve) | *** ## Consumer Credit-specific configuration ### Bridge token for PLL Set `product_type` to `"pll"` and include the `account` object with your bank details and deduction configuration: ```json theme={null} { "product_type": "pll", "company_mapping_id": "COMPANY_MAPPING_ID", "account": { "account_number": "16002600", "routing_number": "123456789", "bank_name": "Your Bank", "account_type": "checking", "deposit_type": "amount", "deposit_value": "200.00" } } ``` ### Deduction options Control the repayment amount with `deposit_type` and `deposit_value`: | `deposit_type` | `deposit_value` | Description | | -------------- | --------------- | -------------------------------- | | `amount` | `"200.00"` | Fixed dollar amount per paycheck | | `percent` | `"10"` | Percentage of each paycheck | ### Dual reports PLL verification produces two reports in parallel: | Report | Endpoint | What it contains | | ------------------------------------------------------------------------------ | ------------------------------------------------ | ---------------------------------------------- | | [VOIE report](/api-reference/user-income-and-employment-reports/users_reports) | `POST /v1/users/{user_id}/reports/` | Verified income, employment, and pay history | | [Deposit switch report](/api-reference/dds-reports/dds-report-retrieve) | `GET /v1/users/{user_id}/deposit_switch/report/` | Deduction confirmation with allocation details | Both reports become available after the `task-status-updated` webhook fires with `status: done`. Fetch them in parallel for the fastest results. *** ## Next steps Verify income before approval, then set up PLL after Full implementation guide for user creation, bridge tokens, and Bridge initialization Product details for Paycheck-Linked Lending Handle all Bridge lifecycle events and error codes # Smart Routing Source: https://truv.com/docs/credit/integration/smart-routing Automatically recommend the best verification method based on employer payroll coverage Route each applicant to the fastest verification path -- payroll, bank transactions, or document upload -- based on their employer's payroll coverage. The system checks coverage via [company search](/api-reference/companies/company_autocomplete_search), recommends a method, and lets the applicant confirm or override. **Integration pattern:** [Bridge Widget](/developers/integration/bridge-widget/overview) | **Products:** VOIE, Income Insights | **Demo:** [SmartRouting](https://github.com/truvhq/demo-apps) *** ## Get started Clone and run the [SmartRouting demo](https://github.com/truvhq/demo-apps) to see the full smart routing flow working locally. ```bash theme={null} git clone https://github.com/truvhq/demo-apps.git cd demo-apps npm install && npm start ``` Open `http://localhost:5173`, select **Consumer Credit > Smart Routing**, and walk through a verification using sandbox credentials (`goodlogin` / `goodpassword`). See [full setup instructions](/developers/quickstarts-overview#demo-apps) for ngrok and environment configuration. The demo follows this sequence: 1. **Search for employer** -- Your server calls [GET /v1/company-mappings-search/](/api-reference/companies/company_autocomplete_search) to find the applicant's employer. The `success_rate` field in the response determines the recommendation: `high` suggests payroll, `low`/`medium` suggests bank, and no results suggests documents. 2. **Create a user** -- Your server calls [POST /v1/users/](/api-reference/users/users_create) to create a Truv user. 3. **Create a bridge token** -- Your server calls [POST /v1/users//tokens/](/api-reference/bridge-token/users_tokens) with the selected `data_sources` array (`["payroll"]`, `["financial_accounts"]`, or `["docs"]`). Pass `company_mapping_id` for payroll to [deeplink](/developers/integration/bridge-widget/deeplinking) Bridge to the employer. 4. **Initialize Bridge** -- Your frontend opens [Truv Bridge](/developers/sdks/javascript) with the `bridge_token`. The applicant connects their provider. 5. **Receive webhooks** -- Truv sends a `task-status-updated` [webhook](/api-reference/webhook-events) when verification completes. Verify the signature using the `X-Webhook-Sign` header with HMAC-SHA256. 6. **Retrieve the report** -- For payroll or document methods, fetch the [VOIE report](/api-reference/user-income-and-employment-reports/users_reports) with `POST /v1/users/{user_id}/reports/`. For bank income, fetch the [income insights report](/api-reference/income-insights/income-insights-report-create) with `POST /v1/users/{user_id}/income_insights/reports/`. Each step maps to a specific file in the demo. Use these as reference when building your integration. | Step | Demo file | API reference | | --------------------- | -------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | | Employer search | [`src/components/CompanySearch.jsx`](https://github.com/truvhq/demo-apps/blob/main/src/components/CompanySearch.jsx) | [Company Search](/api-reference/companies/company_autocomplete_search) | | User creation | [`server/routes/bridge.js`](https://github.com/truvhq/demo-apps/blob/main/server/routes/bridge.js) | [POST /v1/users/](/api-reference/users/users_create) | | Bridge token | [`server/routes/bridge.js`](https://github.com/truvhq/demo-apps/blob/main/server/routes/bridge.js) | [POST /v1/users//tokens/](/api-reference/bridge-token/users_tokens) | | Bridge initialization | [`src/demos/SmartRouting.jsx`](https://github.com/truvhq/demo-apps/blob/main/src/demos/SmartRouting.jsx) | [Bridge SDK](/developers/sdks/javascript) | | Webhook verification | [`server/webhooks.js`](https://github.com/truvhq/demo-apps/blob/main/server/webhooks.js) | [Webhook events](/api-reference/webhook-events) | | Report retrieval | [`server/routes/user-reports.js`](https://github.com/truvhq/demo-apps/blob/main/server/routes/user-reports.js) | [Income reports](/api-reference/user-income-and-employment-reports/users_reports) | *** ## Consumer Credit-specific configuration ### Routing logic The `success_rate` field from [company search](/api-reference/companies/company_autocomplete_search) drives the recommendation: | `success_rate` value | Recommended method | `data_sources` | | -------------------- | ------------------ | ------------------------ | | `high` | Payroll | `["payroll"]` | | `low` / `medium` | Bank transactions | `["financial_accounts"]` | | No results | Document upload | `["docs"]` | The applicant can always override the recommendation and pick any method. ### Data sources Control which verification methods Bridge shows by setting the `data_sources` array when creating the bridge token: ```json theme={null} { "product_type": "income", "data_sources": ["payroll"], "company_mapping_id": "COMPANY_MAPPING_ID" } ``` For payroll, pass `company_mapping_id` to deeplink Bridge to the employer. For bank income, pass `provider_id` to deeplink to the financial institution. Document upload requires no additional identifier. ### Report types The report endpoint depends on the method the applicant chose: | Method | Report endpoint | Report type | | ----------------- | --------------------------------------------------- | ------------------------------------------------------------------------------- | | Payroll | `POST /v1/users/{user_id}/reports/` | [VOIE](/api-reference/user-income-and-employment-reports/users_reports) | | Bank transactions | `POST /v1/users/{user_id}/income_insights/reports/` | [Income Insights](/api-reference/income-insights/income-insights-report-create) | | Documents | `POST /v1/users/{user_id}/reports/` | [VOIE](/api-reference/user-income-and-employment-reports/users_reports) | *** ## Next steps Verify income from bank transactions when payroll coverage is low Connect directly to payroll for the highest data quality Full implementation guide for user creation, bridge tokens, and Bridge initialization Skip the provider search screen when you already know the employer or bank # Consumer Credit Source: https://truv.com/docs/credit/overview Income and asset verification for auto loans, personal loans, and credit decisioning Truv helps consumer lenders verify borrower income and assets instantly, improving approval rates and reducing fraud. Real-time income verification for instant approvals Verify income for thin-file borrowers Direct data prevents document falsification No document uploads needed *** ## Quick start Run a demo app to see Truv in action, then follow the integration guide to build it into your workflow. Payroll-first with automatic document fallback Transaction-based income verification Direct payroll connection for income data Automatic loan repayment from paycheck *** ## What you can verify * Current income * Employment status * Pay frequency * YTD earnings * Bank balances * Account ownership * Transaction patterns * Cash flow analysis * Income deposits * Spending patterns *** ## Use cases Verify income for vehicle financing: * New and used car loans * Refinancing * Lease buyouts **Products:** Income & Employment, Assets Income verification for unsecured lending: * Debt consolidation * Home improvement loans * Emergency expenses **Products:** Income & Employment, Assets Income verification for credit limit decisions: * New account applications * Credit limit increases * Risk assessment **Products:** Income & Employment Quick income checks for BNPL: * Point-of-sale financing * Installment plans * Higher-ticket items **Products:** Income & Employment *** ## Integration options ### Option 1: Dashboard (No Code) Truv Dashboard and order landing page Use the Truv Dashboard to create and manage verification orders without any integration: * Create orders manually via the Dashboard UI * Send verification links to borrowers via email/SMS * View results directly in the Dashboard * Optionally add webhooks to sync data to your loan origination system [Learn more about Dashboard integration -->](/developers/dashboard) ### Option 2: Embedded Orders (Recommended) Embedded order For custom implementations or automated lending workflows: Payroll-first with automatic document fallback Transaction-based income verification Direct payroll connection for income data Automatic loan repayment from paycheck *** ## Implementation timeline | Integration Method | Timeline | Code Required | | ------------------- | --------- | ------------- | | **Dashboard** | Same day | None | | **Embedded Orders** | 2-4 weeks | Minimal | *** ## Get started * Quick start with no code? --> [Dashboard Integration](/developers/dashboard) * Building custom? --> Choose an integration from the [Quick start](#quick-start) section above Clone the [demo apps repo](https://github.com/truvhq/demo-apps) and run a demo to see the verification flow end-to-end. Test with various borrower scenarios Start verifying borrower income instantly *** ## Next steps Payroll-first with document fallback Complete API documentation Implementation guidelines Talk to our lending solutions team # Assets for Lending Source: https://truv.com/docs/credit/products/assets Asset verification for consumer lending Verify borrower bank account balances, ownership, and transaction history for lending decisions. Truv pulls data directly from financial institutions, giving you a verified view of borrower liquidity. *** ## Benefits Real-time account balances and transaction data Data from Chase, Bank of America, and thousands more 30/60/90-day balance averages and deposit patterns Verified ownership and large deposit flagging *** ## What you get * Account type (checking, savings, money market, CD, investment) * Verified account holder name and ownership * Current and available balances * Routing number and masked account number * Up to 2 years of transaction history (30-730 days via `days_requested`) * Date, description, amount, and type * Direct deposit identification * 30/60/90-day average balances * Balance history * Currency and metadata * Bank statements (PDF) * Account verification letter *** ## Use cases Confirm the borrower has sufficient liquid assets to cover the down payment and closing costs for auto or personal loans with collateral requirements. Evaluate total liquid assets across checking, savings, and investment accounts to determine borrower financial stability. Analyze deposit and withdrawal patterns to assess repayment capacity, especially useful for self-employed or gig-economy borrowers. Verify account ownership and flag unusual patterns such as large unexplained deposits or inconsistent account activity. *** ## Data coverage ### Financial Institutions Truv connects to major banks and credit unions: | Institution Type | Examples | | ---------------- | ----------------------------------------- | | National banks | Chase, Bank of America, Wells Fargo, Citi | | Regional banks | PNC, US Bank, TD Bank | | Credit unions | Navy Federal, State Employees CU | | Online banks | Ally, Marcus, Discover | | Investment | Fidelity, Charles Schwab, Vanguard | *** ## How to implement Choose your integration path based on your tech stack: | Path | Code required | Best for | | -------------------------------------------------- | ------------- | ------------------------------------ | | [Smart Routing](/credit/integration/smart-routing) | Minimal | Payroll-first with document fallback | | [Truv Dashboard](/developers/dashboard) | None | Manual orders, pilot testing | **Combine with Income & Employment for a complete picture.** Request both `assets` and `income` product types in a single order to verify both income and liquidity. [Learn about Income & Employment -->](/credit/products/income-employment) For a full implementation walkthrough including webhook handling and [Truv Bridge](/developers/sdks/javascript) setup, see the [Smart Routing guide](/credit/integration/smart-routing). *** ## Report structure When you retrieve asset data via the API, the response contains a `links` array with accounts, balances, and transactions per financial institution. | Field | Path | Example | | --------------- | ----------------------------------------------------- | --------------------- | | Account type | `links[].accounts[].type` | `CHECKING`, `SAVINGS` | | Masked number | `links[].accounts[].mask` | `"1234"` | | Account holder | `links[].accounts[].owners[].full_name` | `"John Smith"` | | Current balance | `links[].accounts[].balances.current` | `"15420.50"` | | Direct deposit | `links[].accounts[].transactions[].is_direct_deposit` | `true` | | 30-day avg | `summary.avg_30` | `"14500.00"` | ```json theme={null} { "id": "a1b2c3d4-5678-90ab-cdef-1234567890ab", "large_deposit_threshold": "2500.00", "summary": { "avg_30": "9200.50", "avg_60": "8850.75", "avg_90": "8500.00", "balance": "23750.25" }, "links": [ { "accounts": [ { "type": "CHECKING", "mask": "1234", "owners": [ { "full_name": "Jane Smith" } ], "balances": { "balance": "8750.25", "available_balance": "8500.00" }, "transactions": [ { "transacted_at": "2024-01-15T10:30:00Z", "posted_at": "2024-01-15T14:00:00Z", "description": "DIRECT DEPOSIT - ACME CORP", "amount": "2650.00", "type": "CREDIT", "is_direct_deposit": true } ] }, { "type": "SAVINGS", "mask": "5678", "owners": [ { "full_name": "Jane Smith" } ], "balances": { "balance": "15000.00", "available_balance": "15000.00" }, "transactions": [] } ] } ] } ``` *** ## API reference Create tokens for Truv Bridge Retrieve asset data Financial account details Create and manage users *** ## Best practices Use the `large_deposit_threshold` from the report and review transactions that exceed it: ```javascript theme={null} const largeDeposits = report.links .flatMap(link => link.accounts) .flatMap(account => account.transactions) .filter(t => t.type === "CREDIT" && t.amount >= report.large_deposit_threshold); ``` Filter for direct deposits to verify recurring income: ```javascript theme={null} const directDeposits = report.links .flatMap(link => link.accounts) .flatMap(account => account.transactions) .filter(t => t.is_direct_deposit); ``` Use the report-level summary or aggregate across all linked accounts: ```javascript theme={null} // Use the report summary for quick totals const totalBalance = report.summary.balance; // Or aggregate per-account balances const perAccount = report.links .flatMap(link => link.accounts) .map(a => ({ type: a.type, mask: a.mask, current: a.balances.current })); ``` *** ## Next steps Payroll-first with document fallback Transaction-level bank data # Transactions for Lending Source: https://truv.com/docs/credit/products/bank-aggregation Cash flow analysis and bank data for lending decisions Analyze transaction-level bank data for cash flow underwriting and alternative credit assessment. Connect directly to the borrower's bank through [Truv Bridge](/developers/sdks/javascript) for a detailed view of income deposits, spending behavior, and balance trends. **Try the demo** -- Run the [Bank Income demo](/credit/integration/bank-income) to see bank transaction-based income verification. [Clone the demo app ->](https://github.com/truvhq/demo-apps) *** ## Benefits Real transaction data for repayment capacity Extend credit to thin-file and underserved borrowers Identify recurring deposits without payroll connection 30-730 days of transaction history, configurable per request *** ## What you get * Individual transactions with date, description, amount, and type * Recurring deposit identification * Expense categorization * Account type (checking, savings) * Verified account holder * Current and available balances * Routing and masked account number * Net cash flow trends * Balance history * Recurring income patterns * Spending behavior *** ## Use cases Analyze real transaction data to assess repayment capacity. Particularly effective for borrowers whose income is not easily captured by traditional pay stubs. Identify recurring deposits to estimate income when payroll-based verification is not available, such as for self-employed or gig-economy workers. Build a financial profile from transaction data for borrowers with thin credit files or limited credit history. Extend credit to underserved populations by supplementing traditional credit data with bank transaction insights. *** ## Data coverage ### Financial Institutions Truv connects to major banks and credit unions: | Institution Type | Examples | | ---------------- | ----------------------------------------- | | National banks | Chase, Bank of America, Wells Fargo, Citi | | Regional banks | PNC, US Bank, TD Bank | | Credit unions | Navy Federal, State Employees CU | | Online banks | Ally, Marcus, Discover | | Neobanks | Chime, Current, Varo | *** ## How to implement | Path | Code required | Best for | | ---------------------------------------------- | ------------- | ------------------------------------- | | [Bank Income](/credit/integration/bank-income) | Minimal | Transaction-based income verification | | [Truv Dashboard](/developers/dashboard) | None | Manual orders, pilot testing | | [API Reference](/api-reference) | Custom | Full API control | *** ## Report structure ### API Response ```json theme={null} { "count": 2, "accounts": [ { "id": "24d7e80942ce4ad58a93f70ce4115f5c", "type": "CHECKING", "subtype": null, "mask": "1234", "nickname": "Primary Checking", "balances": { "currency_code": "USD", "balance": "4500.00", "available_balance": "4200.00", "credit_limit": null } } ], "transactions": [ { "id": "tx_a1b2c3d4", "account_id": "24d7e80942ce4ad58a93f70ce4115f5c", "amount": "2650.00", "currency_code": "USD", "description": "DIRECT DEPOSIT - ACME CORP", "status": "POSTED", "type": "CREDIT", "posted_at": "2024-01-15T14:00:00Z", "transacted_at": "2024-01-15T10:30:00Z", "categories": ["Transfer", "Payroll"], "is_direct_deposit": true }, { "id": "tx_e5f6a7b8", "account_id": "24d7e80942ce4ad58a93f70ce4115f5c", "amount": "1800.00", "currency_code": "USD", "description": "RENT PAYMENT", "status": "POSTED", "type": "DEBIT", "posted_at": "2024-01-12T10:00:00Z", "transacted_at": "2024-01-12T10:00:00Z", "categories": ["Home", "Rent"] } ] } ``` *** ## API reference Create tokens for Truv Bridge Account balance data Financial account details Create and manage users *** ## Best practices Truv supports 30 to 730 days of transaction history. Set `days_requested` when creating the report to control how much data you receive. 60 days is the default. Check the `days_available` field on each account to see how much history was returned. Filter for recurring deposits to estimate stable income, especially for borrowers with irregular pay schedules. Bank Aggregation works best alongside Income & Employment verification. Use payroll data as the primary income source and bank data for supplementary analysis. *** ## Next steps Full implementation walkthrough Payroll-based income data # Income & Employment for Lending Source: https://truv.com/docs/credit/products/income-employment Income verification for consumer lending decisions Verify borrower income and employment instantly for loan underwriting and credit decisions. Truv connects directly to payroll systems, returning verified details in seconds. **Try the demo** -- Run the [Smart Routing demo](/credit/integration/smart-routing) or [Payroll Income demo](/credit/integration/payroll-income) to see income verification working end-to-end. [Clone the demo app ->](https://github.com/truvhq/demo-apps) *** ## Benefits Verified income and employment data in seconds ADP, Paychex, Workday, UKG, and 100+ payroll providers Structured data ready for your decision engine W-2, 1099, gig, and self-employed income *** ## What you get * Base salary, hourly rate, commission, bonus * Pay frequency * Year-to-date gross and net pay * Historical pay statements * Tax deductions and withholdings * Employer name, address, EIN * Employment status (active, terminated, leave) * Start and end dates * Job title and position * Pay stubs (PDF) * W-2 forms (when available) * W-2 employees * 1099 contractors * Multiple employers * Self-employed (limited) *** ## Use cases Verify borrower income in real time during the application flow. Supports both prime and subprime decisioning with gross pay, pay frequency, and employment tenure. Calculate debt-to-income ratios using verified pay data. Ideal for debt consolidation, home improvement, and emergency expense loans. Use current income to set or increase credit limits. Works for new account applications and periodic limit reviews. Quick income checks at the point of sale. Verify affordability for installment plans and higher-ticket purchases. *** ## Data coverage ### Payroll Providers Truv connects to payroll providers covering 85%+ of US employees: | Provider | Coverage | | ------------- | ------------------- | | ADP | \~20% of US workers | | Paychex | \~10% of US workers | | Workday | Large enterprises | | UKG (Kronos) | Healthcare, retail | | Paylocity | Mid-market | | Gusto | Small business | | And 100+ more | | ### Supported Income Types * W-2 employees * 1099 contractors * Multiple employers * Self-employed (limited) *** ## How to implement Choose your integration path based on your tech stack: | Path | Code required | Best for | | ---------------------------------------------------- | ------------- | ------------------------------------ | | [Smart Routing](/credit/integration/smart-routing) | Minimal | Payroll-first with document fallback | | [Payroll Income](/credit/integration/payroll-income) | Minimal | Direct payroll connection | | [Truv Dashboard](/developers/dashboard) | None | Manual orders, pilot testing | The `income` product automatically includes employment data. Do not pass both `income` and `employment` in the same order. **Combine with Assets for stronger decisions.** Request both `income` and `assets` product types in a single order to get a complete financial picture of the borrower. [Learn about Assets verification -->](/credit/products/assets) For a full implementation walkthrough including webhook handling and [Truv Bridge](/developers/sdks/javascript) Token setup, see the [Smart Routing guide](/credit/integration/smart-routing) or [Payroll Income guide](/credit/integration/payroll-income). *** ## Report structure The response follows the `IncomeCheck` schema with a top-level `employments` array. Each employment includes income summary fields, company details, borrower profile, and an array of pay statements. | Field | Path | Example | | -------------- | ----------------------------- | -------------------- | | Annual income | `employments[].income` | `"70000.00"` | | Income period | `employments[].income_unit` | `YEARLY` | | Pay per period | `employments[].pay_rate` | `"6500.00"` | | Pay frequency | `employments[].pay_frequency` | `SM` (Semi-Monthly) | | Employer | `employments[].company.name` | `"Acme Corporation"` | | Pay statements | `employments[].statements[]` | Array of pay stubs | ```json theme={null} { "id": "24d7e80942ce4ad58a93f70ce4115f5c", "status": "done", "provider": "adp", "data_source": "payroll", "employments": [ { "income": "70000.00", "income_unit": "YEARLY", "pay_rate": "6500.00", "pay_frequency": "SM", "company": { "name": "Acme Corporation", "address": { "street": "123 Main St", "city": "New York", "state": "NY", "zip": "10001" } }, "profile": { "first_name": "John", "last_name": "Doe" }, "statements": [ { "pay_date": "2024-01-19", "gross_pay": "2650.00", "net_pay": "1950.00" }, { "pay_date": "2024-01-05", "gross_pay": "2650.00", "net_pay": "1950.00" } ] } ] } ``` **Pay frequency codes:** `M` (Monthly), `SM` (Semi-Monthly), `W` (Weekly), `BW` (Bi-Weekly), `A` (Annually), `SA` (Semiannually), `C` (Commission) The `income` product automatically includes employment data. You never need to request both `income` and `employment` separately. *** ## API reference Create tokens for Truv Bridge Retrieve income data Retrieve employment data Create and manage users *** ## Best practices For most consumer lending decisions, reviewing 90 days of pay statements provides a solid baseline for income calculation. Truv returns available pay statements from the payroll provider. Check the `statements` array in the response and verify that coverage meets your underwriting requirements. Borrowers may have side jobs or gig work. Each payroll connection creates a separate employment entry in the `employments` array. To capture multiple income sources, have the borrower connect each employer through the Truv Bridge widget sequentially. Trigger verification as part of the loan application flow rather than as a separate step to improve completion rates. *** ## Next steps Payroll-first with document fallback Add asset data to your decisions # Paycheck Linked Lending Source: https://truv.com/docs/credit/products/pll Automatic loan repayment directly from paycheck Collect loan repayments automatically by deducting payments directly from the borrower's paycheck. Achieve higher repayment rates and lower default risk compared to traditional ACH-based collections. **Try the demo** -- Run the [Paycheck-Linked Loans demo](/credit/integration/pll) to see payroll deduction setup working end-to-end. [Clone the demo app ->](https://github.com/truvhq/demo-apps) *** ## How it works The borrower authenticates with their employer's payroll system through [Truv Bridge](/developers/sdks/javascript). You specify the repayment amount as a fixed dollar value or a percentage of net pay. Each pay period, the configured amount is deducted from the borrower's paycheck. The deducted payment is sent directly to your collection account. *** ## Benefits Payments happen before discretionary spending Automatic, consistent payments every pay period No manual payment management or missed due dates Know payment status immediately through webhooks *** ## Deduction types | Type | Description | Example | | --------- | --------------------- | -------------------- | | `amount` | Fixed dollar amount | \$200 per paycheck | | `percent` | Percentage of net pay | 10% of each paycheck | Paycheck Linked Lending uses the **User Token flow** instead of Embedded Orders. This provides ongoing access to the payroll connection for recurring deductions. *** ## Data coverage ### Payroll Providers Truv connects to payroll providers covering 85%+ of US employees: | Provider | Coverage | | ------------- | ------------------- | | ADP | \~20% of US workers | | Paychex | \~10% of US workers | | Workday | Large enterprises | | UKG (Kronos) | Healthcare, retail | | Paylocity | Mid-market | | Gusto | Small business | | And 100+ more | | *** ## Report structure The PLL report returns the deduction status and deposit configuration for a borrower's payroll link. | Field | Description | | -------------------------------- | ----------------------------------------------------- | | `id` | Unique report identifier | | `status` | Request status (`new`, `done`, `error`) | | `deposit_details.deposit_type` | `amount` (fixed) or `percent` (percentage of net pay) | | `deposit_details.deposit_value` | Configured deduction value | | `deposit_details.account_number` | Target bank account number | | `deposit_details.routing_number` | Target bank routing number | | `deposit_details.bank_name` | Target bank name | | `deposit_details.account_type` | `checking` or `savings` | | `finished_at` | Timestamp when the report completed | ```json theme={null} { "id": "24d7e80942ce4ad58a93f70ce4115f5c", "status": "done", "finished_at": "2021-04-06T11:30:00Z", "access_token": "48427a36d43c4d5aa6324bc06c692456", "tracking_info": "user123456", "deposit_details": { "account_number": "16002600", "routing_number": "123456789", "bank_name": "TD Bank", "account_type": "checking", "deposit_type": "amount", "deposit_value": "200.00" } } ``` See the [PLL Report API reference](/api-reference/deposit-switch/link_detail_reports_pll) for the full schema. *** ## Manage the lifecycle Once a Paycheck Linked Lending deduction is active, you can: * **Update the deduction amount**, adjust as the loan balance changes * **Pause deductions**, temporarily suspend during hardship periods * **Cancel deductions**, remove when the loan is fully repaid *** ## API reference Create tokens for Truv Bridge Paycheck Linked Lending report PLL link detail report Create and manage users *** ## Best practices Always cancel the deduction when the loan balance reaches zero to avoid over-collection and maintain borrower trust. Fixed dollar deductions provide consistent repayment schedules. Percentage-based deductions are useful when income varies. Watch for `task-status-updated` webhooks to detect if the borrower changes jobs or their payroll provider rejects the deduction. *** ## Next steps Step-by-step Paycheck Linked Lending setup Understand the User + Bridge Token integration flow # Scoring Attributes for Lending Source: https://truv.com/docs/credit/products/scoring Transaction-derived risk scores and financial metrics for credit decisioning Analyze bank transaction data to generate risk scores, income metrics, and spending patterns for credit decisioning. Use scoring reports as an alternative or supplement to traditional credit bureau data. No hard inquiry on the consumer's credit report. *** ## Benefits Risk assessment without impacting the consumer's credit Score borrowers with limited credit history Scores derived from real bank activity, not models Analyze from 1 week to lifetime of data *** ## What you get * Overdraft risk prediction * Balance pattern analysis * Transaction behavior scoring * Derived income streams * Frequency and average amount * Monthly income projections * Daily balance calculations * Minimum balance tracking * Balance trends over time * NSF fee detection * Debit activity ratios * Expense categorization *** ## Report purposes | Purpose | Use Case | Fair Credit Reporting Act (FCRA) | | -------------- | ---------------------------------------------- | -------------------------------- | | `decisioning` | Credit decisioning and loan approval | Yes | | `verification` | Underwriting verifications and income analysis | No | | `analytics` | Retroactive portfolio analysis | No | *** ## Use cases Use transaction-derived risk scores and income metrics as an alternative or supplement to traditional credit bureau data. Particularly valuable for borrowers with thin credit files. Verify income claims and assess financial stability during the loan origination process using real bank transaction data. Run retroactive analysis on existing portfolios to identify risk concentration and performance drivers. Extend credit to underserved populations by supplementing traditional credit data with bank transaction signals. *** ## How to implement | Path | Code required | Best for | | -------------------------------------------------- | ------------- | ---------------------------- | | [Scoring API](/api-reference/data-structure) | Custom | Direct API integration | | [Smart Routing](/credit/integration/smart-routing) | Minimal | Combined with other products | See the [Scoring API reference](/api-reference/data-structure) for full request and response schemas. *** ## API reference Scoring attributes and report schema Create tokens for Truv Bridge Create and manage users *** ## Next steps Full API reference and schema Transaction data that feeds scoring reports # Widget-only Best Practices Source: https://truv.com/docs/developers/best-practices/bridge-token Guidelines for implementing Deposit Switch and Paycheck Linked Lending Follow these best practices for Deposit Switch (DDS) and Paycheck Linked Lending (PLL) integrations using the Widget-only flow. *** ## Wait for webhooks before proceeding Always wait for the `task-status-updated` webhook with `status: done` before treating a connection as complete. Do not rely solely on the client-side `onSuccess` callback. The task may still be processing server-side. ```bash theme={null} # When you receive a task-status-updated webhook with status: done, # retrieve the link details curl --request GET \ --url https://prod.truv.com/v1/links/{link_id}/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' ``` *** ## Validate account details upfront Provide complete and accurate bank account information when creating the bridge token. Missing or incorrect fields cause configuration failures. **Deposit Switch**: route the user's entire paycheck or a fixed amount: ```bash theme={null} curl --request POST \ --url https://prod.truv.com/v1/users/USER_ID/tokens/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' \ --header 'Content-Type: application/json' \ --data '{ "product_type": "deposit_switch", "account": { "account_number": "16002600", "routing_number": "123456789", "bank_name": "TD Bank", "account_type": "checking", "deposit_type": "entire" } }' ``` **Paycheck Linked Lending**: deduct a fixed amount per paycheck: ```bash theme={null} curl --request POST \ --url https://prod.truv.com/v1/users/USER_ID/tokens/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' \ --header 'Content-Type: application/json' \ --data '{ "product_type": "pll", "account": { "account_number": "16002600", "routing_number": "123456789", "bank_name": "TD Bank", "account_type": "checking", "deposit_type": "amount", "deposit_value": "200.00" } }' ``` ### Deposit type options | `deposit_type` | Description | | -------------- | -------------------------------------------------------- | | `entire` | Route the entire paycheck | | `amount` | Route a fixed dollar amount (set `deposit_value`) | | `percent` | Route a percentage of the paycheck (set `deposit_value`) | *** ## Handle errors from webhooks Monitor `task-status-updated` webhooks for error statuses. These indicate the connection or configuration failed. | Webhook status | Cause | Resolution | | ---------------- | ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------- | | `login_error` | Incorrect credentials | Prompt the user to re-authenticate via [Bridge Update Mode](/developers/integration/bridge-widget/returning-user) | | `mfa_error` | MFA challenge failed | Prompt the user to try again | | `config_error` | Provider doesn't support the requested operation | Fall back to manual instructions or try a different provider | | `account_locked` | Too many failed attempts at the provider | Ask the user to unlock their account with the provider | See [Task lifecycle](/api-reference/tasks/lifecycle) for all status transitions. *** ## Handle client-side errors Listen for `ERROR` events in the Bridge `onEvent` callback. The error object uses `error_code`, not a generic `code` field. ```javascript theme={null} onEvent: function(type, payload) { if (type === 'ERROR') { switch (payload.error.error_code) { case 'LOGIN_ERROR': // User entered wrong credentials — Bridge handles retry UI break; case 'UNAVAILABLE': showMessage('This provider is temporarily unavailable. Try again later.'); break; case 'LINK_EXISTS': showMessage('This account is already connected.'); break; } } } ``` See [Bridge Events](/developers/sdks/bridge-events#errors) for all error codes and their meanings. *** ## Use deeplinking when you know the employer If you know the user's employer or payroll provider, pass it when creating the bridge token to skip search screens and improve conversion. ```bash theme={null} curl --request POST \ --url https://prod.truv.com/v1/users/USER_ID/tokens/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' \ --header 'Content-Type: application/json' \ --data '{ "product_type": "deposit_switch", "company_mapping_id": "48427a36d43c4d5aa6324bc06c692456", "account": { "account_number": "16002600", "routing_number": "123456789", "bank_name": "TD Bank", "account_type": "checking", "deposit_type": "entire" } }' ``` See [Deeplinking](/developers/integration/bridge-widget/deeplinking) for the full guide. *** ## Check DDS/PLL support before connecting Use the [company search endpoint](/api-reference/companies/company_autocomplete_search) to check if a provider supports DDS or PLL before routing the user through the flow. This avoids dead-end experiences where the user connects but the provider doesn't support the desired product. ```bash theme={null} curl --request GET \ --url 'https://prod.truv.com/v1/company-mappings-search/?query=Facebook' \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' ``` Check the response for DDS/PLL availability before initiating the bridge token. *** ## Leverage VOIE-PLL flow For combined income verification and paycheck linked lending, complete the VOIE flow first, then check if the connected provider supports DDS/PLL. After VOIE completes, fetch the link details: ```bash theme={null} curl --request GET \ --url https://prod.truv.com/v1/links/{link_id}/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' ``` Check the `is_dds_available` flag in the response. If `true`, the user's payroll provider supports DDS/PLL and you can offer it as a follow-up step without requiring the user to reconnect. *** ## Understand the token flow The Widget-only flow uses a three-token exchange to securely connect users to their payroll providers: ```text theme={null} bridge_token → public_token → access_token ``` | Token | Created By | Lifetime | Purpose | | -------------- | ------------------------ | ----------- | ------------------------------------ | | `bridge_token` | Your server (via API) | 6 hours | Initialize Truv Bridge on the client | | `public_token` | Truv Bridge (on success) | Short-lived | Temporary token for exchange | | `access_token` | Token exchange (via API) | Persistent | Configure DDS/PLL and retrieve data | ## Store and protect tokens * **`access_token`** is persistent and grants access to the user's data. Store it encrypted on your server. * **`bridge_token`** is short-lived (6 hours) and safe to pass to the client. Generate a new one if the user hasn't started within that window. * **`public_token`** is single-use. Exchange it immediately for an `access_token` via `POST /v1/link-access-tokens/` and discard it. Never expose `access_token` or API credentials in client-side code. *** ## Verify webhook signatures Always verify the `X-WEBHOOK-SIGN` header on incoming webhooks to confirm they are from Truv. Use the raw request body. Never use parsed JSON. See [Webhook Security](/api-reference/security) for verification examples. *** ## Next steps Implementation guide for Widget-only flow Reconnect or update an existing link Client-side event types and error codes Server-side connection statuses # Embedded Orders Best Practices Source: https://truv.com/docs/developers/best-practices/embedded-orders Guidelines for implementing Embedded Orders Follow these best practices to ensure a successful Embedded Orders integration, from order creation through data retrieval and ongoing maintenance. *** ## Embedded Orders vs Bridge Token Truv offers two integration methods. Choose based on your use case: | | Embedded Orders | Bridge Token | | ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | | **When to use** | You don't know the user's employer upfront, or you need Truv to manage the order lifecycle (notifications, reminders, status tracking) | You already know the employer and want full control over the UI and data flow | | **Create via** | `POST /v1/orders/` | `POST /v1/users/{user_id}/tokens/` | | **Products parameter** | `products` array: `["income"]`, `["assets"]`, `["income", "assets"]` | `product_type` string: `"income"`, `"employment"`, `"assets"` + optional `allowed_products` array | | **Bridge initialization** | Pass `bridge_token` from order response, set `isOrder: true` | Pass `bridge_token` from token response, `isOrder` not set | | **Notifications** | Truv can send email/SMS to the user with a verification link | You handle all user communication | | **Webhooks** | `order-status-updated` + `task-status-updated` | `task-status-updated` only | | **Data retrieval** | Via order ID or link ID | Via link ID only | | **Best for** | Hosted flows, multi-employer orders, caseworker-initiated verification | Inline embedded flows where you control the full UX | Most integrations use Embedded Orders. Use Bridge Token only when you need direct control over the connection flow and already have the employer identified. See [Embedded Orders overview](/developers/integration/embedded-orders/overview) and [Bridge Widget overview](/developers/integration/bridge-widget/overview) for full implementation guides. *** ## Create an order ### Request the right products Specify only the products your use case requires. When you include `income` in the products array, employment data is automatically included. You do not need to pass both. ```json theme={null} // Correct — income includes employment data { "products": ["income"] } // Incorrect — employment is redundant here { "products": ["income", "employment"] } // Assets only { "products": ["assets"] } // Income + Assets { "products": ["income", "assets"] } ``` ### Use `external_user_id` for user continuity Pass your internal user identifier as `external_user_id` when creating orders. This maps to a persistent Truv user and carries forward across every order you create for that person. ```bash theme={null} curl --request POST \ --url https://prod.truv.com/v1/orders/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' \ --header 'Content-Type: application/json' \ --data '{ "products": ["income"], "first_name": "John", "last_name": "Doe", "external_user_id": "your-internal-user-id-1235" }' ``` When you create a second order with the same `external_user_id`, the user's previous connections are remembered. For example, if a user connected to ADP on their first order and you create a new order with the same `external_user_id`, the orders landing page will already show their ADP connection, reducing friction and improving completion rates. Always pass `external_user_id` in production. It enables user continuity and simplifies data lookups across orders. *** ## Optimize conversion ### Skip search with deeplinking If you already know the user's employer or payroll provider, pass a `company_mapping_id` when creating the order. This skips the search screen and drops users directly into the login flow, one of the highest-impact conversion improvements you can make. ```bash theme={null} curl --request POST \ --url https://prod.truv.com/v1/orders/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' \ --header 'Content-Type: application/json' \ --data '{ "products": ["income"], "first_name": "John", "last_name": "Doe", "employers": [{ "company_mapping_id": "abc123" }] }' ``` Look up `company_mapping_id` values using the [Companies API](/api-reference/companies/company_mapping). [Deeplinking guide →](/developers/integration/embedded-orders/deeplinking) ### Send follow-up reminders When a user leaves without completing verification, Truv can automatically send email and SMS reminders. Suppress notifications during the in-app session, then enable them after the user exits. ```bash theme={null} # Create order with notifications suppressed during in-app flow curl --request POST \ --url https://prod.truv.com/v1/orders/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' \ --header 'Content-Type: application/json' \ --data '{ "products": ["income"], "first_name": "John", "last_name": "Doe", "email": "john@example.com", "notification_settings": { "suppress_user_notifications": true } }' ``` After the user closes the widget without finishing, update the order to enable reminders: ```bash theme={null} curl --request PATCH \ --url https://prod.truv.com/v1/orders/{order_id}/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' \ --header 'Content-Type: application/json' \ --data '{ "notification_settings": { "suppress_user_notifications": false } }' ``` Truv sends up to 3 automatic reminders before the order expires. Order links are valid for 72 hours by default (configurable per client). [Follow-up guide →](/developers/integration/embedded-orders/follow-up) ### Refresh data without re-authentication When you need updated income or employment data for an existing user, create a data refresh order instead of asking them to reconnect. Truv reuses existing account links. The user doesn't need to do anything. ```bash theme={null} curl --request POST \ --url https://prod.truv.com/v1/refresh/tasks/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' \ --header 'Content-Type: application/json' \ --data '{ "access_token": "EXISTING_ACCESS_TOKEN", "product_type": "income" }' ``` [Data refresh guide →](/developers/integration/embedded-orders/data-refresh) *** ## User experience ### Wait for the right event Use the `COMPLETED` event with `source: "order"` before advancing the user in your application. Don't use `onSuccess` or `onClose`. The order may still have pending connections. ```javascript theme={null} onEvent: function(type, payload, source) { if (type === 'COMPLETED' && source === 'order') { navigateToNextStep(); } } ``` ### Handle errors gracefully Listen for `ERROR` events from the connection widget (`source: "bridge"`). The error payload uses the `error` object with `error_code`. See [Bridge Events](/developers/sdks/bridge-events#errors) for all codes. ```javascript theme={null} onEvent: function(type, payload, source) { if (type === 'ERROR' && source === 'bridge') { switch (payload.error.error_code) { case 'LOGIN_ERROR': // User entered wrong credentials — Bridge handles retry UI break; case 'UNAVAILABLE': showMessage('This provider is temporarily unavailable. Please try again later.'); break; } } } ``` *** ## Webhooks ### Process tasks as they complete Handle `task-status-updated` webhooks to process data as each connection finishes. Don't wait for the full order to complete. ```bash theme={null} # When you receive a task-status-updated webhook with status: done, # fetch the income report for the completed link curl --request GET \ --url https://prod.truv.com/v1/links/{link_id}/income/report/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' ``` ### Validate webhook signatures Always verify the `X-WEBHOOK-SIGN` header to confirm requests are from Truv. Use the raw request body. Never use parsed JSON. See [Webhook Security](/api-reference/security) for full verification examples in multiple languages. *** ## Security * Never expose API credentials in client-side code. Use `bridge_token` for frontend operations only. * Don't log sensitive data (SSN, income figures, account numbers) * Encrypt verification data at rest * Implement data retention policies. Don't store data longer than needed. * Validate webhook signatures on every request *** ## Monitoring Track these metrics to monitor integration health: * **Order completion rate**: percentage of orders where the user finishes at least one connection * **Average connections per order**: indicates whether users are connecting all requested accounts * **Error rates by type**: identify provider-specific or credential issues * **Webhook delivery success**: ensure you're receiving all status updates * **Time to completion**: how long users take to finish the verification flow *** ## Next steps Complete implementation walkthrough Skip employer search for higher conversion Automatic email and SMS reminders Refresh data without re-authentication # Building with AI Source: https://truv.com/docs/developers/building-with-ai Connect Claude Code, Codex, or Cursor to Truv docs via MCP for accurate API integrations Connect your AI coding tool to Truv's MCP server. It searches the docs and retrieves full page content on demand, so you get correct auth headers, status enums, and webhook handlers without pasting context manually. *** ## Connect the MCP server The Truv MCP server runs at `https://docs.truv.com/mcp`. It exposes two tools: **search** across all documentation and **retrieve** the full content of any page by path. ```bash theme={null} claude mcp add --transport http truv-api https://docs.truv.com/mcp ``` Add to `~/.codex/config.toml`: ```toml theme={null} [mcp_servers.truv-api] url = "https://docs.truv.com/mcp" ``` Add to `~/.cursor/mcp.json`: ```json theme={null} { "mcpServers": { "truv-api": { "url": "https://docs.truv.com/mcp" } } } ``` Test it by starting a new chat and asking: *"What headers does the Truv API use for authentication?"* *** ## Context files Truv publishes two static context files following the [llms.txt standard](https://llmstxt.org). Use these to seed `CLAUDE.md` / `AGENTS.md`, paste into a prompt, or as a fallback when MCP isn't available. | File | Size | Use case | | ------------------------------------------------------ | -------- | ---------------------------------------------------------------------------------- | | [`llms.txt`](https://truv.com/docs/llms.txt) | \~3.5 KB | Structured overview with links to docs sections | | [`llms-full.txt`](https://truv.com/docs/llms-full.txt) | \~18 KB | Everything inlined: auth, endpoints, schemas, enums, webhooks, sandbox credentials | * Authentication pattern (headers, base URL, SDK init) * All products and when to use each integration method * Complete integration code for Embedded Orders and User Token flows * Connection lifecycle with every status and error state * Webhook event types with example payloads and signature verification * Field-level data reference for Income & Employment, Employment, and Assets reports * Every enum value: job types, pay frequencies, deposit types, account types, income units * All API endpoints grouped by resource * Sandbox test credentials for every scenario *** ## Reference repos Clone these repos and point your AI tool at the source for working reference implementations. * [**demo-apps**](https://github.com/truvhq/demo-apps): Full-stack demo apps covering Embedded Orders, Hosted Orders, Document Processing, and more * [**quickstart**](https://github.com/truvhq/quickstart): Minimal end-to-end integration in Node.js, Python, Ruby, Go, and C# * [**demo-ios**](https://github.com/truvhq/demo-ios) / [**demo-android**](https://github.com/truvhq/demo-android) / [**demo-react-native**](https://github.com/truvhq/demo-react-native) / [**demo-flutter**](https://github.com/truvhq/demo-flutter): Mobile SDK samples *** ## What AI commonly gets wrong | What AI guesses | Correct value | | --------------------------------------------- | ---------------------------------------------------------------------------- | | `Authorization: Bearer {token}` | `X-Access-Client-Id` and `X-Access-Secret` headers | | Status: `complete`, `success`, `finished` | `done` (task statuses: `new`, `login`, `mfa`, `parse`, `full_parse`, `done`) | | Product: `voie`, `voe`, `voa` | `income`, `employment`, `assets` | | `TruvBridge.init({ bridgeToken })` for orders | Must include `isOrder: true` | | Separate sandbox URL | Same URL: `https://prod.truv.com/v1/`, credentials determine environment | | Webhook signature: raw HMAC | Format: `v1={hmac_sha256_hex}` in `X-WEBHOOK-SIGN` header | | Income amounts as numbers | Strings: `"50000.00"` | | Pay frequency: `biweekly`, `monthly` | Codes: `BW`, `M`, `SM`, `W` | *** ## Prompting tips Copy these prompts directly or adapt for your use case. ``` Build a server endpoint that creates a Truv Embedded Order for income and employment verification. Use the Truv API with X-Access-Client-Id and X-Access-Secret headers. Return the bridge_token to the frontend. Then build a frontend that initializes TruvBridge with isOrder: true and handles onSuccess, onClose, and onEvent callbacks (errors surface in onEvent with type=ERROR and an ErrorData payload -- there is no onError callback). ``` ``` Create a webhook endpoint for Truv that: 1. Verifies the X-WEBHOOK-SIGN header using HMAC-SHA256 with my API secret (format: v1={hash}) 2. Handles task-status-updated events - fetch the income report when status is "done" 3. Handles error statuses: login_error, mfa_error, account_locked, unavailable 4. Uses webhook_id for idempotency 5. Responds within 10 seconds ``` ``` Build a Deposit Switch integration using Truv's User Token flow (NOT Embedded Orders). Create a bridge token with product_type "deposit_switch" and include the target bank account details (account_number, routing_number, bank_name, account_type, deposit_type). Initialize TruvBridge WITHOUT the isOrder flag. ``` ``` Write a function that takes a Truv income verification report and extracts: - Current employer name, job title, start date, is_active status - Most recent pay statement: gross_pay, net_pay, pay_date, pay frequency - YTD income from annual_income_summary - All direct deposit bank accounts with routing numbers Use the exact field names from the Truv API docs. ``` *** ## Next steps Create your first verification in minutes Full integration walkthrough Test credentials and sandbox environment Complete endpoint documentation # Financial Accounts Source: https://truv.com/docs/developers/coverage-financial-accounts Financial institution coverage, supported account types, and data access Truv connects to 14,000+ financial institutions covering 98% of US bank accounts. A single `transactions` product connection gives access to account balances, transaction history, and liability details.
*** ## Institution coverage API Query institution coverage and success rates using the [Data Providers API](/api-reference/data-providers/providers-list). *** ## Supported account types | Type | Subtypes | | ---------------- | --------------------------------------- | | `CHECKING` | Standard checking, money market | | `SAVINGS` | Standard savings, high-yield savings | | `CREDIT_CARD` | Rewards, cashback, secured | | `LOAN` | Auto, personal, student, small business | | `LINE_OF_CREDIT` | HELOC, home equity | | `MORTGAGE` | Fixed-rate, adjustable-rate | | `INVESTMENT` | Brokerage, retirement (IRA, 401k) | | `CD` | Certificates of deposit | *** ## Implementation Create an [order](/api-reference/orders/object) with the `transactions` or `assets` product to connect a user's financial accounts. See the [Embedded Orders guide](/developers/integration/embedded-orders/overview) for a complete walkthrough. *** ## Financial accounts products Bank account balances and asset reports Account balances and auth data Transaction history and categorization Credit cards, loans, and mortgage data Risk scores derived from transaction data # Payroll Source: https://truv.com/docs/developers/coverage-payroll Payroll provider coverage, authentication methods, and Smart Login Truv connects to 93+ payroll providers covering 220M+ Americans, 96% of the US labor force, including gig income workers. Truv maps over 300,000 employers to payroll providers so users don't need to make that selection.
*** ## Provider coverage API Query provider coverage and success rates using the [Data Providers API](/api-reference/data-providers/providers-list). Search for employers and retrieve their mapped payroll provider using the [Companies API](/api-reference/companies/object). *** ## Authenticate users Truv's [Smart Login](/banking/smart-login) presents the best authentication method for each user based on employer, historical success rates, and payroll system compatibility. | Method | Description | | --------------------- | ------------------------------------------------------------------------------------------ | | Native OAuth | In-bridge redirect to payroll provider. Patented solution across the largest integrations. | | Single Sign-On (SSO) | Employee credentials via 64 SSO system integrations | | Credential-less Login | One-time passcode via trusted phone or email. Supported by ADP, Paycom. | | AppClip & Instant App | iOS AppClip and Android Instant App for employers behind VPNs | | Mapped Payroll | 300,000+ employers mapped to payroll providers automatically | | Unmapped Payroll | Provider recommendations based on historical data and employer size | *** ## Data sources The `data_source` field on links and providers identifies how data was collected. | Data source | Description | | -------------------- | ---------------------------------------------------- | | `payroll` | Direct API connection to payroll provider | | `docs` | User-uploaded documents (pay stubs, W-2s, tax forms) | | `financial_accounts` | Bank account transaction analysis | | `tax` | Tax return data | *** ## Payroll products Instant income and employment verification from payroll Multi-year employment history from payroll systems Redirect user paychecks to your bank account Automatic loan repayment from borrower paychecks # UX Customization Source: https://truv.com/docs/developers/customization Brand your verification experience across Bridge, emails, SMS, and landing pages Customization templates let you personalize the entire verification experience, from the [Truv Bridge](/developers/sdks/javascript) widget to emails, SMS messages, and landing pages. Templates are configured per product type and can be managed in the [Dashboard](https://dashboard.truv.com) under **Customization > Templates** or programmatically via the [Templates API](/api-reference/templates/object). Truv adds default templates to your account tailored to your use case and products — open and edit these to get started. Template configurations take priority over universal branding settings. Set a template as **Primary** to make it the default for its product type when creating new orders. *** ## Manage templates Truv automatically creates default templates in your account tailored to your products and use case. Adjust them in the [Dashboard](/developers/dashboard/customization#templates) or via the API below. ### API Manage templates programmatically for automated workflows. | Operation | Endpoint | Description | | --------- | -------------------------------------------------------------------------------- | ----------------------------------- | | Create | [`POST /v1/templates/`](/api-reference/templates/templates_create) | Create a new customization template | | List | [`GET /v1/templates/`](/api-reference/templates/templates_list) | List all templates | | Read | [`GET /v1/templates/{id}/`](/api-reference/templates/templates_read) | Retrieve a specific template | | Update | [`PATCH /v1/templates/{id}/`](/api-reference/templates/templates_partial_update) | Update template settings | | Delete | [`DELETE /v1/templates/{id}/`](/api-reference/templates/templates_delete) | Delete a template | Pass a `template_id` when [creating an order](/api-reference/orders/orders_create) to apply a specific template. ```bash theme={null} curl --request POST \ --url https://prod.truv.com/v1/orders/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' \ --header 'Content-Type: application/json' \ --data '{ "products": ["income"], "first_name": "John", "last_name": "Doe", "email": "john@example.com", "template_id": "a1b2c3d4e5f6" }' ``` In a [multi-tenancy](/developers/multi-tenancy) setup, each company has its own set of templates. Make sure you're editing templates in the correct company context. *** ## Settings Configure the template's core identity and order behavior. Truv Dashboard - Template settings | Field | Description | | --------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | | **Template name** | Display name for the template. Cannot be "Default". | | **Product type** | One or more verification products this template applies to | | **Set as primary template for specified product type(s)** | Preselects this template by default when creating new orders for the selected product type(s) | | **Add your end-user agreement or privacy policy** | Toggle on to show a custom agreement on the landing page and in Bridge. Requires a display text label and a URL. | | **Link expiration** | How long the verification link stays active before expiring | | **Send notifications to the end-user** | Toggle whether email and SMS notifications are sent to the applicant | | **Notifications start** | When notifications are first sent: on order creation, or 1–24 hours after | | **Customer support email address** | Support email shown to end users during verification | | **Custom field** | Toggle on to add a custom text field to orders. The value is entered when creating each order and appears in the email body and landing page. | *** ## Company branding Configure the visual identity that appears across all touchpoints. If not specified, these will be inherited from the Branding settings set at the Dashboard level. | Field | Description | | --------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | | **Logo** | Displayed in emails, verification screens, and Truv Bridge | | **Company name** | Name shown across all verification touchpoints | | **Accent color** | Used for buttons and links. A warning is shown if the selected color is too light and may impact conversion rate. | | **Background color (desktop only)** | Overlay background color shown on desktop | | **Hide confetti** | Toggle to show or hide the confetti animation on successful connection | | **Bank name** *Direct Deposit Switch, Paycheck Linked Lending* | Prefilled in emails and the landing page | | **Product name in Truv Bridge and on the landing page** *Paycheck Linked Lending* | Overrides "Auto Pay" across all Bridge screens and the landing page | *** ## Customize Bridge Template settings - Bridge search ### Search Configure the search header for each product and data source combination: | Field | Max length | Description | | ---------- | ---------- | ------------------------- | | **Header** | 34 | Search screen header text | ### Popular companies Set the list shown to users before they search: | Field | Description | | ----------------------------- | ------------------------------------------------------------------------------------------- | | **List of popular companies** | Use the default list or upload a custom CSV (company name + domain, max 15 rows) | | **List of popular providers** | Use the default list or upload a custom CSV for payroll providers or financial institutions | | **Bridge categories** | Select which provider categories are visible in Bridge. At least one must be active. | ### Document upload Configure which document types are accepted: | Field | Description | | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Document upload toggle** | Enable or disable document upload as a fallback | | **Document types** | Enable individual document types: Paystubs, W-2, 1099, 1040. For each: set mandatory/optional, minimum and maximum number of documents, and the upload button label. | ### Success screen Customize what the end user sees after a successful connection: | Field | Max length | Description | | ---------- | ---------- | -------------------------------------------------------------------------------- | | **Title** | 500 | Success screen headline | | **Body** | 500 | Supporting text. Use `{data_provider}` to display the connected provider's name. | | **Button** | 26 | Button text shown after connection | *** ## Customize the order flow Customize the communication and landing pages users see when they receive an order via [Hosted Orders](/developers/integration/hosted-orders/new-user) or [Manual Orders](/developers/integration/manual-orders/new-user). ### Email Order email customization examples Customize the emails sent to applicants. Each section has a **First email** and **Reminder email** sub-tab. Text applied to the first email can optionally be copied to the reminder. | Field | Max length | Description | | ---------------------- | ---------- | ------------------------------------- | | **Subject and header** | 2000 | Email subject line and header text | | **Body** | 2000 | Main body of the email | | **Button** | 26 | Call-to-action button text | | **Caption** | 2000 | Small text displayed below the button | ### SMS * Custom message text within a **120-character limit** * Configurable follow-up SMS timing * The `{link}` variable is required and must be included in the message | Field | Max length | Description | | -------- | ---------- | ---------------------------------------- | | **Text** | 120 | SMS message body. Must include `{link}`. | SMS reminders are only sent between 10am–6pm ET. Contact [support@truv.com](mailto:support@truv.com) to enable SMS for your account. ### Landing Pages Order page customization examples ### Initial landing page Shown before the applicant starts verification: | Field | Max length | Description | | ----------------------------------- | ---------- | ----------------------------------------- | | **Header** | 500 | Headline text on the initial landing page | | **Body** | 500 | Supporting body text | | **Hide frequently asked questions** | — | Toggle to show or hide the FAQ section | ### Success landing page Shown after a successful connection: | Field | Max length | Description | | ---------- | ---------- | ----------------------------------------- | | **Header** | 500 | Headline text on the success landing page | | **Body** | 500 | Supporting body text | ### Expired landing page Shown when the verification link has expired: | Field | Max length | Description | | ---------- | ---------- | ----------------------------------------- | | **Header** | 500 | Headline text on the expired landing page | | **Body** | 500 | Supporting body text | *** ## Dynamic text variables Use variables in emails, SMS, and landing pages to personalize messages with order-specific data. | Variable | Description | Available in | | ----------------------------- | ------------------------ | ---------------------------------- | | `{first_name}` | Recipient's first name | All channels | | `{last_name}` | Recipient's last name | All channels | | `{my_company_name}` | Your company name | All channels | | `{order_number}` | Order tracking ID | All channels | | `{link}` | Unique verification URL | Email, SMS | | `{prospective_employer_name}` | Employer name | Employment orders | | `{target_bank_name}` | Target bank name | Direct Deposit Switch (DDS) orders | | `{target_account_type}` | Target account type | DDS orders | | `{custom_field}` | Custom form input values | All channels | | `{customer_support_email}` | Your support email | All channels | *** ## Results Control what data is returned and displayed in reports. Fields vary by product type. Truv Dashboard - Template results **Income & Employment:** | Field | Description | | --------------------------------- | ------------------------------------------------------ | | **Deposit data** | Show or hide the deposit data section in the report | | **Historical pay period summary** | Show or hide the historical pay period summary section | | **Paystubs limit** | Restrict returned paystubs to the most recent 1–6 | | **W-2 years limit** | Restrict returned W-2s to the most recent 1–3 years | **Assets:** | Field | Description | | --------------------------- | ---------------------------------------------------------------------- | | **Days requested** | Number of days of transaction history to retrieve (30–730, default 60) | | **Large deposits** | Show or hide the large deposits section in the report | | **Large deposit threshold** | Minimum amount ($1–$100,000) for a deposit to be flagged as large | *** ## Next steps Full API reference for template management Apply templates when creating orders The widget you're customizing Manage templates in the Dashboard UI # Truv Dashboard Source: https://truv.com/docs/developers/dashboard Your central hub for managing verifications, teams, customization, billing, integrations and more. Truv Dashboard - orders The [Truv Dashboard](https://dashboard.truv.com) is the central management interface for your Truv account. You can create and manage verification orders, monitor activity, customize the user experience, and administer your team, all without writing any code. The Dashboard can be used as a **standalone platform**. Some teams manage their entire verification workflow through the Dashboard, though Truv is most effective when integrated in the platform your end-users and frontline team use. *** ## Dashboard sections View order summaries filtered by environment, add team members, access reporting, and see a snapshot of verification activity. Simulate the [Truv Bridge](/developers/sdks/javascript) flow with pre-configured values. Test different product types, preview the user experience, and view real-time event logs with full JSON details. Search and filter across three tabs: **Users** (end-user information), **Orders** (create and manage orders), and **Tasks** (historical data retrieval details). View Truv's data source coverage statistics: population reach and supported payroll provider and bank integrations. Create and manage [customization templates](/developers/customization) to brand Bridge, emails, SMS messages, and landing pages. Configure data field selections per product type. Manage API keys (Client ID and Access secret), view API event logs, and configure [webhook](/api-reference/webhooks/object) endpoints and notification settings. View your subscription, invoices, usage breakdown, and download monthly usage reports. Team management, [single sign-on (SSO)](/developers/sso) configuration, [multi-tenancy](/developers/multi-tenancy) company switching, and account-level settings like order expiration windows. *** ## Environments The Dashboard supports two environments. Owners and Administrators have access to toggle Sandbox mode On or Off. | Environment | Purpose | | -------------- | -------------------------------------------------------------------------------------------------------------------- | | **Sandbox** | Test with simulated data and [test credentials](/developers/testing/test-credentials). No real provider connections. | | **Production** | Live environment with real user data and production API keys. | When Sandbox mode is enabled in your Dashboard, it is enabled for all users. Once testing is complete, ensure that you have switched Sandbox mode off. Sandbox mode toggle in Truv Dashboard *** ## Team roles and permissions The Dashboard supports five roles with granular access control: | Access | Owner | Administrator | Developer | Orders Manager | Billing Manager | | --------------------------- | ----- | ------------- | --------- | -------------- | --------------- | | **Reporting** | Yes | Yes | Yes | Yes | Yes | | **Orders / Users** | Yes | Yes | Yes | Yes | No | | **Tasks** | Yes | Yes | Yes | Yes | No | | **Development** | Yes | Yes | Yes | No | No | | **Customization** | Yes | Yes | Yes | No | No | | **Customization Templates** | Yes | Yes | Yes | No | No | | **Company settings** | Yes | Yes | Yes | No | No | | **Team** | Yes | Yes | No | No | No | | **Billing** | Yes | Yes | No | No | Yes | | **Usage** | Yes | Yes | No | No | Yes | | **Support tickets** | Yes | Yes | Yes | Yes | Yes | | **Can be deleted** | No | Yes | Yes | Yes | Yes | Every company must have at least one Owner. In a [multi-tenancy](/developers/multi-tenancy) setup, members can have different roles in each company. ### Manage Team Members Navigate to **Settings > Team > Add member** and provide the member's name, email, role, and available order templates. To edit a team member's role or access, find the user in the Team Members table, click their row, and change any settings. ### Restrict access by template Truv supports controlling Order Manager access through Template assignment. If an Order Manager is assigned specific templates, they will only be able to create orders using those templates and see orders that were created using those templates. This is convenient if team members belong to specific branches or regions and need to create orders with that branding and only see orders for their team. *** ## Get started Test the full verification flow using [sandbox credentials](/developers/testing/test-credentials) before going live. Switch Sandbox mode off and run a real verification with production API keys. Go to **Settings > Team > Add member** to invite your team and assign roles. Go to **Customization > Branding** to upload your logo and set your brand colors. Explore **Customization > Templates** to configure the verification experience for each workflow. Confirm production settings, ensure Sandbox mode is off, and begin processing real verifications. Pick your vertical (Mortgage, Consumer Credit, Retail Banking, Public Sector, Screening) from the top navigation and follow the matching integration guide. # Activity Source: https://truv.com/docs/developers/dashboard/activity Search and manage users, orders, tasks, and provider coverage Search and manage every user, order, task, and provider connection across your Truv account. The Activity section has four tabs: **Users**, **Orders**, **Tasks**, and **Coverage**. *** ## Users The Users tab shows every applicant created in your company and all of their connections. Truv Dashboard - Users ### Table columns | Column | Description | | -------------------- | ------------------------------------------------------------------------------------------------------- | | **Name** | Applicant's full name | | **Created at** | Date the user record was created | | **Updated at** | Date the user record was last updated | | **User ID** | System-generated unique identifier for the user | | **External user ID** | Your system's identifier for the applicant, passed at user creation | | **Email** | Applicant's email address | | **Phone number** | Applicant's phone number | | **SSN** | Applicant's Social Security Number | | **Product type** | The verification product(s) associated with this user's connections | | **Accounts (links)** | The data provider(s) the user has connected to | | **Data source** | The type of data source used (payroll, financial accounts, document upload, etc.) | | **Status** | Outcome status of the user's connection attempts | | **Suspicious** | Flags users where the SSN doesn't match the provider, or uploaded documents may contain fraudulent data | ### Search and filters | Name | Description | | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | | **Search** | Search by name, email, phone, user ID, external user ID, or link ID | | **Date period** | Filter by when the user was created. Presets: Last 24 hours, Last 7 days, This week, Last 30 days (default), Last 90 days, or a custom date range | | **Product type** | Filter by the verification product associated with the user's connections | | **Data provider** | Filter by the specific provider the user connected to | | **Attempts** | Filter by users with attempts, users without attempts, or all users | ### Open a user Click any user to see all reports returned across their links. Reports can be downloaded as PDFs or viewed in the Dashboard UI. Paystubs and W-2s can be downloaded directly from the report view. Additional connection details or errors can be reviewed under the Connections tab. Truv Dashboard - User detail *** ## Orders The Orders tab shows every Truv verification order in your account. Truv Dashboard - Orders ### Table columns | Column | Description | | ------------------------- | -------------------------------------------------------------------------------------------------------- | | **Name** | Applicant's full name | | **Email** | Applicant's email address. Shows a warning if email delivery failed. | | **Phone number** | Applicant's phone number. Shows a warning if SMS delivery failed. | | **Created at** | Date the order was created | | **Refreshed at** | Date a data refresh was completed on this order | | **Source** | Where the order originated (Dashboard, API, Encompass, etc.) | | **Created by** | Name of the order manager who created the order | | **Created by email** | Email of the order manager who created the order | | **Template ID** | ID of the template applied to this order | | **Template name** | Name of the template applied to this order | | **Loan number** | Loan number associated with this order | | **Tracking number** | Internal tracking number for the order | | **Loan processor name** | Name of the loan processor from the loan object | | **Loan processor email** | Email of the loan processor from the loan object | | **Loan originator name** | Name of the loan originator from the loan object | | **Loan originator email** | Email of the loan originator from the loan object | | **Custom field** | Custom field value specified during order creation | | **AIM check report ID** | Report ID for an AIM Check (Freddie Mac) verification | | **VOA report ID** | Report ID for a Verification of Assets report | | **VOIE report ID** | Report ID for a Verification of Income and Employment report | | **User ID** | ID of the applicant user associated with this order | | **Order ID** | Unique identifier for this order | | **Refresh order ID** | ID of the refresh order, if a refresh has been initiated | | **Order link** | Shareable verification link sent to the applicant | | **Status updates** | Email addresses receiving status update notifications for this order | | **External user ID** | Your system's identifier for the applicant | | **Product type** | The verification product(s) requested for this order | | **Data source** | The data source used to complete the verification | | **Provider** | The specific provider the applicant connected to | | **Status** | Current order status (completed, pending, expired, canceled, etc.) | | **Was attempted** | Whether the applicant opened the verification link and attempted to connect | | **Suspicious** | Flags orders where the SSN doesn't match the provider, or uploaded documents may contain fraudulent data | | **Notes** | Internal notes added to the order | Column customization is per-user and does not affect other team members' views. ### Search and filters | Name | Description | | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- | | **Search** | Search by name, email, phone, employer, order ID, report ID, loan number, tracking number, or custom field | | **Date period** | Filter by when the order was created. Presets: Last 24 hours, Last 7 days, This week, Last 30 days (default), Last 90 days, or a custom date range | | **Status** | Filter by order status: Done, Pending, Expired, Canceled, Error, Skipped by user, or No data | | **Product type** | Filter by the verification product requested for the order | | **Source** | Filter by where the order originated: Dashboard, API, Encompass, and other integrated platforms | | **Order type** | Filter between All orders, Initial orders, or Refresh orders | | **Order managers** | Filter by the team member who created the order. Supports multi-select with search. | ### Open an order Click any order to see all associated reports. Reports can be downloaded as PDFs or viewed in the Dashboard UI. Paystubs, W-2s, and order invoices can be downloaded directly from the report view. End-user interaction can be viewed in the timeline and additional connection details or errors can be reviewed under the Connections tab. A new refresh order can also be triggered from the top right. Truv Dashboard - Order detail ### Create an order Create order in Truv Dashboard Go to [dashboard.truv.com](https://dashboard.truv.com) and sign in. Navigate to **Activity > Orders** and click **Create Order**. Provide the applicant's name, email, and last 4 digits of their SSN. Choose Income & Employment, Employment, or Assets. Deliver the link to your applicant via email or SMS. The applicant connects through Truv Bridge. Open the order to view the report, download a PDF, or export as needed. Configure [webhooks](/api-reference/webhooks/object) to receive automatic notifications when an order completes, then fetch the data via API to sync results to your LOS or internal tools. ### Export Click **Export CSV** to download the current table with all active filters and selected columns applied. *** ## Tasks The Tasks tab is the most granular view. Every time an applicant attempted to connect to a provider, it appears as a unique task row. Truv Dashboard - Tasks ### Table columns | Column | Description | | ----------------- | ------------------------------------------------------------------------------------------------------- | | **Created at** | Date and time the connection attempt was made | | **Data source** | The type of data source used (payroll, financial accounts, document upload, etc.) | | **Data provider** | The specific provider the applicant attempted to connect to | | **Task ID** | Unique identifier for this connection attempt | | **Link ID** | ID of the link (account connection) this task belongs to | | **Status** | Outcome of the connection attempt (done, login error, MFA error, etc.) | | **Suspicious** | Flags tasks where the SSN doesn't match the provider, or uploaded documents may contain fraudulent data | | **Product type** | The verification product associated with this task | | **Tracking info** | Tracking identifier passed through from the order or bridge token | | **Bridge token** | The bridge token used to initialize this connection attempt | | **User ID** | ID of the applicant user associated with this task | ### Search and filters | Name | Description | | ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | | **Search** | Search by task ID, link ID, user ID, order ID, bridge token, or tracking info | | **Date period** | Filter by when the task was created. Presets: Last 24 hours, Last 7 days, This week, Last 30 days (default), Last 90 days, or a custom date range | | **Status** | Filter by task outcome: Done, Error, Login Error, Account Locked, MFA Error, Config Error, No Data, Unavailable, Unable to Reset, or Not Supported | | **Product type** | Filter by the verification product associated with the task | | **Data provider** | Filter by the specific provider the applicant attempted to connect to | ### Open a task Click any task row to open the task detail. The detail view shows: | Field | Description | | ---------------------- | ----------------------------------------------------------------- | | **ID** | Unique identifier for this task | | **Created** | Timestamp when the connection attempt was initiated | | **Last updated** | Timestamp when the task was last updated | | **Provider** | The data provider the applicant attempted to connect to | | **Environment** | Sandbox or Production | | **Status** | Outcome of the connection attempt (e.g., Done, Login error) | | **User ID** | Links to the associated user record | | **Link ID** | ID of the link this task belongs to | | **Link is suspicious** | Whether the link was flagged for potential fraud | | **Bridge token** | The bridge token used to initialize this connection | | **Error message** | Details about any error that occurred during the attempt | | **Tracking info** | Tracking identifier passed through from the order or bridge token | | **Product type** | The verification product associated with this task | | **Logs** | Link to view raw connection logs for debugging | Truv Dashboard - Task detail ### Export Like Users and Orders, the Tasks table can be exported as a CSV with all active filters and columns applied. *** ## Coverage The Coverage tab shows Truv's provider coverage across four product categories: * **Payroll** * **Insurance** * **Financial Accounts** * **Scoring Attributes** Truv Dashboard - Coverage ### Provider search In the Payroll and Financial Accounts categories, search for a specific employer, payroll provider, or financial institution to see: * Whether the provider is covered by Truv * The historical connection success rate for that provider Truv Dashboard - Coverage search Each result displays a success rate indicator. The icon shown reflects Truv's historical connection data for that provider:
Icon Rating Payroll Financial accounts
High Expected to succeed, send the verification order. Expected to succeed, send the verification order.
Low May succeed, send if the user knows their payroll provider and is confident. May succeed, send if the user is confident and knows their login credentials.
Unsupported Verification via payroll is not feasible. Try Truv's Document Upload solution or the next step in your waterfall as an alternative. Verification with this financial institution is not supported, use an alternative method.
Unknown Not enough attempts to determine success. May succeed if the user knows their payroll provider and it's supported by Truv. Not enough attempts to determine success. Likely to succeed based on other financial institutions.
*** ## Next steps Manage orders programmatically via the API Retrieve task details and statuses Full payroll provider coverage list Full financial institution coverage list # Billing Source: https://truv.com/docs/developers/dashboard/billing View your subscription, invoices, and usage data View your subscription, track invoices, monitor credits, and break down usage in the Billing section. It has four tabs: **Subscription**, **Invoices**, **Credits**, and **Usage**. *** ## Subscription The Subscription tab shows your current active plan and enabled products. Truv Dashboard - Subscription * Plan name and enabled product details * Billing cycle and price per billable unit (task, report, or loan, depending on your contract) *** ## Invoices The Invoices tab lists all invoices issued to your account. Truv Dashboard - Invoices For each invoice you can: * View invoice details including date, amount, invoice number, due date, and status * Open a direct link to the invoice * Pay outstanding invoices *** ## Credits The Credits tab is visible when your account has a credit balance. It shows how credits are being consumed over time. All dates in the Credits tab are displayed in UTC. ### Summary | Metric | Description | | -------------------- | ------------------------------------------------------ | | **Starting balance** | Credit balance at the beginning of the selected period | | **Ending balance** | Credit balance at the end of the selected period | | **Total usage** | Total credits consumed during the selected period | ### Charts Two line charts visualize credit activity over the selected date range: * **Usage** — daily credit consumption * **Credits balance** — daily ending balance Use the **date period** filter to adjust the range (up to 365 days). *** ## Usage The Usage tab shows a detailed breakdown of all usage in your account, mapped to your billable unit. Truv Dashboard - Usage * The view adjusts to reflect whether your contract bills per **task**, **report**, or **loan** * Filter by **date range** to see usage for a specific billing period * Click **Export CSV** to download usage data for reconciliation against your invoice # Customization Source: https://truv.com/docs/developers/dashboard/customization Control branding, order defaults, templates, and API response fields Brand your verification experience, configure order-level defaults, manage templates, and control which fields your API responses return. The Customization section has four areas: **Branding**, **Order Settings**, **Templates**, and **Data**. *** ## Branding Set your company's visual identity for all verification experiences. Truv Dashboard - Branding Branding settings apply globally across your account as defaults. Template-level branding takes precedence when a template is applied to an order. | Setting | Description | | -------------------- | ------------------------------------------------------------------------------------------------------------- | | **Company logo** | Displayed in emails, verification screens, and Truv Bridge. PNG or JPG under 2 MB. Circular logo recommended. | | **Company name** | Displayed in verification communications | | **Accent color** | Primary color in the verification UI | | **Background color** | Background overlay color for the verification UI (desktop only) | | **Hide confetti** | Show or hide the confetti animation on successful connection | Click **Preview** to see your branding in the Emulator before saving, or **Apply** to save changes. *** ## Order Settings Configure account-wide defaults applied to all orders unless overridden at the template level. Truv Dashboard - Order settings | Setting | Description | | --------------------------------------- | ---------------------------------------------------------------------------------------- | | **End-user agreement / privacy policy** | Toggle on to add a URL to all verification experiences | | **Link expiration** | How long verification links stay active before expiring (e.g. 3 days) | | **Customer support email** | Support email address shown to end users during verification | | **Custom field** | Enforces a required custom data field (e.g. loan number) on all orders | | **Custom phone number** | Send SMS notifications from a specific authenticated phone number via Twilio integration | *** ## Templates Create and manage templates to apply distinct customizations to individual workflows or clients. Truv Dashboard - Templates Templates give fine-grained control over branding, the end-user experience, and returned data for individual workflows. Select a template when creating an order to apply its full configuration. Templates also control **order manager access** — a team member assigned to a specific template can only create orders with that template and can only view orders using it. This makes templates an effective tool for branch-level access control. See the full [UX Customization guide](/developers/customization) for detailed configuration options for each template section. *** ## Data Control which fields are included in API responses for each product type. Truv Dashboard - Data Select a product type to view its full API response schema. Each field group (Profile, Employer, Employment, Income, Pay statements, Earnings, etc.) can be expanded to show individual fields. Uncheck any field to exclude it from all API responses when a connection is completed using that product type. This is useful for limiting data returned to only what your application needs. *** ## Next steps Full template configuration reference Full configuration reference for templates # Development Source: https://truv.com/docs/developers/dashboard/development Manage API keys, view logs, and configure webhooks for your Truv integration Authenticate, debug, and extend your Truv integration from one place — manage API keys, inspect request logs, and configure webhooks. The Development section has three tabs: **API Keys**, **Logs**, and **Webhooks**. *** ## API Keys The API Keys tab is where you find and manage your Truv credentials. Truv Dashboard - API Keys ### Client ID Your **Client ID** is displayed at the top of the page. Pass it as the `X-Access-Client-Id` header on all API requests. ### Keys table The table shows all API keys for your account, grouped by environment (Sandbox, Development, Production): | Column | Description | | ---------------- | ------------------------------------------------ | | **Environment** | Sandbox, Development, or Production | | **Created date** | When the key was generated | | **Secret** | Masked except for the last four characters | | **Last used** | Most recent API call authenticated with this key | #### Actions * **Reveal** — Show the full key value on screen * **Copy** — Copy to clipboard without revealing * **Delete** — Permanently remove the key (irreversible) * **Generate new key** — Create a new key for an environment You cannot have more than **two active keys per environment**. Deleting a key is permanent and immediately revokes authentication for any system using it. ### Rotate API keys To rotate keys without downtime: 1. Generate a new key 2. Update your integration to use the new key 3. Test to confirm the new key works 4. Delete the old key only after confirming the new key is live See [API Keys Rotation](/api-reference/authentication) for the full rotation guide. *** ## Logs The Logs tab shows a record of all API requests associated with your account. Truv Dashboard - Logs ### Filters | Filter | Description | | -------------- | ----------------------------------------- | | **Date range** | Narrow to a specific time window | | **Status** | HTTP response status: 200, 400, 500, etc. | | **Brand** | Filter by a specific sub-company or brand | Use Logs to debug integration issues, trace specific requests, and understand API traffic patterns. *** ## Webhooks The Webhooks tab lets you configure endpoints where Truv sends event notifications. Truv Dashboard - Webhooks ### Create a webhook | Field | Description | | --------------- | ------------------------------------------------- | | **Name** | A label to identify this webhook | | **URL** | The HTTPS endpoint where Truv sends POST requests | | **Environment** | Production, Development, or Sandbox | | **Events** | The event types that trigger this webhook | Always validate the `X-WEBHOOK-SIGN` header before processing any webhook payload. See [Webhook Security](/api-reference/security#webhook-signature-verification). See [Webhook Events](/api-reference/webhook-events) for the full list of supported event types and payload schemas, and [Webhooks](/api-reference/webhooks/object) for delivery best practices — 10-second timeout, retry behavior, and idempotency guidance. *** ## Next steps API authentication reference Full list of webhook event types Step-by-step key rotation guide Webhook signature verification # Emulator Source: https://truv.com/docs/developers/dashboard/emulator Preview and test the Truv verification experience as the end-user using different products and flows. Walk through the end-user verification experience with simulated conditions — preview templates, test workflows, and demo the Bridge flow before shipping. *** ## Configure the emulator Emulator allows you to explore the end-user experience using different Products, Solutions, Templates, as well as routing to a specific Company or Payroll provider. Truv Dashboard - Emulator | Option | Description | | ------------------------- | ------------------------------------------------------------------------------------------------------- | | **Product type** | Income & Employment, Assets, etc. | | **Solution** | Payroll only, or include fallback workflows (document upload, financial accounts, etc.) | | **Template** | Preview how your branding and [template configuration](/developers/dashboard/customization) will appear | | **Company / Provider ID** | Optionally specify a company or provider to open that connection directly | *** ## Explore the verification flow Once configured, click any company in the search results and use one of our [login test credentials](/developers/testing/test-credentials#login-scenarios) to begin the simulated login experience. In Sandbox mode, the emulator lets you test every solution: * Payroll connections * Financial accounts * Document processing (paystubs, W-2s, tax returns) * Smart routing, Choice Connect, and fallback workflow behavior As you click through the experience, login events and their corresponding JSON payloads are loaded in real time. Once a connection is complete, the returned report can be viewed in the UI, as a JSON payload, or downloaded via PDF. Truv Dashboard - Emulator report *** ## Common use cases * **Training demos** — Walk a client through the borrower experience before go-live, with their branding applied via a template * **Template QA** — Validate that branding, copy, and search categories are configured correctly * **Workflow testing** — Reproduce specific fallback or error scenarios in a controlled environment *** ## Next steps Use sandbox credentials to simulate different outcomes Configure the template shown in the emulator # Home Source: https://truv.com/docs/developers/dashboard/home Monitor verification performance and team activity from your reporting dashboard Monitor verification activity and team performance in real time. Home opens on login with two tabs: **Reporting** and **Team Performance**. *** ## Reporting The Reporting tab shows performance metrics for all verifications in the selected period. Truv Dashboard - Reporting ### Filters Use the filter bar to slice the data: | Filter | Description | | ----------------------- | --------------------------------------------------------------------------- | | **Date** | Select a date range for the reporting period | | **Companies** | Filter by sub-company in a [multi-tenancy](/developers/multi-tenancy) setup | | **Product type** | Income & Employment, Assets, etc. | | **Data source** | Payroll, Document Upload, Financial Accounts, etc. | | **Initial vs. Refresh** | Toggle between initial and refresh orders | | **Source** | Dashboard, API, Encompass, or other platforms | | **Template** | Filter by a specific [customization template](/developers/customization) | | **Orders vs. Embedded** | Compare hosted order performance vs. Bridge embedded implementations | ### Charts and tables | Chart | What it shows | | ----------------------------------- | -------------------------------------------------------------------------------------------------------- | | **Total order volume** | Total orders created in the selected period | | **Conversion rate graph** | Created orders and conversion rate over time | | **Status breakdown** | Distribution by status: completed, expired, canceled, etc. | | **Order turnaround time** | Time from creation to completion, broken down by notification method (Email & SMS, Email only, SMS only) | | **Funnel** | Step-by-step breakdown of where users drop off in the verification flow | | **Error distribution** | Incomplete orders broken down by error type | | **Benchmark** | Your conversion rate compared to industry benchmarks | | **Volume & conversion by template** | Order count, completions, and conversion rate per template | ### Export Click **Export CSV** in the top-right corner of any chart to download the underlying data. ### Notifications The bell icon in the top navigation shows in-app notifications in three categories: * **Order updates** — Order completed, canceled, expired, or moved to another terminal status * **Team updates** — A team member requires approval to access the account * **API updates** — A new API key was issued or rotated In addition to opening notifications through the bell icon, notifications will automatically appear as a tile in the Dashboard. To edit notification preferences, see the [Settings](/developers/dashboard/settings) tab. *** ## Team Performance The Team Performance tab shows orders created and conversion rate broken down by individual team members. * Filter by template to see per-template performance for each member * Export the table as a CSV *** ## Next steps View individual users, orders, and tasks Configure templates to brand your experience # Settings Source: https://truv.com/docs/developers/dashboard/settings Configure company details, manage your team, and control notification preferences Configure your company, manage team members, and control notification preferences across four tabs: **Company**, **Team**, **Profile**, and **Notifications**. *** ## Company Truv Dashboard - Company settings | Field | Description | | ------------------------ | ------------------------------------------------------------------------------- | | **Company name** | Name displayed in the Dashboard | | **Website** | Your company's website URL | | **Billing email** | Email address for billing communications | | **Status updates email** | Email address for receiving order status notifications | | **Show / hide API keys** | Control whether API keys are visible to team members in the Development section | *** ## Team The Team tab shows all members in your Truv Dashboard account. Truv Dashboard - Team ### Table columns | Column | Description | | ----------------------- | -------------------------------------------------------------------------------- | | **Name** | Team member's full name | | **Email** | Team member's email address | | **Created at** | Date the member was added | | **Role** | Assigned role (Owner, Administrator, Developer, Orders Manager, Billing Manager) | | **Status** | Current membership status (see [Member statuses](#member-statuses) below) | | **Available templates** | Templates the member has access to | | **Actions** | Actions available per member (see [Member actions](#member-actions) below) | ### Member statuses | Status | Description | | ------------------------ | ------------------------------ | | **Active** | Accepted invite, full access | | **Invited** | Email sent, pending acceptance | | **Waiting for approval** | Signed up, not yet approved | | **Declined** | Access denied | | **Invite expired** | Link expired before acceptance | | **Invitation error** | Invite send failed | | **Deactivated** | Account deactivated | ### Member actions | Action | When available | | ---------------------------- | --------------------------------- | | **Edit** | Always — change role or templates | | **Approve / Decline member** | For members waiting for approval | | **Revoke access** | For active members | | **Grant access** | For declined members | | **Resend invite** | When invite has expired | | **Delete** | For declined or expired members | ### Search and filters | Name | Description | | ------------- | ------------------------------------------------------------------------------------------ | | **Search** | Search by name or email across members of the selected status | | **Status** | Filter by invite status: All members, Approved, Invited, Waiting for approval, or Declined | | **Templates** | Filter by assigned template. Supports multi-select with search. | | **Roles** | Filter by role. Supports multi-select. | Click **Export CSV** to download the current member list. ### Add a member Click **Add Member** and provide: * First name, last name, and email address * Role to assign * Available templates — if the member has the Orders Manager role and you want to restrict their access to specific templates, select the templates here. If none are selected, they can access all templates. Truv Dashboard - Add member The member receives an email with a link to set their password. After setting a password or logging in via Google, Microsoft, or SSO, they are automatically approved. ### Roles See the [full role access matrix](/developers/dashboard#team-roles-and-permissions). In a [multi-tenancy](/developers/multi-tenancy) setup, team members can have different roles in each company. *** ## Profile The Profile tab shows your personal account information. Truv Dashboard - Profile | Field | Description | | -------------- | -------------------------------------------------- | | **First name** | Your first name (editable) | | **Last name** | Your last name (editable) | | **Email** | Your login email address (read-only) | | **Role** | Your assigned role (read-only, visible for Owners) | Click **Save** to apply any changes. *** ## Notifications The Notifications tab controls which notifications you receive and how. Truv Dashboard - Notifications ### Delivery methods For each notification type, toggle delivery via **Email** or **Dashboard** (in-app bell), or both. Deselecting a method stops delivery through that channel. If enabled, a notification feed tile will briefly appear on the Dashboard when a notification is triggered. This can be disabled by unchecking **Show notification popups**. ### Notification types | Notification | Trigger | | ------------------------------------ | ------------------------------------------------------------------------------------------------------------ | | **Order updates** | Get notified when an order you created or were added to completes, expires, or gets updated in any other way | | **Automatically created orders** | Get notified when an order is created in Encompass via ASO and your role is a recipient | | **Refreshes requiring reconnection** | Get notified when a refreshed order requires the end-user to reconnect their accounts | | **Members pending approval** | Get notified when a team member joins the Truv Dashboard and requires approval | | **Production keys** | Get notified when a production API key is issued or rotated | *** ## Next steps Set up single sign-on for your team Manage multiple companies # Support Source: https://truv.com/docs/developers/dashboard/support Submit and track support tickets with the Truv team Submit and track support tickets with the Truv team. Log in with your Truv credentials to access the support portal. Truv Dashboard - Support *** ## What you can do * **View open tickets** — See all active support requests for your account. Click a ticket to see responses from support and reply to the thread. * **Filter by scope** — View tickets submitted by yourself or across your entire organization. Search tickets by Subject or ID. * **Export tickets** — Download ticket data as a CSV * **Submit new tickets** — Create a new support request directly from the portal *** ## Get help Browse FAQs and how-to articles Reach the Truv support team directly # Application Demo Source: https://truv.com/docs/developers/demos/application Verify income, employment, or assets through Embedded Orders The Application demo shows the most common integration pattern: collect applicant info, search for their employer, and verify income, employment, or assets through Bridge in a single session. **Integration pattern:** [Embedded Orders](/developers/integration/embedded-orders/overview) | **Products:** VOIE, VOE, VOA ```bash theme={null} git clone https://github.com/truvhq/demo-apps.git cd demo-apps && npm install && cp .env.example .env # Add your API_CLIENT_ID, API_SECRET, and NGROK_URL to .env npm start # Express server on :3000 npm run dev # Vite dev server on :5173 — select "Application" ``` See [Demo Apps overview](/developers/quickstarts-overview#demo-apps) for full setup details including ngrok configuration. ## Flow Enter applicant PII (name, SSN, email). The app searches for the employer using the [Company Search API](/api-reference/companies/company_autocomplete_search) and creates an [Order](/api-reference/orders/orders_create). Truv Bridge opens inline. The applicant selects their employer, logs in, and connects their account. Sandbox credentials: `goodlogin` / `goodpassword` Truv sends `task-status-updated` and `order-status-updated` webhooks as verification progresses. The right panel shows payloads in real time. Once `status: done`, fetch structured verification reports via the Reports API. ## Use cases | If you're building… | Products | | -------------------------------------------- | --------------------------- | | Mortgage origination (purchase, refi, HELOC) | Income (VOIE), Assets (VOA) | | Consumer lending (auto, personal, BNPL) | Income (VOIE), Assets (VOA) | | Benefits eligibility (SNAP, Medicaid, TANF) | Income (VOIE), Assets (VOA) | | Background screening | Employment (VOE) | *** ## Next steps Handle co-borrowers and multi-product verification Full implementation guide for the Embedded Orders pattern Create and manage verification orders All sandbox login scenarios # Consumer Credit Demo Source: https://truv.com/docs/developers/demos/consumer-credit Bundle income, deposit switch, and payroll-linked lending in one session The Consumer Credit demo shows the Bridge Widget flow. It creates a user and bridge token directly, without orders. This is the pattern for deposit switching and payroll-linked lending. **Integration pattern:** [Bridge Widget](/developers/integration/bridge-widget/overview) | **Products:** DDS, PLL, VOIE ```bash theme={null} git clone https://github.com/truvhq/demo-apps.git cd demo-apps && npm install && cp .env.example .env # Add your API_CLIENT_ID, API_SECRET, and NGROK_URL to .env npm start # Express server on :3000 npm run dev # Vite dev server on :5173 — select "Consumer Credit" ``` See [Demo Apps overview](/developers/quickstarts-overview#demo-apps) for full setup details including ngrok configuration. ## Flow Choose the product type (income, deposit switch, or PLL). The backend creates a user and generates a bridge token. ``` POST /v1/users/ POST /v1/users/{id}/tokens/ ``` Bridge opens as a popup. The user selects their employer and logs in. On success, Bridge returns a `public_token` that gets exchanged for an access token. Sandbox credentials: `goodlogin` / `goodpassword` Exchange the public token for a link report: ``` POST /v1/link-access-tokens/ GET /v1/links/{link_id}/{product}/report ``` ## Use cases | If you're building… | Products | | ---------------------------------------- | ---------------------------- | | Account funding / direct deposit capture | Deposit Switch (DDS) | | Earned wage access or loan repayment | Payroll-Linked Lending (PLL) | | Income verification without orders | Income (VOIE) | *** ## Next steps Full DDS integration guide Full PLL integration guide Client-side event types and error codes DDS and PLL implementation guidelines # Document Processing Demo Source: https://truv.com/docs/developers/demos/document-processing Upload pay stubs and tax returns, extract structured data The Document Processing demo shows how to upload documents, validate them, and extract structured income and employment data, without Truv Bridge or payroll connections. **Integration pattern:** [Document Processing](/developers/integration/document-processing) | **Products:** Document extraction (pay stubs, W-2s, 1099s, 1040s) ```bash theme={null} git clone https://github.com/truvhq/demo-apps.git cd demo-apps && npm install && cp .env.example .env # Add your API_CLIENT_ID, API_SECRET, and NGROK_URL to .env npm start # Express server on :3000 npm run dev # Vite dev server on :5173 — select "Document Processing" ``` See [Demo Apps overview](/developers/quickstarts-overview#demo-apps) for full setup details including ngrok configuration. ## Flow Retrieve an existing `user_id` or create a new user. Save the returned `id` for subsequent steps. ``` GET /v1/users/ POST /v1/users/ ``` Select files and upload them. The app creates a document collection and uploads each file. ``` POST /v1/documents/collections/ POST /v1/documents/collections/{id}/upload/ ``` Truv validates each document: * `is_valid`: recognized document type * `is_readable`: text is extractable * `document_type`: paystub, w2, 1099, etc. Poll the collection status until all documents are processed. Once validated, finalize the collection to extract structured data. ``` POST /v1/documents/collections/{id}/finalize/ ``` Fetch the extracted data: employer name, pay period, gross/net pay, tax withholdings, and more. ``` GET /v1/documents/collections/{id}/finalize/ ``` ## Test documents Use the sample PDFs from [Test Documents](/developers/testing/test-documents). The sandbox determines results based on file name, not file content. # Follow-up Demo Source: https://truv.com/docs/developers/demos/follow-up Create multiple verification tasks for one applicant The Follow-up demo shows how to handle co-borrowers or multi-product verification by creating multiple orders tied to the same applicant using a shared `external_user_id`. **Integration pattern:** [Embedded Orders](/developers/integration/embedded-orders/overview) (multi-task) | **Products:** VOIE, VOE, VOA ```bash theme={null} git clone https://github.com/truvhq/demo-apps.git cd demo-apps && npm install && cp .env.example .env # Add your API_CLIENT_ID, API_SECRET, and NGROK_URL to .env npm start # Express server on :3000 npm run dev # Vite dev server on :5173 — select "Follow-up" ``` See [Demo Apps overview](/developers/quickstarts-overview#demo-apps) for full setup details including ngrok configuration. ## Flow Create multiple orders for the same applicant. Each order targets a different employer or product. Orders share an `external_user_id` to link them in your system. The applicant completes Bridge for each order. Each connection triggers its own webhook chain. Process webhooks for each order independently. Aggregate results across all connections for a complete picture. Fetch reports per order. Combine income from multiple employers for total income calculation. ## Use cases | If you're building… | Products | | ---------------------------------------- | -------------------------- | | Co-borrower mortgage verification | Income, Employment, Assets | | Multi-employer income aggregation | Income (VOIE) | | Full employment history across providers | Employment (VOE) | *** ## Next steps Refresh income data at recertification Add additional employers to an existing order Configure notifications and reminders Listen for verification events # Verifier Portal Demo Source: https://truv.com/docs/developers/demos/verifier-portal Send verification links via email/SMS, no user present The Verifier Portal demo shows the Hosted Orders pattern. Create orders server-side and send verification links to applicants via email or SMS. The applicant completes Bridge on their own device. **Integration pattern:** [Hosted Orders](/developers/integration/hosted-orders/new-user) | **Products:** VOIE, VOE ```bash theme={null} git clone https://github.com/truvhq/demo-apps.git cd demo-apps && npm install && cp .env.example .env # Add your API_CLIENT_ID, API_SECRET, and NGROK_URL to .env npm start # Express server on :3000 npm run dev # Vite dev server on :5173 — select "Verifier Portal" ``` See [Demo Apps overview](/developers/quickstarts-overview#demo-apps) for full setup details including ngrok configuration. ## Flow Create a verification order with applicant PII. Truv sends the share link via email/SMS. ``` POST /v1/orders/ { "first_name": "...", "email": "...", "phone": "...", "products": ["income"] } ``` The applicant receives an email/SMS with a verification link. They complete Bridge on their own device. Monitor webhooks for status updates. Once the applicant completes verification, fetch reports via the Reports API. ## Use cases | If you're building… | Products | | ------------------------------------------- | ------------------------------- | | Loan processor or caseworker portal | Income (VOIE), Employment (VOE) | | Background screening / pre-employment | Employment (VOE) | | Benefits eligibility (no applicant present) | Income (VOIE) | *** ## Next steps Full implementation guide for Hosted Orders Create orders from the Dashboard without code Manage orders, view results, and configure settings All sandbox login scenarios # Fraud Detection & Manual Review Source: https://truv.com/docs/developers/fraud-and-manual-review How to interpret the is_suspicious flag, detect document fraud, and handle manual review scenarios Truv provides two layers of protection when processing verifications: an `is_suspicious` flag on verification reports and detailed error detection for document uploads. Understanding when and how to act on each is critical for maintaining data integrity without creating unnecessary friction. *** ## Detect document upload fraud For document processing (pay stubs, W-2s, tax forms), Truv runs every uploaded document through fraud detection trained on 50M+ verified pay stubs. When fraud or data issues are detected, the connection status is set to `config_error` or `no_data`. ### Detecting fraud in document uploads When a document upload task completes with a `config_error` status, fetch the task record to get the specific error message: ```bash theme={null} curl --request GET \ --url 'https://prod.truv.com/v1/tasks/?order_id=ORDER_ID' \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' ``` Check the `error_message` field on each task in the response. The `error_message` field on the task record provides the specific reason for the failure. ### config\_error messages These indicate issues with the uploaded documents that require action. Some are fraud-related, others are validation failures. | error\_message | Description | | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | | `Possible tampering detected` | The document appears to have been altered or modified from its original form. **This is the strongest fraud signal.** Route to your fraud review team. | | error\_message | Description | | --------------------------------------------------------------- | --------------------------------------------------------------------- | | `The documents contain different full names` | Full names across uploaded documents don't match each other | | `The documents contain different company names` | Employer names across uploaded documents don't match each other | | `The documents contain different SSN's` | SSNs across uploaded documents don't match each other | | `The applicant first name mismatched with one in the documents` | The applicant's first name from the order doesn't match the documents | | `The applicant last name mismatched with one in the documents` | The applicant's last name from the order doesn't match the documents | | `SSN mismatch in application and data` | The SSN from the order doesn't match the SSN in the documents | These errors only occur for documents uploaded through the Truv Bridge experience. For document collections, the same issues are caught up front by the validation check at upload time (see [Monitor processing status](/developers/integration/document-processing#step-4-monitor-processing-status)) and never reach this `config_error` path. | error\_message | Description | | --------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ | | `Please upload documents without password protection or encryption.` | The file is password-protected or encrypted. Re-upload an unprotected version. | | `File type not supported. Please ensure each uploaded file matches the requested document type.` | Unsupported file format. Accepted formats include PDF and common image types. | | `Some documents have mismatched type or subtype: '{filename}' has '{type}' type, expected '{type}'` | A paystub was uploaded when a W-2 was expected, or vice versa | ### no\_data messages These indicate the documents were processed but didn't contain enough information to complete the verification. | error\_message | Description | | ---------------------------------------------------------------------------------- | --------------------------------------------------------- | | `Not enough data to complete the task` | Documents didn't contain sufficient information | | `No employment dates are available` | Employment dates couldn't be found in the documents | | `No saved employments found` | No employment records found in the documents | | `The connected account does not have required data` | The account doesn't contain the needed data | | `No paystubs or W-2s found for the most recent employment` | No recent income documents found for the current employer | | `Required data not found in the source` | Required verification data couldn't be located | | `No statements found for employment` | No income statements found for the reported employment | | `Most recent company does not have address` | Employer address couldn't be determined | | `Empty annual income summary data for {year}` | No annual income summary for the specified year | | `Task {task_id}. Profile validation failed: first_name and last_name are required` | Applicant name wasn't provided. Required for processing. | *** ## Manual Review with is\_suspicious Flag Every income and employment verification report includes an `is_suspicious` boolean field. When `true`, it signals that something in the returned data warrants a closer look. It **does not necessarily indicate fraud**. ### Two-tier fraud detection Truv uses a two-tier detection system. The tier determines whether the task completes with data or fails entirely. | Tier | Behavior | `is_suspicious` | Task status | Data returned | When it triggers | | ---------- | ---------------------------- | --------------- | -------------- | ------------- | -------------------------------------------------------------------------------------------------------------- | | **Tier 1** | Task completes, data flagged | `true` | `completed` | Yes | Data anomalies detected but document is processable (e.g., SSN mismatch, name mismatch, minor inconsistencies) | | **Tier 2** | Task fails, no data returned | N/A | `config_error` | No | Document is too suspicious to process (e.g., confirmed tampering, known fraud template match) | Tier 1 flags require manual review but still return data. Tier 2 blocks the verification entirely because the document cannot be trusted. Check the task `error_message` for Tier 2 failures. ### Common triggers | Scenario | What happened | Tier | Recommended action | | ------------------------ | --------------------------------------------------------------------------------- | ---- | ---------------------------------------------------------------------------------- | | **Name mismatch** | The order was for John Doe, but his spouse Jane Doe connected her payroll account | 1 | Manual review. Verify the correct person connected. | | **SSN mismatch** | The SSN on the order doesn't match the SSN returned from the payroll provider | 1 | Manual review. Confirm identity with the applicant. | | **Employer mismatch** | The applicant's reported employer doesn't match the connected payroll account | 1 | Manual review. The applicant may have changed jobs or connected the wrong account. | | **Document tampering** | Uploaded document metadata or content shows signs of alteration | 2 | Route to fraud team. No data is returned. | | **Known fraud template** | Document matches a known fraudulent template pattern | 2 | Route to fraud team. No data is returned. | ### Detection indicators Truv's fraud detection engine, trained on 50M+ verified pay stubs, analyzes documents across multiple dimensions. Every uploaded document carries metadata that reveals its creation and editing history. Truv inspects PDF producer fields, creation timestamps, and modification history to detect documents that were generated or altered using manipulation tools rather than produced by a legitimate payroll system. Truv maintains a library of known fraudulent document templates. Uploaded documents are compared against these patterns to catch documents created from widely circulated fraud kits or template generators. Documents edited with PDF manipulation software leave distinct artifacts. Truv detects these fingerprints, including font substitution, layer inconsistencies, and editing tool signatures that differ from legitimate payroll-generated documents. Pay stubs "printed to PDF" from a browser rather than exported from a payroll system have different structural characteristics. While not always fraudulent, browser-generated PDFs bypass the payroll system's native export and are flagged for review. Truv validates that pay dates, pay period start and end dates, and year-to-date totals are internally consistent. Mismatched dates, impossible pay periods, or YTD totals that don't align with pay frequency are flagged. When multiple documents are uploaded (e.g., several pay stubs or a pay stub plus a W-2), Truv cross-references them for consistency. Inconsistencies trigger Tier 1 flags or Tier 2 failures depending on severity: | Check | Flag | | ------------------------------------------ | ----------------------------------------------- | | Different SSNs across documents | `The documents contain different SSN's` | | Different company names across documents | `The documents contain different company names` | | Different applicant names across documents | `The documents contain different full names` | Individual fields within a document are validated against each other. Truv checks that gross pay, deductions, and net pay are arithmetically consistent, that tax withholdings are within plausible ranges for the stated income, and that employer identification numbers (EINs) match known formats. ### How to handle each tier #### Tier 1: `is_suspicious = true` The `is_suspicious` flag appears in the response body when you fetch a verification report: ```json theme={null} { "id": "24d7e80942ce4ad58a93f70ce4115f5c", "status": "completed", "is_suspicious": true, "employers": [...] } ``` When `is_suspicious` is `true`: 1. **Do not auto-reject.** The flag is a signal for manual review, not an automatic denial. 2. **Compare the order details against the returned data.** Check names, SSN, and employer information. 3. **Contact the applicant if needed.** In many cases, the mismatch has a simple explanation (e.g., a spouse connected instead of the applicant). Treating `is_suspicious: true` as an automatic rejection will create false positives. Always route these to manual review rather than declining outright. #### Tier 2: Task fails with `config_error` When a document is too suspicious to process, the task fails with status `config_error` and no verification data is returned. Fetch the task record to get the specific `error_message`. See [Detect document upload fraud](#detect-document-upload-fraud) for all error messages and recommended actions. ### SSN mismatch detection When you create an order with the applicant's SSN, Truv automatically compares it against the SSN returned from the payroll provider or extracted from uploaded documents. This is a backend validation -- there is no front-end control or configuration. | Scenario | Source of truth | Comparison target | Result | | ----------------------------------- | ---------------- | ---------------------------------------- | --------------------------------------------- | | **Payroll connection** | SSN on the order | SSN from the payroll provider's records | `is_suspicious: true` if mismatch | | **Document upload (single doc)** | SSN on the order | SSN extracted from the uploaded document | `SSN mismatch in application and data` error | | **Document upload (multiple docs)** | Each document | Other uploaded documents | `The documents contain different SSN's` error | SSN matching runs automatically on every verification where an SSN is provided on the order. You cannot disable or configure this behavior. If no SSN is provided on the order, cross-matching against the payroll provider is skipped, but cross-document SSN consistency checks still run for document uploads. For payroll connections, an SSN mismatch sets `is_suspicious: true` on the report (Tier 1). The verification still completes with data, but you should route the result to manual review before accepting it. For document uploads, SSN mismatches produce `config_error` task failures with specific error messages listed in the [Identity mismatches](#detect-document-upload-fraud) section below. *** ## Recommended review workflow ```mermaid theme={null} %%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#EBF0FD', 'primaryBorderColor': '#2C64E3', 'primaryTextColor': '#111827', 'lineColor': '#9CA3AF', 'tertiaryColor': '#FFFFFF', 'edgeLabelBackground': '#FFFFFF'}}}%% flowchart TD A[Verification completes] --> B{Check status} B -->|completed| C{is_suspicious?} B -->|config_error| D[Fetch task details] B -->|no_data| E[Fetch task details] C -->|false| F[Auto-approve or proceed] C -->|true| G[Route to manual review] D --> H{error_message?} H -->|Possible tampering detected| I[Route to fraud team] H -->|Identity mismatch| G H -->|File issue| J[Request re-upload] E --> K[Request additional documents] ``` ### Priority levels | Signal | Priority | Action | | -------------------------------------------- | ------------------ | -------------------------------------------------- | | `Possible tampering detected` | **High: Fraud** | Escalate to fraud review team immediately | | Identity mismatches (names, SSN across docs) | **Medium: Review** | Manual review to determine if intentional or error | | `is_suspicious: true` on payroll connection | **Medium: Review** | Compare order details against returned data | | File issues (encrypted, wrong type) | **Low: Resubmit** | Ask applicant to re-upload correct documents | | `no_data` errors | **Low: Resubmit** | Request additional or different documents | *** ## Test fraud scenarios Truv provides test documents in sandbox mode to simulate fraud detection. See [Test Documents](/developers/testing/test-documents) for downloadable files including: * **Tampered documents**: triggers `Possible tampering detected` * **Different SSNs**: triggers SSN mismatch errors * **Different applicant names**: triggers name mismatch errors * **No data / invalid data**: triggers `no_data` scenarios *** ## Next steps Implementation guide for document uploads Test fraud detection with sample documents All connection statuses and error states Client-side event reference for error handling and fallback routing # Welcome Source: https://truv.com/docs/developers/home Start here to integrate Truv into your application Truv provides instant verification of income, employment, and assets through direct connections to payroll providers and financial institutions. You integrate once and get structured, source-verified data back via API and webhooks. ## New to Truv? Run the [Quickstart](/developers/quickstart) to see a complete integration working in minutes. Then pick a [Demo App](/developers/quickstarts-overview#demo-apps) that matches your use case and use it as your starting point. Quickstart, demo apps, and use case guides *** ## Industry guides If you're building for a specific vertical, start with the industry tab for tailored product recommendations and integration paths. VOIE, VOA, VOE with GSE certification and LOS/POS integrations Benefits eligibility verification for SNAP, Medicaid, TANF Income and asset verification for auto loans, personal loans, credit Direct deposit switching and paycheck-linked lending *** ## Choose your integration method **Recommended for most use cases.** Create an order with applicant details, launch Truv Bridge in your app, and let the user connect their accounts. Supports income, employment, and asset verification. **For deposit switching and paycheck-linked lending.** Create a user and bridge token directly. No orders needed. The user connects their payroll account through Bridge. **No frontend required.** Create an order via API or Dashboard and Truv sends the verification link to the user via email or SMS. They complete Bridge on their own device. **No code at all.** Create and manage orders through the Truv Dashboard UI or CSV bulk upload. Ideal for low-volume or pilot workflows. **No Bridge needed.** Upload pay stubs, W-2s, and tax returns directly. Truv extracts structured income and employment data automatically. *** ## Understand the platform Before building, familiarize yourself with the core concepts that apply to every integration. How Orders, Users, Links, and Tasks relate to each other Processing stages, timing, and what data is available when API keys, base URL, and environment routing Real-time notifications for task and order status changes Client-side callbacks during the user connection flow *** ## Get help Complete endpoint documentation with schemas Test credentials, sample documents, and sandbox setup SOC 2, GLBA, data protection, and trust center [support@truv.com](mailto:support@truv.com) # Deeplinking Source: https://truv.com/docs/developers/integration/bridge-widget/deeplinking Pre-fill account information in Bridge Widget flows to skip search steps Pre-fill employer or provider information when creating a bridge token to bypass the search screens. Use this for DDS and PLL flows where you already know the user's employer or provider. For Embedded Orders deeplinking (VOIE, VOE, VOA), see [Deeplinking for Embedded Orders](/developers/integration/embedded-orders/deeplinking). ```mermaid theme={null} %%{init: {'theme': 'base', 'themeVariables': {'actorBkg': '#2C64E3', 'actorBorder': '#1E4BB8', 'actorTextColor': '#FFFFFF', 'signalColor': '#9CA3AF', 'signalTextColor': '#111827', 'noteBkgColor': '#EBF0FD', 'noteBorderColor': '#5A8AEF'}}}%% sequenceDiagram participant Server as Your Server participant API as Truv API participant Bridge as Truv Bridge Server->>API: Search company mapping API-->>Server: company_mapping_id Server->>API: Create bridge token with company_mapping_id API-->>Server: bridge_token Note over Bridge: User skips search screens Bridge->>Bridge: User lands on login page ``` *** ## Deeplink by employer Use this when you know the user's employer name. Truv maps the employer to the correct payroll provider automatically. ### Find the company mapping ```bash theme={null} curl --request GET \ --url 'https://prod.truv.com/v1/company-mappings-search/?query=Facebook' \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' ``` ```json theme={null} [ { "company_mapping_id": "48427a36d43c4d5aa6324bc06c692456", "name": "Facebook", // ... } ] ``` ### Create a bridge token with the mapping Pass the `company_mapping_id` when creating the bridge token. ```bash theme={null} curl --request POST \ --url https://prod.truv.com/v1/users/USER_ID/tokens/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' \ --header 'Content-Type: application/json' \ --data '{ "product_type": "deposit_switch", "company_mapping_id": "48427a36d43c4d5aa6324bc06c692456" }' ``` The user skips the employer search screen and lands directly on the provider login page. *** ## Deeplink by provider Use this when you know the specific payroll provider (e.g. ADP, Workday, Gusto) but not the specific employer. ```bash theme={null} curl --request POST \ --url https://prod.truv.com/v1/bridge-tokens/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' \ --header 'Content-Type: application/json' \ --data '{ "product_type": "deposit_switch", "provider_id": "adp", "user": { "id": "99dd17074ac94aa9ace2621d657c7610" } }' ``` All providers from the [List all data providers endpoint](/api-reference/data-providers/providers-list) are supported as deeplink targets. *** ## Next steps Find `company_mapping_id` by employer name All supported `provider_id` values Create bridge tokens with deeplink parameters Deeplinking for VOIE, VOE, and VOA flows # New User Source: https://truv.com/docs/developers/integration/bridge-widget/new-user Direct API integration for Deposit Switch and Paycheck Linked Lending Bridge Widget flow provides direct control over payroll connections, specifically designed for Deposit Switch and Paycheck Linked Lending use cases. **Bridge Widget is only for Deposit Switch and Paycheck Linked Lending.** For Income & Employment, Assets, or Employment verification, use [Embedded Orders](/developers/integration/embedded-orders/overview) instead. *** ## When to Use Bridge Widget ```mermaid theme={null} %%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#EBF0FD', 'primaryBorderColor': '#2C64E3', 'primaryTextColor': '#111827', 'lineColor': '#9CA3AF', 'tertiaryColor': '#FFFFFF', 'edgeLabelBackground': '#FFFFFF'}}}%% graph TD A[What are you building?] --> B{Use case?} B -->|Mortgage / Consumer Credit| C[Use Embedded Orders] B -->|Tenant Screening| C B -->|Government / Social Services| C B -->|Deposit Switch| D[Use Bridge Widget] B -->|Paycheck Linked Lending| D ``` | Use Case | Recommended Method | | ----------------------- | ------------------ | | Deposit Switch | **Bridge Widget** | | Paycheck Linked Lending | **Bridge Widget** | | Income & Employment | Embedded Orders | | Assets | Embedded Orders | | Employment | Embedded Orders | *** ## Token flow The Widget-only flow uses a three-token exchange to securely connect users: ```text theme={null} bridge_token → public_token → access_token ``` | Token | Created By | Lifetime | Purpose | | -------------- | ------------------------ | ----------- | ------------------------------------ | | `bridge_token` | Your server (via API) | 6 hours | Initialize Truv Bridge on the client | | `public_token` | Truv Bridge (on success) | Short-lived | Temporary token for exchange | | `access_token` | Token exchange (via API) | Persistent | Configure DDS/PLL and retrieve data | *** ## Implementation ### Step 1: Create a user \[Server-side] Create a user to associate with this connection. ```bash theme={null} curl --request POST \ --url https://prod.truv.com/v1/users/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' \ --header 'Content-Type: application/json' \ --data '{ "external_user_id": "your-internal-user-id", "first_name": "John", "last_name": "Doe" }' ``` Save the `id` from the response to use in the next step. ### Step 2: Create a bridge token \[Server-side] Create a bridge token with the user ID and your product configuration. Pass the `account` details for the destination bank account. ```bash theme={null} curl --request POST \ --url https://prod.truv.com/v1/users/USER_ID/tokens/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' \ --header 'Content-Type: application/json' \ --data '{ "product_type": "deposit_switch", "allowed_products": ["deposit_switch"], "account": { "account_number": "151251215", "account_type": "checking", "routing_number": "12027471412", "bank_name": "AcmeBank" } }' ``` ```bash theme={null} curl --request POST \ --url https://prod.truv.com/v1/users/USER_ID/tokens/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' \ --header 'Content-Type: application/json' \ --data '{ "product_type": "pll", "account": { "action": "create", "account_type": "savings", "bank_name": "Acme Bank", "routing_number": "12345678219", "account_number": "16002622100", "deposit_type": "amount", "deposit_value": "50.00" } }' ``` ### Step 3: Initialize Bridge Widget \[Client-side] Pass the `bridge_token` to Truv Bridge. When the user connects successfully, Bridge returns a `public_token` via the `onSuccess` callback. ```html theme={null} ``` See [Bridge Events](/developers/sdks/bridge-events) for all callback events, error codes, and payload shapes. ### Step 4: Exchange token and retrieve data \[Server-side] Exchange the `public_token` for a persistent `access_token`: ```bash theme={null} curl --request POST \ --url https://prod.truv.com/v1/link-access-tokens/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' \ --header 'Content-Type: application/json' \ --data '{ "public_token": "PUBLIC_TOKEN_FROM_BRIDGE" }' ``` Store the returned `access_token` securely. Use it to fetch data and manage the connection. *** ## Webhooks Listen for these server-side [webhook events](/api-reference/webhook-events) to track connection status: * `task-status-updated` with `status: done` — task completed successfully * `task-status-updated` with error statuses — connection failed (see [Task lifecycle](/api-reference/tasks/lifecycle)) See [Webhook Events](/api-reference/webhook-events) for the full event reference. *** ## Best practices * Always wait for `task-status-updated` webhook with `status: done` before treating a connection as complete * Handle errors with user-friendly messaging * Store `link_id` and `access_token` for future reference [View best practices guide →](/developers/best-practices/bridge-token) *** ## Next steps Direct Deposit Switch integration for Retail Banking Complete Paycheck Linked Lending setup guide Client-side event types and error codes Widget-only implementation guidelines # Bridge Widget Overview Source: https://truv.com/docs/developers/integration/bridge-widget/overview The client-side widget for secure account connections Widget - income verification Truv Bridge is a drop-in client-side widget that handles the entire account connection flow: employer/bank search, credential entry, multi-factor authentication, and error handling. You embed it in your frontend; Truv manages the UI. Bridge is used in two ways: | Integration | Use case | How Bridge gets a token | | ------------------------------------------------------------------- | ------------------------------------------------------------------------------ | --------------------------------------- | | [Embedded Orders](/developers/integration/embedded-orders/overview) | Income, employment, assets (multi-connection) | Order API returns `bridge_token` | | [Bridge Widget](/developers/integration/bridge-widget/new-user) | Direct Deposit Switch (DDS), Paycheck Linked Lending (PLL) (single connection) | Bridge Token API returns `bridge_token` | *** ## Platform support | Platform | Package | | ---------------- | ----------------------------------------------- | | **Web** | ` ``` *** ## Parameters | Parameter | Required | Description | | ------------- | -------- | ----------------------------------------------------------------------------------------------------- | | `bridgeToken` | Yes | The `bridge_token` value returned by [Create Bridge Token](/api-reference/bridge-token/users_tokens). | | `position` | No | Display mode configuration. Default is `dialog`. See [Set the position](#set-the-position). | *** ## Set the position The `position` parameter controls how Bridge renders on the page. Bridge: Dialog mode vs. Inline mode ### Dialog (default) Bridge opens as a centered overlay and disables page scrolling. ```javascript theme={null} const bridge = TruvBridge.init({ bridgeToken: bridgeToken, position: { type: 'dialog' }, // callbacks... }); ``` ### Inline Bridge embeds inside an existing DOM element. Use this for seamless page layouts. ```javascript theme={null} const container = document.getElementById('bridge-container'); const bridge = TruvBridge.init({ bridgeToken: bridgeToken, position: { type: 'inline', container: container }, // callbacks... }); ``` Inline mode requires the container element to exist in the DOM before calling `TruvBridge.init`. *** ## Close Bridge programmatically Call `bridge.close()` to dismiss the widget from your code. ```javascript theme={null} const bridge = TruvBridge.init({ bridgeToken: bridgeToken, // callbacks... }); // Close the widget after a timeout or user action bridge.close(); ``` *** ## Callbacks | Callback | When it fires | | ----------- | --------------------------------------- | | `onSuccess` | User successfully connected an account | | `onLoad` | Bridge widget finished loading | | `onClose` | User closed the widget | | `onEvent` | Any interaction event, including errors | Errors surface through `onEvent` with `type=ERROR` and an [`ErrorData`](/developers/sdks/bridge-events#errordata) payload — there is no separate `onError` callback. See [Bridge events](/developers/sdks/bridge-events) for the full list of event types and payloads. *** ## Customize the widget Customize Bridge appearance through [Customization Templates](/developers/customization) in the Dashboard: company branding, search experience, success pages, document upload settings, and privacy agreements. *** ## Next steps Multi-connection verification (VOIE, VOA, VOE) Single-connection flow (DDS, PLL) Bundle income, deposit switch, and PLL in one Bridge session Platform-specific installation guides # Returning User Source: https://truv.com/docs/developers/integration/bridge-widget/returning-user Re-authenticate expired connections and refresh data When a user's session expires or they change credentials, data refresh requests return `login_error` or `mfa_error`. Use Bridge update mode to prompt the user to re-authenticate their existing connection. ```mermaid theme={null} %%{init: {'theme': 'base', 'themeVariables': {'actorBkg': '#2C64E3', 'actorBorder': '#1E4BB8', 'actorTextColor': '#FFFFFF', 'signalColor': '#9CA3AF', 'signalTextColor': '#111827', 'noteBkgColor': '#EBF0FD', 'noteBorderColor': '#5A8AEF'}}}%% sequenceDiagram participant Server as Your Server participant API as Truv API participant App as Your App participant Bridge as Truv Bridge Server->>API: Data refresh request API-->>Server: login_error / mfa_error Server->>API: Create bridge token (with access_token) API-->>Server: bridge_token Server->>App: Pass bridge_token App->>Bridge: TruvBridge.init() + open() Bridge->>Bridge: User re-authenticates Bridge-->>App: onSuccess API-->>Server: Webhook (task-status-updated, done) Server->>API: Retrieve updated data ``` *** ## When to use | Issue | Description | Refresh status | | ------------------- | ----------------------------------------------- | -------------- | | Changed credentials | User updated their username or password | `login_error` | | MFA required | Session expired, provider requires new MFA code | `mfa_error` | *** ## Re-authenticate \[Server-side] Create a new bridge token using the `access_token` from the original connection. This puts Bridge in update mode. The user re-enters credentials without going through employer search. ```bash theme={null} curl --request POST \ --url https://prod.truv.com/v1/users/USER_ID/tokens/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' \ --header 'Content-Type: application/json' \ --data '{ "product_type": "income", "access_token": "48427a36d43c4d5aa6324bc06c692456" }' ``` ```json theme={null} { "bridge_token": "2f67984a110747d190c39e1022c81837" } ``` ## Re-authenticate with Bridge \[Client-side] ```html theme={null} ``` *** ## Retrieve updated data \[Server-side] After successful re-authentication, retrieve the refreshed data. ```bash theme={null} curl --request GET \ --url https://prod.truv.com/v1/links/d8a8945ee2b049b193110cfba643f5df/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' \ --header 'Accept: application/json' ``` *** ## Next steps Refresh data without re-authentication Understand connection statuses Create bridge tokens Client-side events and error codes # Document Processing Implementation Source: https://truv.com/docs/developers/integration/document-processing Step-by-step guide to uploading, processing, and verifying borrower documents via the Truv API Document Processing uses a collection-based workflow: you create a container, upload files, monitor validation and AI classification, finalize, then retrieve the same income/employment report you'd get from a live payroll connection. *** ## Step 1: Identify or Create a User Retrieve an existing `user_id` or create a new user. If AIM Check will be used, ensure at least the last 4 digits of the SSN are included during user creation. **Find an existing user:** ```bash theme={null} curl -X GET https://prod.truv.com/v1/users/ \ -H "X-Access-Client-Id: YOUR_TRUV_CLIENT_ID" \ -H "X-Access-Secret: YOUR_TRUV_CLIENT_SECRET" \ -H "Content-Type: application/json" ``` **Or create a new user:** ```bash theme={null} curl -X POST https://prod.truv.com/v1/users/ \ -H "X-Access-Client-Id: YOUR_TRUV_CLIENT_ID" \ -H "X-Access-Secret: YOUR_TRUV_CLIENT_SECRET" \ -H "Content-Type: application/json" \ -d '{ "external_user_id": "your-internal-id", "first_name": "John", "last_name": "Doe", "ssn": "1234" }' ``` Save the returned `id`. You'll need it in subsequent steps. *** ## Step 2: Create a Document Collection Initialize the collection and upload documents in a single call. Files must be Base64-encoded. ```bash theme={null} curl -X POST https://prod.truv.com/v1/documents/collections/ \ -H "X-Access-Client-Id: YOUR_TRUV_CLIENT_ID" \ -H "X-Access-Secret: YOUR_TRUV_CLIENT_SECRET" \ -H "Content-Type: application/json" \ -d '{ "documents": [ { "mime_type": "application/pdf", "filename": "most-recent-paystub.pdf", "content": "{{base64_encoded_file}}", "user_id": "{{user_id}}" }, { "mime_type": "application/pdf", "filename": "prior-paystub.pdf", "content": "{{base64_encoded_file}}", "user_id": "{{user_id}}" } ] }' ``` The response includes a `collection_id`. Save this for all subsequent calls. *** ## Step 3: Add Files Incrementally (Optional) For save-and-resume workflows, add more files after the initial collection is created: ```bash theme={null} curl -X POST https://prod.truv.com/v1/documents/collections/{collection_id}/upload/ \ -H "X-Access-Client-Id: YOUR_TRUV_CLIENT_ID" \ -H "X-Access-Secret: YOUR_TRUV_CLIENT_SECRET" \ -H "Content-Type: application/json" \ -d '{ "documents": [ { "mime_type": "application/pdf", "filename": "w2-2023.pdf", "content": "{{base64_encoded_file}}", "user_id": "{{user_id}}" } ] }' ``` *** ## Step 4: Monitor Processing Status Document processing is asynchronous. Poll the collection until all documents show `status: successful`. ```bash theme={null} curl -X GET https://prod.truv.com/v1/documents/collections/{collection_id}/ \ -H "X-Access-Client-Id: YOUR_TRUV_CLIENT_ID" \ -H "X-Access-Secret: YOUR_TRUV_CLIENT_SECRET" \ -H "Content-Type: application/json" ``` The response has two sections: **`uploaded_files`**: File-level validations: | Field | Description | | ------------------- | ------------------------------------------------- | | `is_valid` | Overall validity | | `is_unique` | Not a duplicate of another file in the collection | | `is_readable` | File can be opened and parsed | | `is_accessible` | File is not password-protected | | `is_viable_size` | File is within size limits | | `is_supported_type` | MIME type is supported | **`documents`**: AI-extracted document records with `document_type`, borrower name, and page range. **Example response:** ```json theme={null} { "collection_id": "f1f63754e72a44b4805a4d16380cd833", "uploaded_files": [ { "file_id": "9efadd7fb43c4598b02fe79bd7e31fd7", "filename": "most-recent-paystub.pdf", "validations": { "is_valid": true, "is_unique": true, "is_readable": true, "is_accessible": true, "is_viable_size": true, "is_supported_type": true }, "status": "successful", "user_id": "c87e695081704310b15d59ee1640b1aa" } ], "documents": [ { "document_id": "b1091a2ddc5d428c9c8af66dbc8b0556", "file_id": "9efadd7fb43c4598b02fe79bd7e31fd7", "document_type": "PAYSTUB", "status": "successful", "first_name": "John", "last_name": "Doe", "start_page": 1, "end_page": 1 } ] } ``` *** ## Step 5: Finalize the Collection Once documents are validated, finalize to trigger report generation. **Use all uploaded documents:** ```bash theme={null} curl -X POST https://prod.truv.com/v1/documents/collections/{collection_id}/finalize/ \ -H "X-Access-Client-Id: YOUR_TRUV_CLIENT_ID" \ -H "X-Access-Secret: YOUR_TRUV_CLIENT_SECRET" \ -H "Content-Type: application/json" \ -d '{ "product_type": "income" }' ``` **Or select specific documents:** ```bash theme={null} curl -X POST https://prod.truv.com/v1/documents/collections/{collection_id}/finalize/ \ -H "X-Access-Client-Id: YOUR_TRUV_CLIENT_ID" \ -H "X-Access-Secret: YOUR_TRUV_CLIENT_SECRET" \ -H "Content-Type: application/json" \ -d '{ "document_ids": [ "b1091a2ddc5d428c9c8af66dbc8b0556", "1cbb5f9bb6f345059af491917179c80b" ], "product_type": "income" }' ``` The response includes a `link_id` for each user: ```json theme={null} { "users": [ { "id": "21ae68826be042e5ab410e531dc40889", "links": [ { "link_id": "1995e2fc5e374beb955ae81276294815", "status": "new", "documents": [ { "id": "ad568bb5c117439e9c00df738052c653", "document_type": "PAYSTUB" }, { "id": "769014511ed748d0a650a73759d06127", "document_type": "PAYSTUB" } ] } ] } ] } ``` Save the `link_id`. *** ## Step 6: Retrieve Verified Data Truv processes the Link asynchronously. Wait for the Task to complete before fetching the report. **Recommended: Listen for a webhook** Wait for a `task-status-updated` webhook with `status: done` and the matching `link_id`, then fetch the report. **Alternative: Poll finalization status** ```bash theme={null} curl -X GET https://prod.truv.com/v1/documents/collections/{collection_id}/finalize/ \ -H "X-Access-Client-Id: YOUR_TRUV_CLIENT_ID" \ -H "X-Access-Secret: YOUR_TRUV_CLIENT_SECRET" \ -H "Content-Type: application/json" ``` **Fetch the report:** ```bash theme={null} curl -X GET https://prod.truv.com/v1/links/{link_id}/income/report/ \ -H "X-Access-Client-Id: YOUR_TRUV_CLIENT_ID" \ -H "X-Access-Secret: YOUR_TRUV_CLIENT_SECRET" \ -H "Content-Type: application/json" ``` ```bash theme={null} curl -X GET https://prod.truv.com/v1/links/{link_id}/employment/report/ \ -H "X-Access-Client-Id: YOUR_TRUV_CLIENT_ID" \ -H "X-Access-Secret: YOUR_TRUV_CLIENT_SECRET" \ -H "Content-Type: application/json" ``` The report schema is identical to a live payroll connection. *** ## Supported document types | Document Type | Description | | ------------- | --------------------------------- | | `PAYSTUB` | Pay statements / pay stubs | | `W2` | W-2 wage and tax statements | | `1099-DIV` | Dividends and distributions | | `1099-G` | Government payments | | `1099-INT` | Interest income | | `1099-MISC` | Miscellaneous income | | `1099-NEC` | Nonemployee compensation | | `1099-R` | Retirement distributions | | `SSA-1099` | Social Security benefit statement | | `1040` | Individual income tax return | ### Additional document types Truv also recognizes these supplementary document types for classification: | Document | Type code | | ----------------------- | ------------------------ | | Bank statements | `BANK_STATEMENT` | | Driver's licenses | `DRIVER_LICENSE` | | Passports | `PASSPORT` | | Green cards | `GREEN_CARD` | | Utility bills | `UTILITY_BILL` | | Lease agreements | `LEASE_AGREEMENT` | | Home insurance policies | `INSURANCE_HOME_POLICY` | | Auto insurance policies | `INSURANCE_AUTO_POLICY` | | Letters of verification | `LETTER_OF_VERIFICATION` | | Volunteer letters | `VOLUNTEER_LETTER` | For sandbox testing, use the [test documents](/developers/testing/test-documents) -- the sandbox uses file names to determine results rather than actual file contents. *** ## API Reference Initialize a document collection Add files to an existing collection Check validation and AI classification status Trigger report generation *** ## Next steps Sample PDFs for sandbox testing Interpret income and employment data from reports Set up notifications for processing completion Upload pay stubs, W-2s, and tax returns. See structured data extraction in action. # Add Employer Source: https://truv.com/docs/developers/integration/embedded-orders/add-employer Add a new employer to an existing order after it has been created Add a new employer to an existing order when additional employment connections are needed after the order was originally created. The order must not be expired or canceled. ```mermaid theme={null} %%{init: {'theme': 'base', 'themeVariables': {'actorBkg': '#2C64E3', 'actorBorder': '#1E4BB8', 'actorTextColor': '#FFFFFF', 'signalColor': '#9CA3AF', 'signalTextColor': '#111827', 'noteBkgColor': '#EBF0FD', 'noteBorderColor': '#5A8AEF'}}}%% sequenceDiagram participant Server as Your Server participant API as Truv API participant Bridge as Truv Bridge Server->>API: Add employer (POST /v1/orders/{id}/employers/) API-->>Server: New employer added to order API->>Bridge: User receives notification Bridge->>Bridge: User connects new employer API-->>Server: Webhook (task-status-updated, done) ``` *** ## When to use | Scenario | Example | | ------------------- | ---------------------------------------------------------------- | | Missing employer | User disclosed an additional employer after initial verification | | Seasonal employment | User has a second job that wasn't initially included | *** ## Add an employer \[Server-side] Send a `POST` request to the order's `/employers/` endpoint with the employer details. ```bash theme={null} curl --request POST \ --url https://prod.truv.com/v1/orders/39aa1486ccca4bc19cda071ffc1ba392/employers/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' \ --header 'Content-Type: application/json' \ --data '{ "company_name": "Facebook Demo", "company_domain": "facebook.com", "start_date": "2019-08-24", "company_address": { "street": "1 Hacker Way", "city": "Menlo Park", "state": "CA", "zip": "94025" } }' ``` ### Request fields | Field | Type | Required | Description | | ----------------- | ------ | -------- | ------------------------------------------------------ | | `company_name` | string | No | Employer name | | `company_domain` | string | No | Company website domain | | `start_date` | date | No | Job start date (YYYY-MM-DD) | | `end_date` | date | No | Job end date (YYYY-MM-DD) | | `suborder_number` | string | No | Your external ID for tracking | | `company_address` | object | No | Employer address with `street`, `city`, `state`, `zip` | The order must be in an active state, not expired or canceled. Check the order status before adding employers. *** ## What happens next After adding the employer, Truv extends the order to include the new employer. The user receives a notification (if configured) to connect their additional employer through Bridge. Listen for `task-status-updated` webhooks to know when the new employer's data is ready. *** ## Next steps Pull updated data without user re-authentication Re-engage users who didn't finish verification Let users review and confirm retrieved data # Data Refresh Source: https://truv.com/docs/developers/integration/embedded-orders/data-refresh Refresh verification data from a completed order without requiring the user to reconnect Create a data refresh order to pull updated income, employment, or asset data from an existing order's connections. The user does not need to re-authenticate. Truv reuses the existing account links. Data refresh works only when the original account connections are still active. If a connection has expired or the user changed their credentials, use [Bridge Update Mode](/developers/integration/bridge-widget/returning-user) to re-authenticate. ```mermaid theme={null} %%{init: {'theme': 'base', 'themeVariables': {'actorBkg': '#2C64E3', 'actorBorder': '#1E4BB8', 'actorTextColor': '#FFFFFF', 'signalColor': '#9CA3AF', 'signalTextColor': '#111827', 'noteBkgColor': '#EBF0FD', 'noteBorderColor': '#5A8AEF'}}}%% sequenceDiagram participant Server as Your Server participant API as Truv API Server->>API: Create refresh order (POST /v1/orders/{id}/) API-->>Server: New order_id Note over API: Truv pulls fresh data from existing connections API-->>Server: Webhook (task-status-updated, done) Server->>API: Retrieve refreshed order (GET /v1/orders/{new_id}/) API-->>Server: Updated employer data, reports ``` *** ## Refresh vs new order | | Data Refresh | New Order | | --------------- | ------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | | **User action** | None. Truv reuses existing connections. | User must reconnect through Bridge | | **When to use** | Data is stale but connections are still active | Original connections expired, credentials changed, or new employer | | **Limits** | 3 refreshes per access\_token per 24 hours; 5 re-verifications within 90 days for GSE | No limit | | **Cost** | Free for GSE orders (up to 5 within 90 days) | Standard pricing | | **MFA** | Fails if provider requires MFA. User must reconnect. | User handles MFA during connection | *** ## When to use | Scenario | Example | | ----------------- | -------------------------------------------------------- | | Stale data | Original verification is older than your policy window | | Updated pay stubs | Need the most recent pay period before closing | | Re-verification | Underwriting requires a fresh pull before final approval | | Monitoring | Periodic income checks on active loans | *** ## Create a data refresh order \[Server-side] Send a `POST` request to the original order's endpoint. Specify which `products` to refresh and optionally which `employers` or `financial_accounts` to include. ```bash theme={null} curl --request POST \ --url https://prod.truv.com/v1/orders/39aa1486ccca4bc19cda071ffc1ba392/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' \ --header 'Content-Type: application/json' \ --data '{ "products": ["income"] }' ``` ```bash theme={null} curl --request POST \ --url https://prod.truv.com/v1/orders/39aa1486ccca4bc19cda071ffc1ba392/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' \ --header 'Content-Type: application/json' \ --data '{ "products": ["assets"] }' ``` ```bash theme={null} curl --request POST \ --url https://prod.truv.com/v1/orders/39aa1486ccca4bc19cda071ffc1ba392/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' \ --header 'Content-Type: application/json' \ --data '{ "products": ["income"], "employers": [ { "id": "ad9f14440d624ec3b0f66e81e44518c7" } ] }' ``` ```bash theme={null} curl --request POST \ --url https://prod.truv.com/v1/orders/39aa1486ccca4bc19cda071ffc1ba392/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' \ --header 'Content-Type: application/json' \ --data '{ "products": ["employment"] }' ``` ### Request fields | Field | Type | Description | | -------------------- | ----- | --------------------------------------------------------------------------------------------------------------- | | `products` | array | Product to refresh: `income`, `employment`, `assets`, `insurance`, or `transactions`. One product per request. | | `employers` | array | Employers to include. Each object takes `id` or `suborder_number` from the original order. Omit to refresh all. | | `financial_accounts` | array | Financial accounts to include. Each object takes `id` or `suborder_number`. Omit to refresh all. | For `income` type orders, the refresh can request `income` or `employment` products. For `employment` type orders, the refresh can only request `employment`. The refresh creates a **new order** with a new `id`. Use this new order ID for all subsequent operations — the original order ID is not updated. If you pass an `order_number` when creating the original order, it persists through to the refresh order. Use this to correlate refresh orders with your internal tracking system. *** ## Handle the response Listen for the `order-status-updated` webhook to know when the refreshed data is ready. ```json theme={null} { "webhook_id": "17a80437ce23411dbfd656694d19a8c6", "event_type": "order-status-updated", "event_created_at": "2024-07-11T21:43:08.073930Z", "order_id": "NEW_ORDER_ID", "status": "completed", "updated_at": "2024-07-11T21:43:08.075540+00:00" } ``` Retrieve the refreshed data using the new order ID. ```bash theme={null} curl --request GET \ --url https://prod.truv.com/v1/orders/NEW_ORDER_ID/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' \ --header 'Accept: application/json' ``` If the refresh fails (e.g., expired session), Truv fires an `order-refresh-failed` [webhook event](/api-reference/webhook-events). Handle this by prompting the user to re-authenticate through Bridge. See [Order object](/api-reference/orders/object) for the full response schema. *** ## Handle failed refreshes Refreshes can fail when the user's credentials have changed or the provider requires MFA. Check the task status in the webhook payload. | Status | Cause | Resolution | | ------------- | -------------------------------------------------------------- | ------------------------ | | `login_error` | User changed their password | Re-authenticate the user | | `mfa_error` | Provider requires MFA that can't be completed without the user | Re-authenticate the user | Other common failure causes: * **OAuth token expired (\~180 days)**: Financial institutions using OAuth typically expire tokens after \~180 days. The user must reconnect. * **Provider unavailable**: The payroll provider may be temporarily down. Retry after some time. * **Account locked**: Too many failed attempts may have locked the user's account at the provider. The user needs to unlock it with the provider first. ### Re-authenticate with Bridge Update Mode Create a new bridge token using the `access_token` from the original connection, then initialize Truv Bridge for the user to re-authenticate. ```bash theme={null} curl -X POST https://prod.truv.com/v1/users/{user_id}/tokens/ \ -H "X-Access-Client-Id: YOUR_TRUV_CLIENT_ID" \ -H "X-Access-Secret: YOUR_TRUV_CLIENT_SECRET" \ -H "Content-Type: application/json" \ -d '{ "product_type": "income", "access_token": "ACCESS_TOKEN_FROM_ORIGINAL_CONNECTION" }' ``` Pass the new `bridge_token` to your frontend and re-initialize Bridge. The user logs in again, and fresh data becomes available through the existing Link. Sessions are determined by the payroll provider. Data refreshes succeed automatically during active sessions. If the session has expired, re-authentication is required. See [Bridge Update Mode](/developers/integration/bridge-widget/returning-user) for the full returning-user flow. *** ## Next steps Receive notifications when refreshed data is ready Understand connection status transitions Re-engage users who didn't finish verification # Deeplinking Source: https://truv.com/docs/developers/integration/embedded-orders/deeplinking Pre-fill account information (employer, bank, etc.) to skip search steps and maximize conversion Deeplinking lets you pre-fill account information (employer, bank, or other provider) when creating an order, bypassing the search screens entirely. When you already know the user's provider, deeplinking sends them directly to the login screen. **Deeplinking is one of the highest-impact conversion improvements you can make.** Removing the search step eliminates friction and reduces drop-off. ```mermaid theme={null} %%{init: {'theme': 'base', 'themeVariables': {'actorBkg': '#2C64E3', 'actorBorder': '#1E4BB8', 'actorTextColor': '#FFFFFF', 'signalColor': '#9CA3AF', 'signalTextColor': '#111827', 'noteBkgColor': '#EBF0FD', 'noteBorderColor': '#5A8AEF'}}}%% sequenceDiagram participant Server as Your Server participant API as Truv API participant Bridge as Truv Bridge Server->>API: Search company mapping (GET /v1/company-mappings-search/) API-->>Server: company_mapping_id Server->>API: Create order with company_mapping_id API-->>Server: bridge_token Note over Bridge: User skips search screens Bridge->>Bridge: User lands on login page ``` *** ## How it works Truv Bridge normally shows two search screens before login: 1. **Employer selection**: user searches for their employer by name 2. **Provider selection**: user selects their payroll provider (e.g. ADP, Workday) With deeplinking, you provide this information when creating the order and users land directly on the credential entry screen. *** ## Deeplink by employer Use this when you know the user's employer name. Truv maps the employer to the correct payroll provider automatically. ### Find the company mapping Call the [Search companies endpoint](/api-reference/companies/company_mapping) with the employer name from your application. ```bash theme={null} curl --request GET \ --url 'https://prod.truv.com/v1/company-mappings-search/?query=Facebook' \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' ``` ```json theme={null} [ { "company_mapping_id": "48427a36d43c4d5aa6324bc06c692456", "name": "Facebook", // ... } ] ``` ### Create an order with the mapping Pass the `company_mapping_id` in the `employers` array when creating the order. ```bash theme={null} curl --request POST \ --url https://prod.truv.com/v1/orders/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' \ --header 'Content-Type: application/json' \ --data '{ "products": ["income"], "first_name": "John", "last_name": "Doe", "employers": [ { "company_mapping_id": "48427a36d43c4d5aa6324bc06c692456" } ] }' ``` The user skips the employer search screen and lands directly on the provider login page. ### Alternative: Deeplink by company name If you don't have a `company_mapping_id` but have the employer name on hand, pass `company_name` instead. Truv will attempt to match the employer automatically. ```bash theme={null} curl --request POST \ --url https://prod.truv.com/v1/orders/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' \ --header 'Content-Type: application/json' \ --data '{ "products": ["income"], "first_name": "John", "last_name": "Doe", "employers": [ { "company_name": "facebook" } ] }' ``` This is a best-effort match. For the highest accuracy, use `company_mapping_id` from the [company search endpoint](/api-reference/companies/company_autocomplete_search). *** ## Deeplink by provider Use this when you know the specific payroll provider (e.g. ADP, Workday, Gusto) but not the specific employer. Pass the `provider_id` in the `employers` array. ```bash theme={null} curl --request POST \ --url https://prod.truv.com/v1/orders/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' \ --header 'Content-Type: application/json' \ --data '{ "products": ["income"], "first_name": "John", "last_name": "Doe", "employers": [ { "provider_id": "adp" } ] }' ``` All providers from the [List all data providers endpoint](/api-reference/data-providers/providers-list) are supported as deeplink targets. *** ## Testing deeplinking Use the [Truv Dashboard Emulator](https://dashboard.truv.com/app/emulator) to test deeplinks before deploying. Enter a `company_mapping_id` or `provider_id` in the emulator settings to verify the user lands on the correct screen. *** ## Best practices for conversion If your application collects employer name (nearly every mortgage application does), always resolve and pass `company_mapping_id`. Each extra screen costs conversion. Call the company mapping API when the borrower enters their employer name in your form. Don't wait until they open Truv Bridge. If a company mapping isn't found, fall back to launching Bridge without a deeplink. The user can still search and connect manually. Company mappings don't change frequently. Cache results for common employers to avoid redundant API calls. *** ## Next steps Full embedded orders implementation guide Find `company_mapping_id` by employer name Deeplinking for Bridge widget flows Create orders with employer pre-fill # Follow-up Source: https://truv.com/docs/developers/integration/embedded-orders/follow-up Let Truv handle email and SMS reminders when users leave without finishing verification When a user leaves your application without finishing verification, Truv can automatically send email and SMS reminders to bring them back. Toggle notifications on and off using the order's `notification_settings`. Truv handles the messaging. ```mermaid theme={null} %%{init: {'theme': 'base', 'themeVariables': {'actorBkg': '#2C64E3', 'actorBorder': '#1E4BB8', 'actorTextColor': '#FFFFFF', 'signalColor': '#9CA3AF', 'signalTextColor': '#111827', 'noteBkgColor': '#EBF0FD', 'noteBorderColor': '#5A8AEF'}}}%% sequenceDiagram participant App as Your App participant API as Truv API participant User as User App->>API: Create order (notifications suppressed) App->>User: User starts verification in-app User-->>App: User leaves without finishing App->>API: Update order (enable notifications) API->>User: Truv sends email/SMS reminders User->>API: User clicks link, completes verification API-->>App: Webhook (order-status-updated) ``` *** ## How it works 1. Create the order with `suppress_user_notifications: true` while the user is in your app 2. When the user leaves without finishing, update the order to enable notifications 3. Truv sends email and SMS reminders on your behalf 4. When the user returns and completes verification, you receive a webhook *** ## Suppress notifications while user is in-app While the user is active in your application, suppress Truv notifications. Your app controls the experience. ```bash theme={null} curl --request POST \ --url https://prod.truv.com/v1/orders/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' \ --header 'Content-Type: application/json' \ --data '{ "products": ["income"], "first_name": "John", "last_name": "Doe", "email": "john@example.com", "phone": "4155554193", "notification_settings": { "suppress_user_notifications": true } }' ``` *** ## Enable notifications when user leaves When the user leaves your app without completing verification, update the order to turn on notifications. Truv takes over and sends email/SMS reminders to bring them back. ```bash theme={null} curl --request PATCH \ --url https://prod.truv.com/v1/orders/39aa1486ccca4bc19cda071ffc1ba392/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' \ --header 'Content-Type: application/json' \ --data '{ "notification_settings": { "suppress_user_notifications": false } }' ``` You can also delay the first notification instead of sending it immediately. ```bash theme={null} curl --request PATCH \ --url https://prod.truv.com/v1/orders/39aa1486ccca4bc19cda071ffc1ba392/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' \ --header 'Content-Type: application/json' \ --data '{ "notification_settings": { "suppress_user_notifications": false, "first_notification_delay_hours": 24 } }' ``` *** ## Configure notifications | Field | Type | Default | Description | | -------------------------------- | ------- | ------- | -------------------------------------------------------- | | `suppress_user_notifications` | boolean | `false` | Suppress all Truv email/SMS notifications for this order | | `first_notification_delay_hours` | integer | `0` | Hours to delay the first notification after enabling | *** ## Reminders Truv automatically sends an initial notification and up to three reminders via email and/or SMS. Reminders are distributed evenly from order creation until expiration. Once an order reaches a terminal status (completed, canceled, expired), reminders stop. SMS reminders require account-level enablement. Contact [support@truv.com](mailto:support@truv.com) to activate. SMS reminders are only sent between 10am–6pm ET. | Link Expiration | Order Lifespan | Initial Notification | Reminders | | --------------- | -------------------- | -------------------- | ------------------------------------------------------ | | 1 day | 24 hours + weekends | 30 seconds | 1st: 6 hours
2nd: 16 hours
3rd: 22 hours | | 2 days | 48 hours + weekends | 30 seconds | 1st: 6 hours
2nd: 24 hours | | 3 days | 72 hours + weekends | 30 seconds | 1st: 24 hours
2nd: 48 hours
3rd: 66 hours | | 1 week | 168 hours + weekends | 30 seconds | 1st: 24 hours
2nd: 72 hours
3rd: 120 hours | | 2 weeks | 336 hours + weekends | 30 seconds | 1st: 96 hours
2nd: 192 hours
3rd: 288 hours | | 3 weeks | 504 hours + weekends | 30 seconds | 1st: 264 hours
2nd: 384 hours
3rd: 456 hours | | 4 weeks | 672 hours + weekends | 30 seconds | 1st: 312 hours
2nd: 432 hours
3rd: 624 hours | Order expiration periods exclude weekends, but reminders continue being sent during weekends. Customize expiration times and reminder schedules in the [Truv Dashboard](https://dashboard.truv.com). Combining email and SMS improves completion rates. High-intent borrowers complete over 50% of verifications within 2 hours. *** ## Next steps Pull updated data without user re-authentication Let users review and confirm retrieved data Receive notifications when order status changes # Embedded Orders Source: https://truv.com/docs/developers/integration/embedded-orders/overview Create an order when you don't know the user's employer or provider Start here when you have a new user and don't know their employer, payroll provider, or bank upfront. Truv Bridge presents a search screen where the user finds and connects their accounts. Embedded order and widget Embedded Orders support the following data source types: | Data source | Products | Use case | | ------------- | ------------------------ | -------------------------------------------------------------------------------------------------------------------------- | | **Payroll** | `income`, `employment` | Income verification, employment history. **Note:** `income` auto-includes employment data. You don't need to request both. | | **Bank** | `transactions`, `assets` | Asset verification, transaction history | | **Documents** | `income`, `employment` | Document upload verification (pay stubs, W-2s, tax forms) | | **Tax** | `income` | Tax return verification | If you already know the user's employer or provider, use [deeplinking](/developers/integration/embedded-orders/deeplinking) to skip the search screen and go directly to the login flow. ```mermaid theme={null} %%{init: {'theme': 'base', 'themeVariables': {'actorBkg': '#2C64E3', 'actorBorder': '#1E4BB8', 'actorTextColor': '#FFFFFF', 'signalColor': '#9CA3AF', 'signalTextColor': '#111827', 'noteBkgColor': '#EBF0FD', 'noteBorderColor': '#5A8AEF'}}}%% sequenceDiagram participant Server as Your Server participant API as Truv API participant Browser as Your App participant Bridge as Truv Bridge Server->>API: 1. Create Order (POST /v1/orders/) API-->>Server: order_id, bridge_token Server->>Browser: 2. Pass bridge_token Browser->>Bridge: 3. Initialize widget (TruvBridge.init) Bridge->>Browser: User searches & connects accounts Bridge-->>Browser: onSuccess / onClose callbacks API-->>Server: 4. Webhook (task-status-updated) Server->>API: 5. Retrieve data (GET /v1/orders/{id}/) API-->>Server: Order with employer data, reports ``` *** ## How it works 1. **Create an order** via API with desired products 2. **User opens the widget** using the bridge token 3. **User connects accounts** (payroll, banks) 4. **Receive data** via webhook notifications 5. **Retrieve results** using the order ID *** ## Implement ### Step 1: Create an order \[Server-side] Create an [Order](/api-reference/orders/object) to link different data providers. The response includes a `bridge_token` to initialize Truv Bridge. ```bash theme={null} curl -X POST https://prod.truv.com/v1/orders/ \ -H "X-Access-Client-Id: YOUR_TRUV_CLIENT_ID" \ -H "X-Access-Secret: YOUR_TRUV_CLIENT_SECRET" \ -H "Content-Type: application/json" \ -d '{ "products": ["income"], "first_name": "John", "last_name": "Doe" }' ``` ```bash theme={null} curl -X POST https://prod.truv.com/v1/orders/ \ -H "X-Access-Client-Id: YOUR_TRUV_CLIENT_ID" \ -H "X-Access-Secret: YOUR_TRUV_CLIENT_SECRET" \ -H "Content-Type: application/json" \ -d '{ "products": ["assets"], "first_name": "John", "last_name": "Doe" }' ``` ```bash theme={null} curl -X POST https://prod.truv.com/v1/orders/ \ -H "X-Access-Client-Id: YOUR_TRUV_CLIENT_ID" \ -H "X-Access-Secret: YOUR_TRUV_CLIENT_SECRET" \ -H "Content-Type: application/json" \ -d '{ "products": ["income", "assets"], "first_name": "John", "last_name": "Doe" }' ``` When you include `income` in the products array, employment data is automatically included. You do not need to pass both `income` and `employment`. **Best practice:** Include `email` and `phone` on the order along with `notification_settings` to send a delayed notification if the user doesn't complete verification during the embedded session: ```json theme={null} { "notification_settings": { "suppress_user_notifications": false, "first_notification_delay_hours": 6 } } ``` This gives the user time to finish in-app, then sends a reminder if they haven't completed within 6 hours. The create order endpoint accepts additional fields to customize the verification: | Field | Description | | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | | `employers` | Pre-populate the employer in Bridge so the user doesn't have to search. Pass `company_name` and optionally `company_address`. | | `notification_settings` | Suppress emails/SMS to the user with `suppress_user_notifications: true`, or delay the first notification with `first_notification_delay_hours`. | | `loan` | Attach loan metadata: `loan_number` (required), `originator_name`, `originator_email`, `loan_processor_name`, `loan_processor_email`. | | `external_user_id` | Your internal identifier for the user. | | `order_number` | Your internal reference number for this order. | | `ssn` | Last 4 or full 9 digits. Enables SSN matching on the verification. | | `email` / `phone` | Contact info for sending the order link via email or SMS. | | `template_id` | [Customization template](/developers/customization) to apply. | [Explore the full request schema →](/api-reference/orders/orders_create) Orders can be configured in two modes that control how users interact with pre-populated employers: | Mode | Behavior | Best for | | ---------------- | -------------------------------------------------------------------------------- | --------------------------------------------------------- | | **Open order** | User can skip pre-populated employers and add new ones not on the original order | Flexible flows where users may have changed jobs | | **Closed order** | User must attempt all pre-populated employers. Cannot add new ones. | Strict verification where specific employers are required | Within open orders, two skip behaviors are available: * **Require attempt, then allow skip** — User must try connecting before they can skip * **Allow skip without attempting** — User can skip immediately This is an account-level setting. Contact your Truv representative or [support@truv.com](mailto:support@truv.com) to configure. Extract the `bridge_token` from the response. ```json theme={null} { "id": "39aa1486ccca4bc19cda071ffc1ba392", "order_number": "truv-o-39aa1486", // ... additional order fields "user_id": "b1e24b60b8d84b9da11e13f46a830f41", "bridge_token": "93be103a3ccd4d4fa38af0b1bfcf3be8" // ... full response includes status, timestamps, share_url, and more } ``` ### Step 2: Initialize widget \[Client-side] Load Truv Bridge and pass the `bridge_token` from Step 1. `isOrder: true` is required for Embedded Orders. Initializing without it causes unexpected behavior. ```html theme={null} ``` Wait for the `COMPLETED` event with `source: "order"` before advancing the user in your application. This event fires when the order reaches its final state: all connections succeeded or were skipped. Do **not** use `onSuccess` or `onClose` to advance the user, as the order may still have pending connections. #### Callbacks | Callback | Description | Required | | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------- | | `onLoad` | Bridge finished loading the order page | Optional | | `onSuccess` | User connected all accounts and clicked "I'm done" | Optional | | `onClose` | Bridge closed the order page | Optional | | `onEvent` | Receives events from the order page (`source: "order"`) and the connection widget (`source: "bridge"`). See [Bridge Events](/developers/sdks/bridge-events#callbacks) for all types. | Optional | #### Display modes Control how the widget appears using the `position` property. Bridge: Dialog mode vs. Inline mode ```javascript theme={null} // Dialog mode (default) — overlays the page var bridge = TruvBridge.init({ isOrder: true, bridgeToken: bridgeToken }); // Inline mode — renders inside a container element var bridge = TruvBridge.init({ isOrder: true, bridgeToken: bridgeToken, position: { type: 'inline', container: document.querySelector('#order-container') } }); ``` When using inline mode: 1. The container element must remain stable. Do not unmount or reparent it while the bridge is open. 2. Manually close the bridge before removing the container (e.g., on SPA navigation). 3. Only one bridge instance can be open at a time. ### Step 3: Test in sandbox Test your implementation with sandbox credentials. | Username | Password | Description | | ---------------------- | -------------- | ---------------------------- | | `goodlogin` | `goodpassword` | Full-time current employment | | `hourly.part-time` | `goodpassword` | Hourly part-time worker | | `multiple.employments` | `goodpassword` | Multiple employers | See [Test Credentials](/developers/testing/test-credentials) for all scenarios. ### Step 4: Monitor webhooks \[Server-side] [Webhooks](/api-reference/webhooks/object) notify you when task and order statuses change. Use `user_id` to match events to a specific order. ```mermaid theme={null} %%{init: {'theme': 'base', 'themeVariables': {'actorBkg': '#2C64E3', 'actorBorder': '#1E4BB8', 'actorTextColor': '#FFFFFF', 'signalColor': '#9CA3AF', 'signalTextColor': '#111827', 'noteBkgColor': '#EBF0FD', 'noteBorderColor': '#5A8AEF'}}}%% sequenceDiagram participant User participant Bridge as Truv Bridge participant API as Truv API participant Server as Your Server User->>Bridge: Connects account Bridge->>API: Creates task API-->>Server: task-status-updated (login) API-->>Server: task-status-updated (parse) API-->>Server: task-status-updated (done) User->>Bridge: Clicks "I'm done" API-->>Server: order-status-updated (completed) ``` Task-level webhook, fires as each connection progresses. ```json theme={null} { "webhook_id": "17a80437ce23411dbfd656694d19a8c6", "event_type": "task-status-updated", "event_created_at": "2024-07-11T21:43:08.073930Z", "product": "income", "link_id": "d8a8945ee2b049b193110cfba643f5df", "user_id": "adbe707dddee4334bffaeb5866272740", "data_source": "payroll", "task_id": "871fef2e79ea444ea2019c8845305d31", "tracking_info": null, "status": "done", "template_id": null, "updated_at": "2024-07-11T21:43:08.075540+00:00" } ``` Order-level webhook, fires when the user finishes the order. ```json theme={null} { "webhook_id": "0aac461e7b774a38a72fd9c7c0eef8ee", "event_type": "order-status-updated", "event_created_at": "2024-07-11T21:40:48.424610Z", "product": "income", "link_id": "d8a8945ee2b049b193110cfba643f5df", "user_id": "adbe707dddee4334bffaeb5866272740", "data_source": "payroll", "order_id": "ddd192646b3c48be96651a0ff25cef85", "order_number": "4138538", "employer_id": "d7166cffbfef4bd6a9e830cf5508e615", "status": "completed", "template_id": null, "updated_at": "2024-07-11T21:40:48.424655+00:00" } ``` See [Task lifecycle](/api-reference/tasks/lifecycle) for all status transitions. ### Step 5: Retrieve data \[Server-side] Fetch order details using the `order_id`. The response includes employer data, employment history, income statements, and report IDs. ```bash theme={null} curl https://prod.truv.com/v1/orders/{order_id}/ \ -H "X-Access-Client-Id: YOUR_TRUV_CLIENT_ID" \ -H "X-Access-Secret: YOUR_TRUV_CLIENT_SECRET" ``` See [Order object](/api-reference/orders/object) for the full response schema. *** ## Content Security Policy (CSP) If your application uses a Content Security Policy, you must allow these domains for the embedded widget to load and function correctly: | Domain | Purpose | | -------------- | -------------------------- | | `my.truv.com` | Truv Bridge application | | `cdn.truv.com` | Truv Bridge JavaScript SDK | ```text theme={null} Content-Security-Policy: frame-src my.truv.com; script-src cdn.truv.com; ``` Missing CSP configuration is one of the most common causes of the widget failing to load in embedded contexts. If the widget doesn't appear or shows a blank frame, check your CSP settings first. *** ## Demo apps Applicant verifies income, employment, or assets through Bridge in a single session. Applicant returns to complete multiple verification tasks tied to one file. *** ## Next steps Add additional employers to an existing order Pull updated data without user re-authentication Skip employer search for higher conversion # Self-Certification Source: https://truv.com/docs/developers/integration/embedded-orders/self-certification Retrieve user self-certification results for employments and accounts in an order Self-certification allows users to review and confirm (or reject) the employment and account data retrieved during verification. Retrieve the certification results to see whether the user confirmed the data as representative or flagged discrepancies. ```mermaid theme={null} %%{init: {'theme': 'base', 'themeVariables': {'actorBkg': '#2C64E3', 'actorBorder': '#1E4BB8', 'actorTextColor': '#FFFFFF', 'signalColor': '#9CA3AF', 'signalTextColor': '#111827', 'noteBkgColor': '#EBF0FD', 'noteBorderColor': '#5A8AEF'}}}%% sequenceDiagram participant Bridge as Truv Bridge participant User participant Server as Your Server participant API as Truv API Bridge->>User: Verification data retrieved User->>Bridge: Reviews and certifies data API-->>Server: Webhook (order-status-updated) Server->>API: GET /v1/orders/{id}/certifications/ API-->>Server: Certification results (representative / not_representative) ``` *** ## When to use | Scenario | Example | | ----------------------- | ---------------------------------------------------------------- | | Income verification | Borrower confirms retrieved income matches their actual earnings | | Employment confirmation | Borrower validates employer name, start date, and pay rate | | Asset verification | Borrower reviews account balances and ownership details | | Dispute handling | Borrower flags incorrect or outdated data with a reason | *** ## Retrieve certification results \[Server-side] Send a `GET` request to the order's `/certifications/` endpoint after the user completes their review. ```bash theme={null} curl --request GET \ --url https://prod.truv.com/v1/orders/39aa1486ccca4bc19cda071ffc1ba392/certifications/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' \ --header 'Accept: application/json' ``` ### Response structure Each result contains a `decision` and either an `employment` or `account` object. ```json theme={null} { "results": [ { "decision": "representative", "employment": { "id": "24d7e80942ce4ad58a93f70ce4115f5c", "start_date": "2018-01-01", "pay_rate": "25.50", "pay_date": "2023-12-15", "company": { "name": "Facebook" } } }, { "decision": "not_representative", "rejection_reason": "incorrect_amount", "rejection_comment": "Balance is outdated", "account": { "id": "bc917458a3da4b2c8cc8282aa1707aaa", "type": "CHECKING", "mask": "1234", "routing_number": "021000021", "balance": "1500.25", "owners": [ { "full_name": "John Doe" } ] } } ] } ``` *** ## Decision values | Decision | Meaning | | -------------------- | --------------------------------------- | | `representative` | Borrower confirmed the data is accurate | | `not_representative` | Borrower flagged the data as inaccurate | ### Rejection reasons When the decision is `not_representative`, the result includes a `rejection_reason`: | Reason | Description | | ----------------------------- | ------------------------------------------------------------- | | `employment_no_longer_active` | Borrower is no longer employed at this company | | `incorrect_amount` | Income or balance amount is wrong | | `duplicate_entry` | Employer or account appears more than once | | `outdated_information` | Data is stale or no longer current | | `other` | Borrower provided a custom explanation in `rejection_comment` | *** ## Next steps Re-engage users who didn't finish verification Full embedded orders implementation guide # Add Employer Source: https://truv.com/docs/developers/integration/hosted-orders/add-employer Add a new employer to an existing order after it has been created Add a new employer to an existing hosted order when additional employment connections are needed after the order was originally created. The order must not be expired or canceled. ```mermaid theme={null} %%{init: {'theme': 'base', 'themeVariables': {'actorBkg': '#2C64E3', 'actorBorder': '#1E4BB8', 'actorTextColor': '#FFFFFF', 'signalColor': '#9CA3AF', 'signalTextColor': '#111827', 'noteBkgColor': '#EBF0FD', 'noteBorderColor': '#5A8AEF'}}}%% sequenceDiagram participant Server as Your Server participant API as Truv API participant User as User Server->>API: Add employer (POST /v1/orders/{id}/employers/) API-->>Server: New employer added to order API->>User: Email/SMS notification User->>API: User connects new employer API-->>Server: Webhook (task-status-updated, done) ``` *** ## When to use | Scenario | Example | | ------------------- | ---------------------------------------------------------------- | | Missing employer | User disclosed an additional employer after initial verification | | Seasonal employment | User has a second job that wasn't initially included | *** ## Add an employer \[Server-side] Send a `POST` request to the order's `/employers/` endpoint with the employer details. ```bash theme={null} curl --request POST \ --url https://prod.truv.com/v1/orders/39aa1486ccca4bc19cda071ffc1ba392/employers/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' \ --header 'Content-Type: application/json' \ --data '{ "company_name": "Facebook Demo", "company_domain": "facebook.com", "start_date": "2019-08-24", "company_address": { "street": "1 Hacker Way", "city": "Menlo Park", "state": "CA", "zip": "94025" } }' ``` ### Request fields | Field | Type | Required | Description | | ----------------- | ------ | -------- | ------------------------------------------------------ | | `company_name` | string | No | Employer name | | `company_domain` | string | No | Company website domain | | `start_date` | date | No | Job start date (YYYY-MM-DD) | | `end_date` | date | No | Job end date (YYYY-MM-DD) | | `suborder_number` | string | No | Your external ID for tracking | | `company_address` | object | No | Employer address with `street`, `city`, `state`, `zip` | The order must be in an active state, not expired or canceled. Check the order status before adding employers. *** ## What happens next After adding the employer, Truv extends the order to include the new employer. The user receives a notification to connect their additional employer through the hosted verification page. Listen for `task-status-updated` webhooks to know when the new employer's data is ready. *** ## Next steps Pull updated data without user re-authentication Create a hosted order from scratch Pre-fill employer info to skip search # Data Refresh Source: https://truv.com/docs/developers/integration/hosted-orders/data-refresh Refresh verification data from a completed order without requiring the user to reconnect Create a data refresh order to pull updated income, employment, or asset data from an existing order's connections. The user does not need to re-authenticate. Truv reuses the existing account links. Data refresh works only when the original account connections are still active. If a connection has expired or the user changed their credentials, use [Bridge Update Mode](/developers/integration/bridge-widget/returning-user) to re-authenticate. ```mermaid theme={null} %%{init: {'theme': 'base', 'themeVariables': {'actorBkg': '#2C64E3', 'actorBorder': '#1E4BB8', 'actorTextColor': '#FFFFFF', 'signalColor': '#9CA3AF', 'signalTextColor': '#111827', 'noteBkgColor': '#EBF0FD', 'noteBorderColor': '#5A8AEF'}}}%% sequenceDiagram participant Server as Your Server participant API as Truv API Server->>API: Create refresh order (POST /v1/orders/{id}/) API-->>Server: New order_id Note over API: Truv pulls fresh data from existing connections API-->>Server: Webhook (task-status-updated, done) Server->>API: Retrieve refreshed order (GET /v1/orders/{new_id}/) API-->>Server: Updated employer data, reports ``` *** ## When to use | Scenario | Example | | ----------------- | -------------------------------------------------------- | | Stale data | Original verification is older than your policy window | | Updated pay stubs | Need the most recent pay period before closing | | Re-verification | Underwriting requires a fresh pull before final approval | | Monitoring | Periodic income checks on active loans | *** ## Create a data refresh order \[Server-side] Send a `POST` request to the original order's endpoint. Specify which `products` to refresh and optionally which `employers` or `financial_accounts` to include. ```bash theme={null} curl --request POST \ --url https://prod.truv.com/v1/orders/39aa1486ccca4bc19cda071ffc1ba392/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' \ --header 'Content-Type: application/json' \ --data '{ "products": ["income"] }' ``` ```bash theme={null} curl --request POST \ --url https://prod.truv.com/v1/orders/39aa1486ccca4bc19cda071ffc1ba392/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' \ --header 'Content-Type: application/json' \ --data '{ "products": ["assets"] }' ``` ```bash theme={null} curl --request POST \ --url https://prod.truv.com/v1/orders/39aa1486ccca4bc19cda071ffc1ba392/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' \ --header 'Content-Type: application/json' \ --data '{ "products": ["income"], "employers": [ { "id": "ad9f14440d624ec3b0f66e81e44518c7" } ] }' ``` ```bash theme={null} curl --request POST \ --url https://prod.truv.com/v1/orders/39aa1486ccca4bc19cda071ffc1ba392/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' \ --header 'Content-Type: application/json' \ --data '{ "products": ["employment"] }' ``` ### Request fields | Field | Type | Description | | -------------------- | ----- | --------------------------------------------------------------------------------------------------------------- | | `products` | array | Product to refresh: `income`, `employment`, `assets`, `insurance`, or `transactions`. One product per request. | | `employers` | array | Employers to include. Each object takes `id` or `suborder_number` from the original order. Omit to refresh all. | | `financial_accounts` | array | Financial accounts to include. Each object takes `id` or `suborder_number`. Omit to refresh all. | For `income` type orders, the refresh can request `income` or `employment` products. For `employment` type orders, the refresh can only request `employment`. The refresh creates a **new order** with a new `id`. Use this new order ID for all subsequent operations — the original order ID is not updated. If you pass an `order_number` when creating the original order, it persists through to the refresh order. Use this to correlate refresh orders with your internal tracking system. *** ## Handle the response Listen for the `order-status-updated` webhook to know when the refreshed data is ready. ```json theme={null} { "webhook_id": "17a80437ce23411dbfd656694d19a8c6", "event_type": "order-status-updated", "order_id": "NEW_ORDER_ID", "status": "completed", "updated_at": "2024-07-11T21:43:08.075540+00:00" } ``` Retrieve the refreshed data using the new order ID. ```bash theme={null} curl --request GET \ --url https://prod.truv.com/v1/orders/NEW_ORDER_ID/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' \ --header 'Accept: application/json' ``` If the refresh fails (e.g., expired session), Truv fires an `order-refresh-failed` [webhook event](/api-reference/webhook-events). Handle this by sending the user a new verification link. See [Order object](/api-reference/orders/object) for the full response schema. *** ## Next steps Receive notifications when refreshed data is ready Understand connection status transitions # Deeplinking Source: https://truv.com/docs/developers/integration/hosted-orders/deeplinking Pre-fill account information (employer, bank, etc.) to skip search steps and maximize conversion Pre-fill account information (employer, bank, or other provider) when creating a hosted order to bypass the search screens. When the user clicks the verification link, they land directly on the login screen. **Deeplinking is one of the highest-impact conversion improvements you can make.** Removing the search step eliminates friction and reduces drop-off. ```mermaid theme={null} %%{init: {'theme': 'base', 'themeVariables': {'actorBkg': '#2C64E3', 'actorBorder': '#1E4BB8', 'actorTextColor': '#FFFFFF', 'signalColor': '#9CA3AF', 'signalTextColor': '#111827', 'noteBkgColor': '#EBF0FD', 'noteBorderColor': '#5A8AEF'}}}%% sequenceDiagram participant Server as Your Server participant API as Truv API participant User as User Server->>API: Search company mapping (GET /v1/company-mappings-search/) API-->>Server: company_mapping_id Server->>API: Create order with company_mapping_id API-->>Server: order_id, share_url API->>User: Email/SMS with verification link Note over User: User skips search screens User->>User: Lands directly on login page ``` *** ## How it works Truv's hosted verification page normally shows two search screens before login: 1. **Employer selection**: user searches for their employer by name 2. **Provider selection**: user selects their payroll provider (e.g. ADP, Workday) With deeplinking, you provide this information when creating the order and users land directly on the credential entry screen. *** ## Deeplink by employer Use this when you know the user's employer name. Truv maps the employer to the correct payroll provider automatically. ### Find the company mapping Call the [Search companies endpoint](/api-reference/companies/company_mapping) with the employer name from your application. ```bash theme={null} curl --request GET \ --url 'https://prod.truv.com/v1/company-mappings-search/?query=Facebook' \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' ``` ```json theme={null} [ { "company_mapping_id": "48427a36d43c4d5aa6324bc06c692456", "name": "Facebook", // ... } ] ``` ### Create an order with the mapping Pass the `company_mapping_id` in the `employers` array when creating the order. ```bash theme={null} curl --request POST \ --url https://prod.truv.com/v1/orders/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' \ --header 'Content-Type: application/json' \ --data '{ "products": ["income"], "first_name": "John", "last_name": "Doe", "email": "john@example.com", "employers": [ { "company_mapping_id": "48427a36d43c4d5aa6324bc06c692456" } ] }' ``` The user skips the employer search screen and lands directly on the provider login page. ### Alternative: Deeplink by company name If you don't have a `company_mapping_id` but have the employer name on hand, pass `company_name` instead. Truv will attempt to match the employer automatically. ```bash theme={null} curl --request POST \ --url https://prod.truv.com/v1/orders/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' \ --header 'Content-Type: application/json' \ --data '{ "products": ["income"], "first_name": "John", "last_name": "Doe", "email": "john@example.com", "employers": [ { "company_name": "facebook" } ] }' ``` This is a best-effort match. For the highest accuracy, use `company_mapping_id` from the [company search endpoint](/api-reference/companies/company_autocomplete_search). *** ## Deeplink by provider Use this when you know the specific payroll provider (e.g. ADP, Workday, Gusto) but not the specific employer. Pass the `provider_id` in the `employers` array. ```bash theme={null} curl --request POST \ --url https://prod.truv.com/v1/orders/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' \ --header 'Content-Type: application/json' \ --data '{ "products": ["income"], "first_name": "John", "last_name": "Doe", "email": "john@example.com", "employers": [ { "provider_id": "adp" } ] }' ``` All providers from the [List all data providers endpoint](/api-reference/data-providers/providers-list) are supported as deeplink targets. *** ## Next steps Create a hosted order from scratch Find `company_mapping_id` by employer name Deeplinking for Bridge widget flows Create orders with employer pre-fill # New User Source: https://truv.com/docs/developers/integration/hosted-orders/new-user Create an order where Truv contacts the user via email or SMS to complete verification Hosted orders let Truv handle user outreach. Create an order with the user's contact information, and Truv sends an email or SMS with a link to complete verification. No app or widget integration required. At least one of `email` or `phone` is required. Truv needs a way to contact the user. Providing both maximizes success rates. | Creation method | Best for | | ------------------- | -------------------------------------------- | | **API** | Programmatic workflows, automated pipelines | | **Dashboard** | Manual order creation, one-off verifications | | **CSV bulk upload** | High-volume batch processing | ```mermaid theme={null} %%{init: {'theme': 'base', 'themeVariables': {'actorBkg': '#2C64E3', 'actorBorder': '#1E4BB8', 'actorTextColor': '#FFFFFF', 'signalColor': '#9CA3AF', 'signalTextColor': '#111827', 'noteBkgColor': '#EBF0FD', 'noteBorderColor': '#5A8AEF'}}}%% sequenceDiagram participant Server as Your Server participant API as Truv API participant User as User Server->>API: 1. Create Order (POST /v1/orders/) API-->>Server: order_id, share_url API->>User: 2. Email/SMS with verification link User->>API: 3. User clicks link, connects accounts API-->>Server: 4. Webhook (task-status-updated) Server->>API: 5. Retrieve data (GET /v1/orders/{id}/) API-->>Server: Order with employer data, reports ``` *** ## How it works 1. **Create an order** via API with the user's contact information 2. **Truv sends a notification** (email, SMS, or both) with a link to the hosted verification page 3. **User connects accounts** on Truv's hosted page (payroll, banks) 4. **Receive data** via webhook notifications 5. **Retrieve results** using the order ID *** ## Implement ### Step 1: Create an order \[Server-side] Create an [Order](/api-reference/orders/object) with the user's name and contact information. Truv sends the verification link automatically. ```bash theme={null} curl --request POST \ --url https://prod.truv.com/v1/orders/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' \ --header 'Content-Type: application/json' \ --data '{ "products": ["income"], "first_name": "John", "last_name": "Doe", "email": "john@example.com", "phone": "4155554193", "ssn": "222233333" }' ``` ```bash theme={null} curl --request POST \ --url https://prod.truv.com/v1/orders/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' \ --header 'Content-Type: application/json' \ --data '{ "products": ["assets"], "first_name": "John", "last_name": "Doe", "email": "john@example.com", "phone": "4155554193" }' ``` ```bash theme={null} curl --request POST \ --url https://prod.truv.com/v1/orders/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' \ --header 'Content-Type: application/json' \ --data '{ "products": ["income", "assets"], "first_name": "John", "last_name": "Doe", "email": "john@example.com", "phone": "4155554193", "ssn": "222233333" }' ``` The response includes a `short_share_url`, the hosted verification link to send to the user. ```json theme={null} { "id": "39aa1486ccca4bc19cda071ffc1ba392", "products": ["income"], "first_name": "John", "last_name": "Doe", "user_id": "99dd17074ac94aa9ace2621d657c7610", "bridge_token": "e4100fccdae94691b4414c7306220c06", // ... additional fields "short_share_url": "https://truv.link/abc123", // ... status, timestamps, employers } ``` Specify only the products your use case requires. | Field | Type | Required | Description | | ------------------ | ------ | -------- | ------------------------------------------------------------ | | `products` | array | Yes | Products to request: `income`, `employment`, `assets` | | `first_name` | string | Yes | User's first name | | `last_name` | string | Yes | User's last name | | `email` | string | Yes\* | User's email for notifications | | `phone` | string | No | User's phone for SMS notifications | | `ssn` | string | No | SSN for identity matching (4 or 9 digits) | | `external_user_id` | string | No | Your internal user/application identifier | | `template_id` | string | No | [Customization template](/developers/customization) to apply | If you already know the user's employer, use [deeplinking](/developers/integration/hosted-orders/deeplinking) to skip the search screen. ### Step 2: Test in sandbox Test your implementation with sandbox credentials. | Username | Password | Description | | ---------------------- | -------------- | ---------------------------- | | `goodlogin` | `goodpassword` | Full-time current employment | | `hourly.part-time` | `goodpassword` | Hourly part-time worker | | `multiple.employments` | `goodpassword` | Multiple employers | See [Test Credentials](/developers/testing/test-credentials) for all scenarios. ### Step 3: Monitor webhooks \[Server-side] [Webhooks](/api-reference/webhooks/object) notify you when task and order statuses change. Use `user_id` to match events to a specific order. ```mermaid theme={null} %%{init: {'theme': 'base', 'themeVariables': {'actorBkg': '#2C64E3', 'actorBorder': '#1E4BB8', 'actorTextColor': '#FFFFFF', 'signalColor': '#9CA3AF', 'signalTextColor': '#111827', 'noteBkgColor': '#EBF0FD', 'noteBorderColor': '#5A8AEF'}}}%% sequenceDiagram participant User participant API as Truv API participant Server as Your Server User->>API: Connects account via hosted page API-->>Server: task-status-updated (login) API-->>Server: task-status-updated (parse) API-->>Server: task-status-updated (done) User->>API: Clicks "I'm done" API-->>Server: order-status-updated (completed) ``` Task-level webhook, fires as each connection progresses. ```json theme={null} { "webhook_id": "17a80437ce23411dbfd656694d19a8c6", "event_type": "task-status-updated", "event_created_at": "2024-07-11T21:43:08.073930Z", "product": "income", "link_id": "d8a8945ee2b049b193110cfba643f5df", "user_id": "adbe707dddee4334bffaeb5866272740", "data_source": "payroll", "task_id": "871fef2e79ea444ea2019c8845305d31", "tracking_info": null, "status": "done", "template_id": null, "updated_at": "2024-07-11T21:43:08.075540+00:00" } ``` Order-level webhook, fires when the user finishes the order. ```json theme={null} { "webhook_id": "0aac461e7b774a38a72fd9c7c0eef8ee", "event_type": "order-status-updated", "event_created_at": "2024-07-11T21:40:48.424610Z", "product": "income", "link_id": "d8a8945ee2b049b193110cfba643f5df", "user_id": "adbe707dddee4334bffaeb5866272740", "data_source": "payroll", "order_id": "ddd192646b3c48be96651a0ff25cef85", "order_number": "4138538", "employer_id": "d7166cffbfef4bd6a9e830cf5508e615", "status": "completed", "template_id": null, "updated_at": "2024-07-11T21:40:48.424655+00:00" } ``` See [Task lifecycle](/api-reference/tasks/lifecycle) for all status transitions. ### Step 4: Retrieve data \[Server-side] Fetch order details using the `order_id`. The response includes employer data, employment history, income statements, and report IDs. ```bash theme={null} curl --request GET \ --url https://prod.truv.com/v1/orders/39aa1486ccca4bc19cda071ffc1ba392/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' \ --header 'Accept: application/json' ``` See [Order object](/api-reference/orders/object) for the full response schema. *** ## Order statuses | Status | Description | | ------------- | ------------------------------------------------ | | **Pending** | Order created, system processing | | **Sent** | Email or SMS sent to the user | | **Completed** | User connected their account | | **Error** | Notification delivery failed | | **Canceled** | Order manually canceled | | **Expired** | Order exceeded its expiration window | | **Skipped** | User opened the link but did not complete | | **No Data** | User connected but the provider returned no data | *** ## No-code alternative Create orders through the Dashboard UI without any API integration: single orders or bulk via CSV. See [Manual Orders](/developers/integration/manual-orders/new-user). *** ## Set expiration and reminders The default expiration window is **72 hours**, configurable from 1 day to 12 weeks. Expiration periods do not count weekends. Configure expiration and automatic reminders in the [Dashboard](/developers/dashboard) under **Customization**, or set `expired_at` when creating orders via API. *** ## Next steps Add additional employers to an existing order Refresh data from existing connections Pre-fill employer info to skip search Let users review and confirm retrieved data Send verification links via email/SMS. The applicant completes Bridge on their own device. # Self-Certification Source: https://truv.com/docs/developers/integration/hosted-orders/self-certification Retrieve user self-certification results for employments and accounts in an order Self-certification allows users to review and confirm (or reject) the employment and account data retrieved during verification. Retrieve the certification results to see whether the user confirmed the data as representative or flagged discrepancies. ```mermaid theme={null} %%{init: {'theme': 'base', 'themeVariables': {'actorBkg': '#2C64E3', 'actorBorder': '#1E4BB8', 'actorTextColor': '#FFFFFF', 'signalColor': '#9CA3AF', 'signalTextColor': '#111827', 'noteBkgColor': '#EBF0FD', 'noteBorderColor': '#5A8AEF'}}}%% sequenceDiagram participant User participant Hosted as Hosted Page participant Server as Your Server participant API as Truv API Hosted->>User: Verification data retrieved User->>Hosted: Reviews and certifies data API-->>Server: Webhook (order-status-updated) Server->>API: GET /v1/orders/{id}/certifications/ API-->>Server: Certification results (representative / not_representative) ``` *** ## When to use | Scenario | Example | | ----------------------- | ------------------------------------------------------------ | | Income verification | User confirms retrieved income matches their actual earnings | | Employment confirmation | User validates employer name, start date, and pay rate | | Asset verification | User reviews account balances and ownership details | | Dispute handling | User flags incorrect or outdated data with a reason | *** ## Retrieve certification results \[Server-side] Send a `GET` request to the order's `/certifications/` endpoint after the user completes their review. ```bash theme={null} curl --request GET \ --url https://prod.truv.com/v1/orders/39aa1486ccca4bc19cda071ffc1ba392/certifications/ \ --header 'X-Access-Client-Id: YOUR_TRUV_CLIENT_ID' \ --header 'X-Access-Secret: YOUR_TRUV_CLIENT_SECRET' \ --header 'Accept: application/json' ``` ### Response structure Each result contains a `decision` and either an `employment` or `account` object. ```json theme={null} { "results": [ { "decision": "representative", "employment": { "id": "24d7e80942ce4ad58a93f70ce4115f5c", "start_date": "2018-01-01", "pay_rate": "25.50", "pay_date": "2023-12-15", "company": { "name": "Facebook" } } }, { "decision": "not_representative", "rejection_reason": "incorrect_amount", "rejection_comment": "Balance is outdated", "account": { "id": "bc917458a3da4b2c8cc8282aa1707aaa", "type": "CHECKING", "mask": "1234", "routing_number": "021000021", "balance": "1500.25", "owners": [ { "full_name": "John Doe" } ] } } ] } ``` *** ## Decision values | Decision | Meaning | | -------------------- | ----------------------------------- | | `representative` | User confirmed the data is accurate | | `not_representative` | User flagged the data as inaccurate | ### Rejection reasons When the decision is `not_representative`, the result includes a `rejection_reason`: | Reason | Description | | ----------------------------- | --------------------------------------------------------- | | `employment_no_longer_active` | User is no longer employed at this company | | `incorrect_amount` | Income or balance amount is wrong | | `duplicate_entry` | Employer or account appears more than once | | `outdated_information` | Data is stale or no longer current | | `other` | User provided a custom explanation in `rejection_comment` | *** ## Next steps Create a hosted order from scratch Refresh data when certifications flag outdated info # CSV Upload Source: https://truv.com/docs/developers/integration/manual-orders/csv-upload Create verification orders in bulk by uploading a CSV file through the Dashboard For high-volume order creation without API integration, upload a CSV file through the Dashboard. Each row creates a separate order. Truv sends notifications to all users automatically. ```mermaid theme={null} %%{init: {'theme': 'base', 'themeVariables': {'actorBkg': '#2C64E3', 'actorBorder': '#1E4BB8', 'actorTextColor': '#FFFFFF', 'signalColor': '#9CA3AF', 'signalTextColor': '#111827', 'noteBkgColor': '#EBF0FD', 'noteBorderColor': '#5A8AEF'}}}%% sequenceDiagram participant Dashboard as Truv Dashboard participant API as Truv API participant Users as Users Dashboard->>API: 1. Upload CSV file API->>API: Validate rows API->>Users: 2. Email/SMS to each user Users->>API: 3. Users complete verifications API-->>Dashboard: 4. Status updates per order ``` *** ## Upload orders 1. Go to **Activity > Orders** and click **Upload Order** 2. Select the product type (income, employment, assets) ![Upload orders](https://files.readme.io/300294d-126.png) 3. Download the sample CSV template provided 4. Fill in the template with applicant details, one row per order 5. Drag-and-drop or browse to upload the completed file ![CSV file upload](https://files.readme.io/c847552-image.png) 6. Truv validates mandatory fields before processing Audit your CSV file to ensure all details are accurately filled out before uploading. Rows with missing mandatory fields (first name, last name) are rejected. *** ## CSV template fields | Column | Required | Description | | ------------------ | -------- | -------------------------------------- | | `first_name` | Yes | User's first name | | `last_name` | Yes | User's last name | | `email` | No\* | User's email for notifications | | `phone` | No\* | User's phone for SMS notifications | | `ssn` | No | Social security number (4 or 9 digits) | | `employer_name` | No | Pre-fill employer for deeplinking | | `loan_number` | No | Loan identifier for tracking | | `external_user_id` | No | Your internal identifier | At least one of `email` or `phone` is recommended per row. Otherwise Truv cannot send notifications and you must share the verification link manually. *** ## After upload Each row creates a separate order visible in the **Activity > Orders** table. Filter by source to see only CSV-uploaded orders. Track individual order statuses and view results as users complete their verifications. See [Manage Orders](/developers/integration/manual-orders/manage-orders) for filtering, searching, and exporting. *** ## Next steps Filter, search, and export order data Create a single order through the Dashboard # Manage Orders Source: https://truv.com/docs/developers/integration/manual-orders/manage-orders Filter, search, export, and customize the orders table in the Dashboard The Orders dashboard provides a centralized view of all verification orders, whether created manually, via CSV, or through the API. Filter, search, and export to manage your verification pipeline. Orders table *** ## Filter orders Narrow the orders table using these filters: | Filter | Options | | ---------------- | -------------------------------------------------------------------- | | **Date range** | Custom start and end dates | | **Status** | Pending, Sent, Completed, Error, Canceled, Expired, Skipped, No Data | | **Product type** | Income, Employment, Assets | | **Source** | Dashboard, API, CSV upload | | **Creator** | Team member who created the order | *** ## Search orders Search across multiple fields to find specific orders: | Search field | Example | | --------------- | ------------------------------------------------------------- | | Order ID | `39aa1486ccca4bc19cda071ffc1ba392` | | Applicant name | `John Doe` | | Email | `john@example.com` | | Phone | `4155554193` | | Employer | `Facebook` | | Loan number | `LN-2024-001` | | Tracking number | Custom tracking identifiers | | Report ID | Income & Employment (VOIE) or Assets (VOA) report identifiers | *** ## Export orders Export filtered order data as a CSV file. 1. Apply your desired filters 2. Click **Export CSV** 3. The file downloads with all visible columns Large exports (10,000+ rows) may take a few minutes to generate. *** ## Customize columns Control which columns appear in the orders table. 1. Click **Edit Columns** above the table 2. Toggle columns on or off 3. Drag to reorder columns Available columns include order ID, applicant name, status, product type, employer, creation date, completion date, source, creator, loan number, and custom fields. *** ## Order statuses | Status | Description | Terminal | | ------------- | ------------------------------------------------ | -------- | | **Pending** | Order created, system processing | No | | **Sent** | Email or SMS sent to the user | No | | **Completed** | User connected their account | Yes | | **Error** | Notification delivery failed | Yes | | **Canceled** | Order manually canceled | Yes | | **Expired** | Order exceeded its expiration window | Yes | | **Skipped** | User opened the link but did not complete | Yes | | **No Data** | User connected but the provider returned no data | Yes | *** ## Expiration & reminders ### Expiration The default expiration window is **72 hours**, configurable in your account settings from 1 day to 12 weeks. Expiration periods **do not count weekends**. An order created on Friday with a 2-day expiration expires on Tuesday, not Sunday. ### Automatic reminders Truv sends **3 reminder notifications** evenly spaced throughout the order lifespan: * Reminders stop once the order reaches a terminal status (Completed, Canceled, Expired, etc.) * SMS reminders are only sent between **10am–6pm ET** * Each reminder includes the original order link *** ## Cancel an order Cancel an active order from the Dashboard when it's no longer needed. Open the order and click **Cancel**. If the order is partially completed, previously verified data remains accessible. Once canceled, the verification link is deactivated. The user can no longer complete the order. *** ## Next steps Create orders in bulk via CSV Create a single order through the Dashboard Full Dashboard overview and backend integration # New Order Source: https://truv.com/docs/developers/integration/manual-orders/new-user Create a verification order through the Truv Dashboard without writing any code Create orders directly in the Truv Dashboard. No API integration required. Enter the user's details, select a product, and Truv sends an email or SMS with a link to complete verification. Providing both email and phone maximizes success rates. High-intent users complete over 50% of verifications within 2 hours. ```mermaid theme={null} %%{init: {'theme': 'base', 'themeVariables': {'actorBkg': '#2C64E3', 'actorBorder': '#1E4BB8', 'actorTextColor': '#FFFFFF', 'signalColor': '#9CA3AF', 'signalTextColor': '#111827', 'noteBkgColor': '#EBF0FD', 'noteBorderColor': '#5A8AEF'}}}%% sequenceDiagram participant Dashboard as Truv Dashboard participant API as Truv API participant User as User Dashboard->>API: 1. Create Order API->>User: 2. Email/SMS with verification link User->>API: 3. User clicks link, connects accounts API-->>Dashboard: 4. Status updates in Dashboard ``` *** ## Create an order 1. Go to **Activity > Orders** in the [Dashboard](https://dashboard.truv.com) and click **Create Order** Dashboard - Orders 2. Select the product type (income, employment, assets) 3. Enter applicant details. First and last name are required. 4. Choose how to reach the user: send via email, SMS, or generate a shareable link Dashboard - Create an order 5. Click **Create**. Truv sends the notification automatically. ### Required fields | Field | Description | | -------------- | ----------------------------- | | `First name` | User's first name | | `Last name` | User's last name | | `Product type` | Income, employment, or assets | ### Recommended fields | Field | Description | | -------------- | --------------------------------------------------------------------------------------------------------------------------------------- | | `Email` | User's email for notifications | | `Phone` | User's phone for SMS notifications | | `SSN` | Social security number (4 or 9 digits). Used for identity matching. | | `Loan number` | Loan identifier for tracking | | `Employer` | Pre-fill employer info to skip search (up to 5 employers) | | `Template` | [Customization template](/developers/customization) for branding | | `Custom field` | Custom metadata field to associate with the order. Configure custom fields in your [customization template](/developers/customization). | If both email and phone are left blank, Truv cannot send notifications. Retrieve the verification link from the order details and share it manually. *** ## Track order status After creating an order, track its progress directly in the Dashboard. The order card shows the current status, notification history, and connection results. Subscribe to email alerts for order status changes in **Settings > Notifications** to get notified when orders complete or fail without checking the Dashboard. | Status | Description | | ------------- | ------------------------------------------------ | | **Pending** | Order created, system processing | | **Sent** | Email or SMS sent to the user | | **Completed** | User connected their account | | **Error** | Notification delivery failed | | **Canceled** | Order manually canceled | | **Expired** | Order exceeded its expiration window | | **Skipped** | User opened the link but did not complete | | **No Data** | User connected but the provider returned no data | *** ## Set expiration and reminders The default expiration window is **72 hours**, configurable from 1 day to 12 weeks. Expiration periods do not count weekends. Configure expiration and automatic reminders in the [Dashboard](/developers/dashboard) under **Customization**. *** ## View results Once the user completes verification: 1. Open the order in **Activity > Orders** 2. View employer data, income, and employment details 3. Download PDF reports for each verified employer 4. Export data as needed Dashboard - Order details *** ## Next steps Filter, search, and export order data Create orders in bulk via CSV Full Dashboard overview and backend integration # Login Source: https://truv.com/docs/developers/login Log into the Truv Dashboard using email, SSO, or a social provider Sign into the Truv Dashboard with email/password, SSO, Google, or Microsoft. Go to [dashboard.truv.com](https://dashboard.truv.com) and click **Login**. *** ## Authentication methods | Method | How to use | | ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------- | | **Email and password** | Enter your work email, press **Continue**, then enter your password | | **One-time passcode** | If configured, choose this option after entering your email to receive a passcode instead of a password | | **Google** | Click **Continue with Google** to authenticate with your Google Workspace account | | **Microsoft** | Click **Continue with Microsoft** to authenticate with your Microsoft account | | **Single sign-on (SSO)** | If your company has SAML 2.0 or OIDC SSO configured, entering your work email automatically redirects you to your identity provider | If you're not sure which method you used previously, enter your work email and press **Continue** — Truv redirects you to the last successfully used login method. *** ## SSO If your organization uses a centralized identity provider (Okta, Azure AD, etc.), Truv supports SAML 2.0 and OIDC. Contact [Truv Support](mailto:support@truv.com) to enable SSO for your company. Once SSO is active: * Users enter their work email and are automatically redirected to the identity provider * MFA is enforced at the identity provider level * Deprovisioning a user in your IdP immediately revokes their Truv Dashboard access See [SSO Configuration](/developers/sso) for setup instructions. *** ## Next steps Set up single sign-on for your team Add team members and assign roles # Multi-Tenancy Source: https://truv.com/docs/developers/multi-tenancy Manage separate Dashboard instances for different business units Multi-tenancy allows your organization to manage multiple separate [Dashboard](/developers/dashboard) instances, each with its own orders, customization templates, API keys, and team configuration. Team members can belong to multiple companies and switch between them instantly. This is useful for: * **Business unit separation**: distinct divisions operating independently * **Brand management**: different brands with separate branding and templates * **Testing isolation**: separating sandbox and production setups across teams *** ## How it works ### Company Toggle A company toggle appears in the bottom-left of the Dashboard Home page. It shows your current company and an expandable list of all companies you belong to, with member counts and owner email addresses. Multi-tenancy dropdown list ### Shared Credentials Team members use the **same login credentials** across all assigned companies. No separate accounts needed. When access to a company is removed, it simply disappears from the toggle list. Members can have **different roles** in each company. For example, you could be an Owner in one company and a Developer in another. See [Team Roles & Permissions](/developers/dashboard#team-roles--permissions) for the full roles matrix. ### Company Identification A static company tile appears in the header on key pages (Create Order, New Template, Add Member) so you always know which company context you're working in. Multi-tenancy order creation *** ## Set up multi-tenancy Provide the following for each new company: * Company name * Designated owner (one owner per company) * Billing rollup preferences * Any specific configuration requirements Your CSM creates the company and sends invitations. Existing active members get automatic access without needing a new invite email. For each new company, you'll need to: * Request production API keys * Set up [customization templates](/developers/customization) with the correct branding * Configure [webhooks](/api-reference/webhooks/object) and data settings as needed *** ## Manage teams Add members to any company via **Settings > Team > Add member**. When adding a member, specify: * Name and email * Role for this specific company * Available order templates Adding a member who already has a Truv account automatically grants them access to the new company through their existing login. *** ## Next steps Navigate the Dashboard interface Manage API credentials for each company Set up branding per company # Quickstart Source: https://truv.com/docs/developers/quickstart Run a complete Truv integration in minutes with Python, Ruby, Go, Node.js, or C# The [quickstart](https://github.com/truvhq/quickstart) repo runs a complete Truv integration end-to-end: create a user, launch Bridge, receive webhooks, and fetch reports. Available in five server-side languages, plus separate iOS and Android apps. *** ## Languages and repos ### Server-side quickstarts | Language | Repo | Port | | -------- | ------------------------------------------------------------------------------ | ---- | | Node.js | [quickstart/node](https://github.com/truvhq/quickstart/tree/master/node) | 5004 | | Python | [quickstart/python](https://github.com/truvhq/quickstart/tree/master/python) | 5001 | | Ruby | [quickstart/ruby](https://github.com/truvhq/quickstart/tree/master/ruby) | 5002 | | Go | [quickstart/golang](https://github.com/truvhq/quickstart/tree/master/golang) | 5003 | | C# | [quickstart/c-sharp](https://github.com/truvhq/quickstart/tree/master/c-sharp) | 5005 | *** ## Setup ### Prerequisites * [Docker](https://www.docker.com/) and Docker Compose * A [Truv sandbox account](https://dashboard.truv.com/app/development/keys) * API credentials from the [Truv Dashboard API Keys page](https://dashboard.truv.com/app/development/keys) ### Clone and configure ```bash theme={null} git clone https://github.com/truvhq/quickstart.git cd quickstart make env ``` Open `.env` and add your credentials from the [Dashboard API Keys page](https://dashboard.truv.com/app/development/keys): ``` API_CLIENT_ID=your_client_id API_SECRET=your_secret ``` Set `IS_ORDER=true` to use the Orders API instead of the Users API. The Orders API lets you pre-configure employer and account information. The quickstart also supports `API_PRODUCT_TYPE` values such as `income`, `employment`, `deposit_switch`, `pll`, and `admin`. Choose the product flow you want to exercise before starting the app. ### Environments All environments use the same base URL: `https://prod.truv.com/v1/`. Your credentials determine which environment you're using. | Environment | Purpose | | -------------- | ----------------------------------------------------- | | **Sandbox** | Test with sandbox credentials and simulated providers | | **Production** | Live user traffic and billed activity | *** ## Webhooks with ngrok To receive webhooks locally, start ngrok in a separate terminal: ```bash theme={null} ngrok http 3001 ``` Copy the forwarding URL into `.env`: ``` NGROK_URL=https://xxxx-xxxx-xxxx.ngrok-free.app ``` Restart the app. It automatically registers a sandbox webhook and cleans it up on exit. *** ## Run Pick your language and run with Docker: ```bash theme={null} make node_docker # http://localhost:5004 make python_docker # http://localhost:5001 make ruby_docker # http://localhost:5002 make golang_docker # http://localhost:5003 make csharp_docker # http://localhost:5005 ``` To run all languages simultaneously: `docker-compose up` *** Providers and credentials ## Sandbox data Use `goodlogin` / `goodpassword` to test a standard login flow, or `goodlogin` / `mfa` (MFA code: `12345`) to test the MFA flow. See [Test Credentials](/developers/testing/test-credentials) for all scenarios including error states, pay frequencies, and financial accounts. # Start Building Source: https://truv.com/docs/developers/quickstarts-overview Quickstart for basics, demo apps for real integration patterns ## Quickstart Run a minimal Truv integration end-to-end in Python, Ruby, Go, Node.js, or C#. Create a user, launch Bridge, receive a webhook, and fetch a report. Use this to verify your API keys work and understand the core flow before building anything. Clone, configure, and run in minutes with Docker. Five languages available. *** ## Demo apps The [demo-apps](https://github.com/truvhq/demo-apps) repo implements five real integration patterns. Each makes live API calls, launches Bridge, receives webhooks, and fetches reports. Pick the demo that matches your use case and use it as a starting point. ### Prerequisites * [Node.js](https://nodejs.org/) 18+ * [ngrok](https://ngrok.com/) (free tier) for receiving webhooks locally * A [Truv sandbox account](https://dashboard.truv.com/app/development/keys) ### Setup ```bash theme={null} git clone https://github.com/truvhq/demo-apps.git cd demo-apps npm install cp .env.example .env ``` Open `.env` and add your Truv API credentials: ``` API_CLIENT_ID=your_client_id API_SECRET=your_secret ``` Start ngrok in a separate terminal to receive webhooks: ```bash theme={null} ngrok http 3000 ``` Copy the `https://...ngrok-free.dev` URL into `.env`: ``` NGROK_URL=https://your-tunnel.ngrok-free.dev ``` Run the app: ```bash theme={null} npm start # Express server on :3000 npm run dev # Vite dev server on :5173 ``` Open `http://localhost:5173` and pick a demo. ### Choose a demo | Demo | Pattern | Products | | ---------------------------------------------------------------- | -------------------------------------------------------------------------------- | ------------------- | | [**Application**](/developers/demos/application) | [Embedded Orders](/developers/integration/embedded-orders/overview) | VOIE, VOE, VOA | | [**Follow-up**](/developers/demos/follow-up) | [Embedded Orders](/developers/integration/embedded-orders/overview) (multi-task) | VOIE, VOE, VOA | | [**Consumer Credit**](/developers/demos/consumer-credit) | [Bridge Widget](/developers/integration/bridge-widget/overview) | DDS, PLL, VOIE | | [**Verifier Portal**](/developers/demos/verifier-portal) | [Hosted Orders](/developers/integration/hosted-orders/new-user) | VOIE, VOE | | [**Document Processing**](/developers/demos/document-processing) | [Document Processing](/developers/integration/document-processing) | Document extraction | ### Which demo fits your use case? | If you're building… | Start with | | -------------------------------------------- | ---------------------------------------------------------------------------------------------------- | | Mortgage origination (purchase, refi, HELOC) | [Application](/developers/demos/application) | | Consumer lending (auto, personal, BNPL) | [Application](/developers/demos/application) | | Co-borrower or multi-product verification | [Follow-up](/developers/demos/follow-up) | | Account funding / direct deposit capture | [Consumer Credit](/developers/demos/consumer-credit) | | Earned wage access or loan repayment | [Consumer Credit](/developers/demos/consumer-credit) | | Loan processor or caseworker portal | [Verifier Portal](/developers/demos/verifier-portal) | | Background screening / pre-employment | [Verifier Portal](/developers/demos/verifier-portal) | | Benefits eligibility (SNAP, Medicaid, TANF) | [Application](/developers/demos/application) or [Verifier Portal](/developers/demos/verifier-portal) | | Pay stub / W-2 / tax return processing | [Document Processing](/developers/demos/document-processing) | See [Test Credentials](/developers/testing/test-credentials) for sandbox login scenarios. # Android SDK Source: https://truv.com/docs/developers/sdks/android Truv Bridge SDK for Android (Kotlin) **Package:** `com.truv.sdk:android_sdk` | [Maven Central](https://central.sonatype.com/artifact/com.truv.sdk/android_sdk) | [Demo app](https://github.com/truvhq/demo-android) ## Install Add the Truv SDK to your module's `build.gradle`: ```gradle theme={null} dependencies { implementation "com.truv.sdk:android_sdk:LATEST_VERSION" } ``` Make sure `mavenCentral()` is included in your project's repository configuration. Add the `INTERNET` permission to your `AndroidManifest.xml`: ```xml theme={null} ``` *** ## Embedded Orders Use `TruvOrderView` to embed an Order, a multi-connection verification workflow that supports multiple data sources and product types. Add to your layout XML: ```xml theme={null} ``` Or create programmatically: ```kotlin theme={null} val orderView = TruvOrderView(context) ``` Initialize and load: ```kotlin theme={null} import com.truv.models.TruvEventPayload import com.truv.models.TruvOrderEvent import com.truv.webview.TruvOrderEventsListener import com.truv.webview.TruvOrderView class MyFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { val orderView = view.findViewById(R.id.orderView) orderView.addEventListener(object : TruvOrderEventsListener { override fun onOrderEvent(event: TruvOrderEvent) { when (event) { is TruvOrderEvent.Load -> { // Order page finished loading } is TruvOrderEvent.Close -> { // User closed the Order } is TruvOrderEvent.Success -> { // A task within the Order completed successfully. // The Order is still open at this point — it may show // a success screen or a self-certification screen // depending on the configuration. } is TruvOrderEvent.Completed -> { // The entire Order is complete (all tasks finished) } } } override fun onBridgeEvent(event: TruvEventPayload) { // Fired when the user interacts with the Bridge for a // sub-order (task) within the Order. // Equivalent to TruvEventsListener.onEvent(). } }) orderView.loadOrderUrl(orderToken) } } ``` *** ## Bridge Widget Use `TruvBridgeView` for single-connection flows like Direct Deposit Switch and Paycheck Linked Lending. Add to your layout XML: ```xml theme={null} ``` Or create programmatically: ```kotlin theme={null} val bridgeView = TruvBridgeView(context) ``` Initialize and load: ```kotlin theme={null} import com.truv.models.TruvEventPayload import com.truv.models.TruvSuccessPayload import com.truv.webview.TruvBridgeView import com.truv.webview.TruvEventsListener class MyFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { val bridgeView = view.findViewById(R.id.bridgeView) bridgeView.addEventListener(object : TruvEventsListener { override fun onLoad() { // Bridge finished loading } override fun onClose() { // User closed the Bridge } override fun onSuccess(payload: TruvSuccessPayload) { // Called when the Bridge closes after a successful task. // payload.publicToken — use this to retrieve data server-side. // payload.metadata.taskId — the task identifier. } override fun onEvent(event: TruvEventPayload) { // Lifecycle event — see Bridge Events for all types. } }) bridgeView.loadBridgeTokenUrl(bridgeToken) } } ``` See [Bridge Events](/developers/sdks/bridge-events) for all event types, payloads, and error codes. *** ## Sample app Kotlin demo using the Truv Android SDK Clone the demo app from GitHub and install dependencies. Copy your **Client ID** and **Access Secret** from the [Dashboard](https://dashboard.truv.com) into the app's configuration file. Use [sandbox test credentials](/developers/testing/test-credentials) to simulate a full verification flow. Use the demo app as a reference to understand how the SDK works. Follow the implementation guide above to add Truv Bridge to your own application. Swap in production credentials in your app when ready. # Bridge Events Source: https://truv.com/docs/developers/sdks/bridge-events Complete reference for Truv Bridge JavaScript callbacks, onEvent types, event data payloads, and error codes Truv Bridge emits client-side events during the user's connection flow. These are JavaScript callbacks configured when you initialize `TruvBridge.init()`. They are distinct from [server-side webhook events](/api-reference/webhook-events). * [Callbacks](#callbacks): Responses for specific Truv Bridge actions * [Event data](#event-data): `onEvent` types and their payload shapes * [Errors](#errors): Bridge error objects, types, and codes *** ## Callbacks ```javascript theme={null} const bridge = TruvBridge.init({ bridgeToken: bridgeToken, onSuccess(publicToken, metadata) {}, // required onLoad() {}, // optional onEvent(type, payload) {}, // optional onClose() {}, // optional }) ``` | Callback | Required | Description | | ----------- | -------- | -------------------------------------------------------------------------------------------------------------------- | | `onSuccess` | Required | User successfully connected to a payroll provider and closed Bridge. Receives `publicToken` and a `metadata` object. | | `onLoad` | Optional | Truv Bridge finished loading. | | `onEvent` | Optional | A specific event occurred within Bridge. See [Event data](#event-data) for all types. | | `onClose` | Optional | Truv Bridge was closed by the user. | The Embedded Orders flow uses a different callback signature. See [Embedded Orders](/developers/integration/embedded-orders/overview) for the correct initialization pattern when using `isOrder: true`. *** ## Event data ### onEvent Types | Event Type | Payload | Description | | --------------------- | ----------------------- | --------------------------------------------------------- | | `LOAD` | None | Bridge module finished loading | | `OPEN` | `CommonEventData` | Bridge is ready and visible | | `SCREEN_VIEW` | `ScreenViewData` | A Bridge screen was viewed | | `EMPLOYER_SELECTED` | `EmployerSelectedData` | Employer or provider selected | | `DOC_UPLOAD_OPENED` | `CommonEventData` | Document upload screen opened | | `DOCUMENTS_UPLOADED` | `DocumentsUploadedData` | Specific document types uploaded | | `LINK_CREATED` | `TaskData` | User logging in as a new Link | | `LOGIN_COMPLETE` | `TaskData` | User successfully logged in | | `SUCCESS` | `TaskData` | Data successfully retrieved | | `ERROR` | `ErrorData` | Error during connection process | | `UNSUPPORTED_BROWSER` | None | Browser is not supported | | `CLOSE` | `CloseData` | Bridge was closed | | `MANUAL_DDS` | `ManualDDSData` | Manual Direct Deposit Switch (DDS) operation submitted | | `OAUTH_OPENED` | `OAuthEventData` | User redirected to OAuth login (assets/transactions only) | *** ### CommonEventData Present on `OPEN` and `DOC_UPLOAD_OPENED` events. | Field | Type | Description | | -------------- | ------ | ---------------------------------------------------------------------------------------------- | | `bridge_token` | string | The `bridge_token` passed to `TruvBridge.init` | | `product_type` | string | Product type (`income`, `employment`, `assets`, etc.). May be `undefined` if token is expired. | | `data_source` | string | Underlying data source: `payroll`, `docs`, `financial_accounts`, `tax`, or `insurance` | ```json theme={null} { "bridge_token": "b5cb1933e43043a792a9b337af5824e2", "product_type": "income", "data_source": "payroll" } ``` *** ### ScreenViewData | Field | Type | Description | | -------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------- | | `view_name` | string | Screen viewed: `SELECT_EMPLOYER`, `PROVIDER_LIST`, `PROVIDER_LOGIN`, `PROVIDER_ORG_ID`, `ERROR`, `SUCCESS`, `DOC_UPLOAD`, `DOC_UPLOAD_TYPES` | | `bridge_token` | string | The `bridge_token` passed to `TruvBridge.init` | | `product_type` | string | Product type | | `doc_type` | string | Applicable only for `DOC_UPLOAD`: `paystub`, `w2`, or `f1099` | | `data_source` | string | Underlying data source: `payroll`, `docs`, `financial_accounts`, `tax`, `scoring_attributes`, or `insurance` | ```json theme={null} { "view_name": "PROVIDER_LOGIN", "bridge_token": "b5cb1933e43043a792a9b337af5824e2", "product_type": "income", "data_source": "payroll" } ``` *** ### EmployerSelectedData | Field | Type | Description | | -------------- | ------ | -------------------------------------------------------------- | | `bridge_token` | string | The `bridge_token` passed to `TruvBridge.init` | | `product_type` | string | Product type | | `employer` | object | Employer object with `name` property. `null` if none selected. | | `provider` | string | ID of the selected provider. `null` if none selected. | | `data_source` | string | Underlying data source | ```json theme={null} { "bridge_token": "b5cb1933e43043a792a9b337af5824e2", "product_type": "income", "employer": { "name": "Acme Corp" }, "provider": "workday", "data_source": "payroll" } ``` *** ### DocumentsUploadedData | Field | Type | Description | | -------------- | ------ | ------------------------------------------------------ | | `bridge_token` | string | The `bridge_token` passed to `TruvBridge.init` | | `product_type` | string | Product type | | `doc_type` | string | Type of document uploaded: `paystub`, `w2`, or `f1099` | | `data_source` | string | Always `docs` for document upload events | ```json theme={null} { "bridge_token": "b5cb1933e43043a792a9b337af5824e2", "product_type": "income", "doc_type": "paystub", "data_source": "docs" } ``` *** ### TaskData Present on `LINK_CREATED`, `LOGIN_COMPLETE`, and `SUCCESS` events. | Field | Type | Description | | -------------- | ------ | ------------------------------------------------------------------ | | `public_token` | string | Exchange for `access_token` on your server | | `task_id` | string | Unique task identifier. Include in support tickets. | | `bridge_token` | string | The `bridge_token` passed to `TruvBridge.init` | | `product_type` | string | Product type | | `employer` | object | Employer data object. May be `undefined` for `admin` product type. | | `provider_id` | string | Unique identifier for the selected provider | | `data_source` | string | Underlying data source | ```json theme={null} { "public_token": "d80ec8255dc54c5eb7cc03ac05d18ebd", "task_id": "2b0e7a7dec1d47678fec4e02af621cc0", "bridge_token": "b5cb1933e43043a792a9b337af5824e2", "product_type": "income", "provider_id": "adp", "employer": { "name": "Acme Corp" }, "data_source": "payroll" } ``` *** ### ErrorData | Field | Type | Description | | -------------- | ------ | ------------------------------------------------------------------------------------------ | | `error` | object | Error object. See [Errors](#errors). | | `public_token` | string | Associated `public_token`. Only present if error is tied to a specific connection attempt. | | `task_id` | string | Task identifier. Include in support tickets. | | `bridge_token` | string | The `bridge_token` passed to `TruvBridge.init` | | `product_type` | string | Product type | | `data_source` | string | Underlying data source | ```json theme={null} { "error": { "error_code": "LOGIN_ERROR", "error_message": "Username or password is incorrect", "error_type": "LINK_ERROR" }, "task_id": "5ad1938450c54024bbc967a3a7dc9020", "bridge_token": "b5cb1933e43043a792a9b337af5824e2", "product_type": "income", "data_source": "payroll" } ``` *** ### CloseData | Field | Type | Description | | ---------- | ------ | ------------------------------------------------------------------------ | | `employer` | object | Employer selected before closing. `undefined` if no employer was chosen. | ```json theme={null} { "employer": { "name": "Acme Corp" } } ``` *** ### ManualDDSData | Field | Type | Description | | ------------- | ------ | ----------------------------------------------------------------------------------------- | | `action` | string | Operation type: `EMAIL`, `DOWNLOAD`, `SHARE`, or `EXTERNAL_FLOW` | | `depositType` | string | Deposit type selected: `entire`, `percent`, or `amount`. Not present for `EXTERNAL_FLOW`. | ```json theme={null} { "depositType": "entire", "action": "EMAIL" } ``` *** ### OAuthEventData | Field | Type | Description | | -------------- | ------ | ---------------------------------------------- | | `bridge_token` | string | The `bridge_token` passed to `TruvBridge.init` | | `product_type` | string | Product type | | `task_id` | string | Task identifier | | `provider_id` | string | Unique identifier for the selected provider | | `url` | string | OAuth URL the user is redirected to | ```json theme={null} { "bridge_token": "b5cb1933e43043a792a9b337af5824e2", "product_type": "assets", "provider_id": "truv_bank_oauth", "task_id": "5ad1938450c54024bbc967a3a7dc9020", "url": "https://www.truv.com/oauth-login.html?..." } ``` *** ## Errors ```json theme={null} { "error": { "error_code": "LOGIN_ERROR", "error_message": "Username or password is incorrect", "error_type": "LINK_ERROR" } } ``` Design your UX to surface login errors to borrowers in real time. When `onEvent` fires with type `ERROR` and `error_code: LOGIN_ERROR`, prompt the user to re-enter their credentials rather than silently failing. ### Error Object | Field | Type | Description | | --------------- | ------ | -------------------------- | | `error_type` | string | Category of error | | `error_code` | string | Specific error code | | `error_message` | string | Human-readable description | ### Error Types | Type | Description | | ------------ | ------------------------ | | `LINK_ERROR` | Generic link-level error | ### Error Codes | Code | Description | | ------------- | ------------------------------------- | | `ERROR` | Generic error occurred | | `LINK_EXISTS` | User's account is already connected | | `LOGIN_ERROR` | Incorrect username, password, or both | | `MFA_ERROR` | Invalid MFA input | | `NO_DATA` | User account has no data available | | `UNAVAILABLE` | Payroll provider is unreachable | *** ## Route errors to manual fallback When Bridge encounters an error, intercept it client-side and route the user to a manual verification workflow instead of dead-ending the experience. 1. **Detect the error.** Register an `onEvent` callback when initializing Truv Bridge. When `onEvent` fires with type `ERROR`, inspect the `error_code` in the payload. 2. **Close Bridge.** After capturing the error details, close the Bridge widget programmatically or wait for the user to close it via `onClose`. 3. **Route to fallback.** Based on the error type, redirect the user to your manual process -- document upload, paper form submission, or a support contact flow. | `error_code` | Meaning | Recommended fallback | | ------------- | ------------------------------- | --------------------------------------------------------------------------------------------- | | `LOGIN_ERROR` | Incorrect credentials | Prompt the user to retry. After repeated failures, offer document upload. | | `MFA_ERROR` | Invalid MFA input | Prompt the user to retry. After repeated failures, offer document upload. | | `UNAVAILABLE` | Payroll provider is unreachable | Route directly to document upload or manual process. The provider outage is not user-fixable. | | `NO_DATA` | Account has no data | Route to document upload. The connected account lacks the required records. | | `ERROR` | Generic error | Log the `task_id` for debugging. Offer document upload as a fallback. | Track which `error_code` values trigger manual fallbacks in your analytics. A high rate of `UNAVAILABLE` errors for a specific provider may indicate a temporary outage, while frequent `LOGIN_ERROR` events may point to a UX issue in your credential entry flow. Bridge errors are client-side events, distinct from server-side [webhook events](/api-reference/webhook-events) and task status changes. Use both in combination: Bridge `onEvent` for real-time UX routing, and webhooks for backend workflow orchestration. *** ## Next steps Install Truv Bridge for web and mobile Server-side event reference for task and data-object events Task status flow referenced by Bridge events Skip employer search to improve conversion # Flutter SDK Source: https://truv.com/docs/developers/sdks/flutter Truv Bridge SDK for Flutter **Package:** `truv_flutter` | [pub.dev](https://pub.dev/packages/truv_flutter) | [Demo app](https://github.com/truvhq/demo-flutter) ## Install ```bash theme={null} flutter pub add truv_flutter ``` *** ## Embedded Orders Use `TruvOrder` to embed an Order, a multi-connection verification workflow that supports multiple data sources and product types. ```dart theme={null} import 'package:flutter/widgets.dart'; import 'package:truv_flutter/truv_event.dart'; import 'package:truv_flutter/truv_flutter.dart'; class OrderScreen extends StatelessWidget { final String bridgeToken; const OrderScreen({super.key, required this.bridgeToken}); @override Widget build(BuildContext context) { return TruvOrder( bridgeToken: bridgeToken, onOrderEvent: (TruvOrderBridgeEvent event) { switch (event) { case TruvOrderBridgeLoad(): // Order page finished loading break; case TruvOrderBridgeClose(): // User closed the Order break; case TruvOrderBridgeSuccess(): // A task within the Order completed successfully. // The Order is still open at this point — it may show // a success screen or a self-certification screen // depending on the configuration. break; case TruvOrderBridgeCompleted(): // The entire Order is complete (all tasks finished) break; } }, onBridgeEvent: (TruvEventEvent event) { // Fired when the user interacts with the Bridge for a // sub-order (task) within the Order. // Equivalent to TruvBridge onEvent. }, ); } } ``` *** ## Bridge Widget Use `TruvBridge` for single-connection flows like Direct Deposit Switch and Paycheck Linked Lending. ```dart theme={null} import 'package:flutter/widgets.dart'; import 'package:truv_flutter/truv_event.dart'; import 'package:truv_flutter/truv_flutter.dart'; class BridgeScreen extends StatelessWidget { final String bridgeToken; const BridgeScreen({super.key, required this.bridgeToken}); @override Widget build(BuildContext context) { return TruvBridge( bridgeToken: bridgeToken, onEvent: (TruvEvent event) { switch (event) { case TruvEventLoad(): // Bridge finished loading break; case TruvEventClose(): // User closed the Bridge break; case TruvEventSuccess(:final publicToken, :final metadata): // Called when the Bridge closes after a successful task. // publicToken — use this to retrieve data server-side. // metadata.taskId — the task identifier. break; case TruvEventEvent(:final eventType, :final payload): // Lifecycle event — see Bridge Events for all types. break; case TruvEventError(): // An error occurred in the Bridge break; } }, ); } } ``` See [Bridge Events](/developers/sdks/bridge-events) for all event types, payloads, and error codes. *** ## Sample app Cross-platform with a single codebase Clone the demo app from GitHub and install dependencies. Copy your **Client ID** and **Access Secret** from the [Dashboard](https://dashboard.truv.com) into the app's configuration file. Use [sandbox test credentials](/developers/testing/test-credentials) to simulate a full verification flow. Use the demo app as a reference to understand how the SDK works. Follow the implementation guide above to add Truv Bridge to your own application. Swap in production credentials in your app when ready. # iOS SDK Source: https://truv.com/docs/developers/sdks/ios Truv Bridge SDK for iOS (Swift) **Package:** `TruvSDK` | [Swift Package](https://github.com/truvhq/ios-sdk) | [CocoaPods](https://cocoapods.org/pods/TruvSDK) | [Demo app](https://github.com/truvhq/demo-ios) ## Install ### Swift Package Manager 1. In Xcode, go to **File > Add Package Dependencies** 2. Enter the package URL: ``` https://github.com/truvhq/ios-sdk.git ``` 3. Select the version and add `TruvSDK` to your target ### CocoaPods [CocoaPods trunk becomes read-only on December 2, 2026](https://blog.cocoapods.org/CocoaPods-Specs-Repo/). No new library versions can be published after that date. Truv plans to stop publishing CocoaPods updates in December 2026. Swift Package Manager is recommended for new projects. Add to your `Podfile`: ```ruby theme={null} pod 'TruvSDK' ``` Then run: ```bash theme={null} pod install ``` *** ## Embedded Orders Use `TruvOrderController` to present an Order, a multi-connection verification workflow that supports multiple data sources and product types. ```swift theme={null} import TruvSDK class ViewController: UIViewController { func openOrder(token: String) { let order = TruvOrderController(token: token, delegate: self) order.modalPresentationStyle = .fullScreen present(order, animated: true) } } extension ViewController: TruvOrderDelegate { func onOrderEvent(_ event: TruvOrderEvent) { switch event { case .load: // Order page finished loading break case .close: // User closed the Order break case .success: // A task within the Order completed successfully. // The Order is still open at this point — it may show // a success screen or a self-certification screen // depending on the configuration. break case .completed: // The entire Order is complete (all tasks finished) break } } func onBridgeEvent(_ event: TruvEventPayload) { // Fired when the user interacts with the Bridge for a // sub-order (task) within the Order. // Equivalent to TruvDelegate.onEvent(.onEvent(payload)). } } ``` *** ## Bridge Widget Use `TruvBridgeController` for single-connection flows like Direct Deposit Switch and Paycheck Linked Lending. ```swift theme={null} import TruvSDK class ViewController: UIViewController { func openBridge(token: String) { let bridge = TruvBridgeController(token: token, delegate: self) bridge.modalPresentationStyle = .fullScreen present(bridge, animated: true) } } extension ViewController: TruvDelegate { func onEvent(_ event: TruvEvent) { switch event { case .onLoad: // Bridge finished loading break case .onClose: // User closed the Bridge break case .onSuccess(let payload): // Called when the Bridge closes after a successful task. // payload?.publicToken — use this to retrieve data server-side. // payload?.metadata.taskId — the task identifier. break case .onEvent(let payload): // Lifecycle event — see Bridge Events for all types. break } } } ``` See [Bridge Events](/developers/sdks/bridge-events) for all event types, payloads, and error codes. *** ## Sample app Swift demo using `TruvSDK` Clone the demo app from GitHub and install dependencies. Copy your **Client ID** and **Access Secret** from the [Dashboard](https://dashboard.truv.com) into the app's configuration file. Use [sandbox test credentials](/developers/testing/test-credentials) to simulate a full verification flow. Use the demo app as a reference to understand how the SDK works. Follow the implementation guide above to add Truv Bridge to your own application. Swap in production credentials in your app when ready. # Vanilla JS SDK Source: https://truv.com/docs/developers/sdks/javascript Truv Bridge SDK for vanilla JavaScript **Package:** `@truv/bridge` | [npm](https://www.npmjs.com/package/@truv/bridge) | [GitHub](https://github.com/truvhq) ## Install ```bash theme={null} npm install @truv/bridge ``` Or with yarn: ```bash theme={null} yarn add @truv/bridge ``` *** ## Embedded Orders Use `isOrder: true` when initializing Bridge for multi-connection verification workflows (VOIE, VOE, VOA). ```javascript theme={null} import TruvBridge from '@truv/bridge'; const bridge = TruvBridge.init({ bridgeToken: 'your_bridge_token', isOrder: true, onLoad: function () { console.log('Order page loaded'); }, onSuccess: function () { console.log('User connected all accounts'); }, onClose: function () { console.log('Order page closed'); }, onEvent: function (type, payload, source) { console.log('Event:', type, 'Source:', source); if (type === 'COMPLETED' && source === 'order') { // Order reached final state — advance the user navigateToNextStep(); } } }); bridge.open(); ``` Wait for the `COMPLETED` event with `source: "order"` before advancing the user in your application. Do **not** use `onSuccess` or `onClose` to advance. The order may still have pending connections. The `onEvent` callback receives a third `source` parameter that distinguishes order-page events from connection-widget events. **Order page events** (`source: "order"`): ```javascript theme={null} onEvent('LOAD', undefined, 'order') // Fires same time as onLoad() onEvent('CLOSE', undefined, 'order') // Fires same time as onClose() onEvent('SUCCESS', undefined, 'order') // Fires same time as onSuccess() onEvent('COMPLETED', undefined, 'order') // Fires on final state (success or skipped) ``` **Connection widget events** (`source: "bridge"`): ```javascript theme={null} onEvent(bridgeEventType, bridgeEventPayload, 'bridge'); ``` See [Bridge Events](/developers/sdks/bridge-events) for the full list of connection widget event types and payloads. ### Position The `position` parameter controls how the embedded order page is displayed. The default type is `'dialog'`. * `{ type: 'dialog' }`: The bridge appears as a dialog window, which overlays the rest of the interface and disables scrolling. * `{ type: 'inline', container: HTMLElement }`: The embedded order page is integrated within an existing element, allowing the interface to function without blocking the rest of the interface or global scrolling. Ensure that your interface functions seamlessly across various devices, particularly on mobile devices such as iPhones and Androids, including compatibility with virtual keyboards. ```javascript theme={null} const bridge = TruvBridge.init({ bridgeToken: '', isOrder: true, position: { type: 'inline', container: document.querySelector('#inline-order-container') } }); ``` There are important requirements when using inline position: 1. The container element must remain stable while the bridge is open. The container and all its parent elements must not be unmounted or moved to a different parent node. 2. You must manually close the bridge before removing the parent container, for example when navigating to another page in a single-page application without a full reload. 3. Only one bridge instance can be open on the page at a time. *** ## Bridge Widget Use the Bridge Widget flow (without `isOrder`) for single-connection flows like Direct Deposit Switch and Paycheck Linked Lending. ```javascript theme={null} import TruvBridge from '@truv/bridge'; const bridge = TruvBridge.init({ bridgeToken: 'your_bridge_token', onSuccess: (publicToken, metaData) => { console.log('public_token:', publicToken); // Send publicToken to your backend for exchange }, onClose: () => { console.log('Widget closed'); } }); bridge.open(); ``` # React SDK Source: https://truv.com/docs/developers/sdks/react Truv Bridge SDK for React **Package:** `@truv/react` | [npm](https://www.npmjs.com/package/@truv/react) | [GitHub](https://github.com/truvhq) ## Install ```bash theme={null} npm install @truv/react ``` Or with yarn: ```bash theme={null} yarn add @truv/react ``` *** ## Embedded Orders Use `isOrder={true}` when rendering the Bridge component for multi-connection verification workflows (VOIE, VOE, VOA). ```jsx theme={null} import { useState } from 'react'; import { TruvBridge } from '@truv/react'; function VerificationFlow({ bridgeToken }) { const [isOpen, setIsOpen] = useState(false); return ( <> setIsOpen(false)} onSuccess={() => { console.log('User connected all accounts'); }} onEvent={(type, payload, source) => { if (type === 'COMPLETED' && source === 'order') { navigateToNextStep(); } }} /> ); } ``` Wait for the `COMPLETED` event with `source: "order"` before advancing the user in your application. Do **not** use `onSuccess` or `onClose` to advance. The order may still have pending connections. The `onEvent` callback receives a third `source` parameter. See [Bridge Events](/developers/sdks/bridge-events) for all event types, payloads, and error codes. *** ## Bridge Widget Use the Bridge component without `isOrder` for single-connection flows like Direct Deposit Switch and Paycheck Linked Lending. ```jsx theme={null} import { useState } from 'react'; import { TruvBridge } from '@truv/react'; function DepositSwitch({ bridgeToken }) { const [isOpen, setIsOpen] = useState(false); return ( <> setIsOpen(false)} onSuccess={(publicToken, metaData) => { console.log('public_token:', publicToken); }} /> ); } ``` # React Native SDK Source: https://truv.com/docs/developers/sdks/react-native Truv Bridge SDK for React Native **Package:** `@truv/react-native` | [npm](https://www.npmjs.com/package/@truv/react-native) | [Demo app](https://github.com/truvhq/demo-react-native) ## Install ```bash theme={null} npm install @truv/react-native ``` Or with yarn: ```bash theme={null} yarn add @truv/react-native ``` Run CocoaPods install for iOS after adding the package: ```bash theme={null} cd ios && pod install ``` *** ## Embedded Orders Use `TruvOrder` to embed an Order, a multi-connection verification workflow that supports multiple data sources and product types. ```typescript theme={null} import { FC } from 'react'; import { StyleSheet, View } from 'react-native'; import { TruvOrder, TruvEventPayload, TruvOrderEventPayload } from '@truv/react-native'; const OrderScreen: FC<{ bridgeToken: string }> = ({ bridgeToken }) => { return ( { switch (payload.eventType) { case "LOAD": // Order page finished loading break; case "CLOSE": // User closed the Order break; case "SUCCESS": // A task within the Order completed successfully. // The Order is still open at this point — it may show // a success screen or a self-certification screen // depending on the configuration. break; case "COMPLETED": // The entire Order is complete (all tasks finished) break; } }} onWidgetEvent={(payload: TruvEventPayload) => { // Fired when the user interacts with the Bridge for a // sub-order (task) within the Order. // Equivalent to TruvBridge onEvent. }} /> ); }; const styles = StyleSheet.create({ order: { flex: 1 }, }); ``` *** ## Bridge Widget Use `TruvBridge` for single-connection flows like Direct Deposit Switch and Paycheck Linked Lending. ```typescript theme={null} import { FC } from 'react'; import { StyleSheet, View } from 'react-native'; import TruvBridge, { TruvEventPayload, TruvSuccessPayload } from '@truv/react-native'; const BridgeScreen: FC<{ bridgeToken: string }> = ({ bridgeToken }) => { return ( { // Bridge finished loading }} onClose={() => { // User closed the Bridge }} onSuccess={(payload: TruvSuccessPayload) => { // Called when the Bridge closes after a successful task. // payload.publicToken — use this to retrieve data server-side. // payload.metadata.taskId — the task identifier. }} onEvent={(payload: TruvEventPayload) => { // Lifecycle event — see Bridge Events for all types. // payload.eventType — one of TruvEventType enum values }} /> ); }; const styles = StyleSheet.create({ bridge: { flex: 1 }, }); ``` See [Bridge Events](/developers/sdks/bridge-events) for all event types, payloads, and error codes. *** ## Sample app Cross-platform demo for iOS and Android Clone the demo app from GitHub and install dependencies. Copy your **Client ID** and **Access Secret** from the [Dashboard](https://dashboard.truv.com) into the app's configuration file. Use [sandbox test credentials](/developers/testing/test-credentials) to simulate a full verification flow. Use the demo app as a reference to understand how the SDK works. Follow the implementation guide above to add Truv Bridge to your own application. Swap in production credentials in your app when ready. # SSO Configuration Source: https://truv.com/docs/developers/sso Set up single sign-on with SAML 2.0, OIDC, or Azure AD Truv supports single sign-on (SSO) so your team can authenticate to the [Dashboard](/developers/dashboard) through your organization's identity provider. Once enabled, users sign in with their corporate credentials instead of a separate Truv password. SSO works with [multi-tenancy](/developers/multi-tenancy) setups. Users authenticate once and access all assigned companies. *** ## Supported protocols HTTP Redirect binding (SP → IdP) and HTTP POST binding (IdP → SP) Requires Issuer URL and Client ID. Client Secret is optional. Requires Azure AD Domain, Client ID, and Client Secret. *** ## Supported identity providers * Okta * Azure Active Directory * Google Workspace * Ping Identity * Auth0 * Custom SAML providers *** ## Benefits Manage all Dashboard access through your existing identity provider. When a user's account is deactivated at the IdP, they immediately lose Dashboard access. Enforce multi-factor authentication and conditional access policies at the IdP level. Comprehensive audit trail of all SSO authentication events for compliance. *** ## Set up SSO Contact your Technical Account Manager (TAM) to request SSO setup for your organization. Truv generates a secure self-service configuration link for your IT team to set up the connection in your IdP. Let your TAM know when the IdP configuration is complete so Truv can validate the connection. Truv activates SSO organization-wide. Production clients validate via a call; onboarding clients validate via email. Once SSO is activated, all team members authenticate through your IdP. Any MFA or conditional access policies you've configured apply automatically. *** ## User experience After SSO is enabled: 1. Users navigate to the Dashboard login page 2. They enter their work email address 3. They're redirected to your identity provider for authentication 4. After successful authentication, they're returned to the Dashboard with full access based on their [assigned role](/developers/dashboard#team-roles--permissions) *** ## Next steps Data protection, encryption, and compliance certifications Navigate the Dashboard interface API credentials and access management # Launch Checklist Source: https://truv.com/docs/developers/testing/launch-checklist Pre-production steps for any Truv integration Complete these steps before going live. Not all steps are required for minimal operation, but following them makes your integration more robust, secure, and maintainable. ## Production setup Email [support@truv.com](mailto:support@truv.com) to schedule a UX review session. Get tips on implementing Truv Bridge to increase conversion rates. Use the [production test providers](/developers/testing/test-credentials#testing-in-production) (Truv Payroll Provider, Truv Bank OAuth, Truv Bank non-OAuth) with sandbox credentials to validate your integration against real provider behavior. This confirms your webhook handling, error flows, and data ingestion work correctly. Walk through the full end-to-end flow as an end user: complete verification, confirm data appears in your system, test error and retry paths, and verify notifications deliver correctly. Ensure Truv Bridge matches your application's branding. Visit [Branding](https://dashboard.truv.com/app/customization/account/branding) to update colors, logo, and link expiration. Fill out your company profile in **Settings** → **Company**. Request Production keys via the [API Keys](https://dashboard.truv.com/app/development/keys) page. Configure your backend to use Production credentials. Remove Sandbox credentials from production code. Add teammates to the [Dashboard](https://dashboard.truv.com/app/settings/team) for shared access and monitoring. *** ## Bridge setup Pass a unique value for `tracking_info` when creating bridge tokens. This makes connections easy to track in the Dashboard and in your own systems. If you collect the user's employer name upfront, resolve it to a `company_mapping_id` and pass it when creating the order or bridge token. This skips the search screen and improves conversion. See [Deeplinking](/developers/integration/embedded-orders/deeplinking). Implement `onEvent` handling to provide better UX when the user closes Bridge or encounters an error. Use events to track conversion metrics. See [Bridge Events](/developers/sdks/bridge-events). *** ## Configure webhooks Add your endpoint URL in the Dashboard under **Development** → **Webhooks**. Each environment needs a separate URL. Validate the `X-WEBHOOK-SIGN` header on every incoming webhook. See [Security](/api-reference/security) for code examples in 5 languages. Your endpoint must respond within **1 second** connection timeout and **1 second** read timeout. If you need to do heavy processing, acknowledge the webhook immediately and process asynchronously. *** ## Handle errors Add retry logic for API calls to handle intermittent outages at supported institutions. Use exponential backoff. Users may not complete all connections. Process available data rather than treating partial completions as failures. Confirm that refresh orders return updated data when the session is active. Verify your system falls back to a new verification link when refresh returns `login_error` or `mfa_error`. See [Data Refresh](/developers/integration/embedded-orders/data-refresh). Track error rates by type (login\_error, mfa\_error, unavailable) to spot provider-specific issues early. *** ## Industry-specific checklists Sandbox credentials and test scenarios Sample documents for document processing testing # Test Credentials Source: https://truv.com/docs/developers/testing/test-credentials Sandbox login credentials for testing all Truv products Use these credentials when testing with Truv Bridge in sandbox mode. For additional login fields, use: **Phone:** (111)111-1111 | **Email:** [goodlogin@domain.com](mailto:goodlogin@domain.com) ## Sandbox credentials These credentials apply to all products. Use them to test authentication flows and error handling. | Username | Password | Scenario | | ------------ | ---------------- | -------------------------------------------- | | `goodlogin` | `goodpassword` | Successful login with complete data | | `goodlogin` | `no_data` | No data found after successful login | | `goodlogin` | `mfa` | **MFA flow**: enter code: **12345** | | `goodlogin` | `mfa_captcha` | **MFA flow**: enter answer: **9M4BP** | | `goodlogin` | `mfa_select` | **MFA flow**: verification method selection | | `goodlogin` | `longcheck` | **Wait state**: \~30 second processing delay | | `error.user` | `login_error` | Incorrect credentials | | `error.user` | `mfa_error` | MFA verification failed | | `error.user` | `account_locked` | Account locked by provider | | `error.user` | `unavailable` | Provider under maintenance | | `error.user` | `error` | Generic login error | | `error.user` | `config_error` | Organization ID configuration failure | These credentials are available for Income & Employment (VOIE), Employment History (VOE), Direct Deposit Switch (DDS), and Paycheck Linked Lending (PLL). | Username | Password | SSN | Scenario | | ----------------------- | -------------- | ----------- | ----------------------------------- | | `goodlogin` | `goodpassword` | 991-91-9991 | Successful login with complete data | | `goodlogin.weekly` | `goodpassword` | 991-91-9991 | Weekly pay frequency | | `goodlogin.semimonthly` | `goodpassword` | 991-91-9991 | Semi-monthly pay frequency | | `goodlogin.monthly` | `goodpassword` | 991-91-9991 | Monthly pay frequency | | `goodlogin.min-data` | `goodpassword` | 991-91-9991 | Minimal information returned | | `fulltime` | `goodpassword` | 2211 | Full-time salesperson | | `hourly.part-time` | `goodpassword` | 666382548 | Hourly part-time worker | | `partial.data` | `goodpassword` | 2222 | Partial payroll data | | `military` | `goodpassword` | 9988 | Military MyPay data | | `multiple.employments` | `goodpassword` | — | Multiple different employers | | `multiple.employments2` | `goodpassword` | 7740 | Multiple same-employer positions | | `nonactive` | `goodpassword` | 1890 | Employment with end date | | `unemployment` | `goodpassword` | 9988 | Unemployment benefits (weekly) | | `goodlogin.shift` | `goodpassword` | — | Gig worker with earned wage access | **Retirement, disability, and veterans benefits** Retirement and Disability scenarios return a sample Social Security Administration Benefits Verification Letter. Veterans Benefits return a VA Benefit Summary Letter (Veterans Affairs provider) or a retirement paystub (DFAS myPay provider). Search for the desired benefit type in Truv Bridge, select a login method, and use `goodlogin` / `goodpassword`. | Username | Password | Scenario | | ---------------------------- | -------------- | ------------------------------------------------------ | | `goodlogin` | `goodpassword` | Complete data | | `goodlogin` | `good_asset` | 30 days of data | | `goodlogin` | `low_risk` | Low risk consumer profile | | `goodlogin` | `high_risk` | High risk consumer profile | | `goodlogin.checking` | `goodpassword` | Checking | | `goodlogin.checking.savings` | `goodpassword` | Checking, Savings | | `goodlogin.card` | `goodpassword` | Checking, Savings, Credit Card | | `goodlogin.inv` | `goodpassword` | Investment | | `goodlogin.all` | `goodpassword` | Checking, Savings, Credit Card, Investment | | `goodlogin.gig` | `goodpassword` | Gig economy income | | `goodlogin.tax.credits` | `goodpassword` | Tax credits | | `goodlogin.unemployment` | `goodpassword` | Unemployment benefits | | `goodlogin.benefits` | `goodpassword` | Benefits | | `goodlogin.gov.benefits` | `goodpassword` | Government benefits | | `goodlogin.gov.employee` | `goodpassword` | Government employee | | `goodlogin.retirement` | `goodpassword` | Retirement | | `goodlogin.ewa` | `goodpassword` | Earned wage access | | `goodlogin.rental` | `goodpassword` | Rental income | | `goodlogin.interest` | `goodpassword` | Interest income | | `sit` | `goodpassword` | Certificate of Deposit, Investments (Stocks and Bonds) | *** ## Sample reports These sample PDFs show the verification reports generated for specific test credential scenarios. Use them to preview report formatting and data structure before building your integration. ### VOIE reports | Scenario | Credentials | Sample PDF | | -------------------------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------ | | Standard (bi-weekly) | `goodlogin` / `goodpassword` | [Download PDF](https://truv.com/wp-content/uploads/2025/11/report-goodlogin.pdf?v=1) | | Weekly pay frequency | `goodlogin.weekly` / `goodpassword` | [Download PDF](https://truv.com/wp-content/uploads/2025/11/report-goodlogin.weekly.pdf?v=1) | | Semi-monthly pay frequency | `goodlogin.semimonthly` / `goodpassword` | [Download PDF](https://truv.com/wp-content/uploads/2025/11/report-goodlogin.semimonthly.pdf?v=1) | | Monthly pay frequency | `goodlogin.monthly` / `goodpassword` | [Download PDF](https://truv.com/wp-content/uploads/2025/11/report-goodlogin.monthly.pdf?v=1) | To generate your own sample reports in sandbox, create an order with the desired test credentials, then retrieve the report using `GET /v1/users/{user_id}/reports/{report_id}/?fmt=pdf`. See [Sample Reports](/mortgage/testing/sample-reports) for retrieval details. For GSE-specific sample reports (Fannie Mae D1C and Freddie Mac AIM), see the dedicated test scenarios on the [Fannie Mae](/mortgage/d1c-aim/fannie-mae) and [Freddie Mac](/mortgage/d1c-aim/freddie-mac) pages. *** ## Testing in production Test scenarios are also available in production mode using the following providers. Search for them by name in Truv Bridge. | Provider | Type | Use case | | --------------------- | -------------------------------- | ------------------------------------------------------------- | | Truv Payroll Provider | Payroll | Test VOIE, VOE, DDS, and PLL flows | | Truv Bank OAuth | Financial accounts (OAuth) | Test asset and transaction flows with OAuth login | | Truv Bank non-OAuth | Financial accounts (credentials) | Test asset and transaction flows with username/password login | Use the same test credentials from the tables above. These providers return sandbox-quality data in your production environment. *** ## Refresh testing Data refreshes automatically succeed with `goodlogin` / `goodpassword`. To test a failed refresh, use `goodlogin` / `mfa_captcha` for the initial verification. The refresh will fail with `mfa_error` status. *** ## Native reset for authentication Truv Sandbox supports authentication reset workflows. Enter values in the requested fields, then use `goodlogin` credentials for MFA verification. For embedded flows, borrowers may be required to complete MFA during refresh. Use MFA credentials in the original verification and trigger a data refresh via the API to test this scenario. *** ## Native login via mobile SDKs Native logins in mobile SDKs in sandbox are available when using `Truv payroll provider`. Native login for other providers works in production mode only. *** ## Supported companies for testing The list below contains the available information for Mapping. These companies return a `company_mapping_id` value for integration. * **Facebook**: Workday * **Bank of America**: Company with single sign on * **Kroger**: Custom integration * **Fannie Mae**: ADP * **Freddie Mac**: Workday In the emulator, only sandbox companies have the correct `company_mapping_id` value. Production environments have all valid mapping information values for many large US-based organizations and data providers. # Test Documents Source: https://truv.com/docs/developers/testing/test-documents Sample PDFs for testing document processing in the sandbox When testing [Document Processing](/developers/integration/document-processing), use the sample PDFs below. Upload these documents to test successful parsing, various tax form types, and suspicious document detection. Test scenarios use the **file name** to determine results. The sandbox ignores actual file contents. Only the file name matters. ## Pay stubs | Document | Download | | ------------------- | -------------------------------------------------------------------------------------------------------------------- | | Most recent paystub | [most.recent.paystub.pdf](https://citadelid-resources.s3.us-west-2.amazonaws.com/doc_upload/most.recent.paystub.pdf) | | Next recent paystub | [next.recent.paystub.pdf](https://citadelid-resources.s3.us-west-2.amazonaws.com/doc_upload/next.recent.paystub.pdf) | | First paystub | [first.paystub.pdf](https://citadelid-resources.s3.us-west-2.amazonaws.com/doc_upload/first.paystub.pdf) | *** ## Tax documents | Document | Download | | --------- | ---------------------------------------------------------------------------------------------- | | W-2 | [w2.pdf](https://citadelid-resources.s3.us-west-2.amazonaws.com/doc_upload/w2.pdf) | | 1099-DIV | [1099div.pdf](https://citadelid-resources.s3.us-west-2.amazonaws.com/doc_upload/1099div.pdf) | | 1099-G | [1099g.pdf](https://citadelid-resources.s3.us-west-2.amazonaws.com/doc_upload/1099g.pdf) | | 1099-INT | [1099int.pdf](https://citadelid-resources.s3.us-west-2.amazonaws.com/doc_upload/1099int.pdf) | | 1099-MISC | [1099misc.pdf](https://citadelid-resources.s3.us-west-2.amazonaws.com/doc_upload/1099misc.pdf) | | 1099-NEC | [1099nec.pdf](https://citadelid-resources.s3.us-west-2.amazonaws.com/doc_upload/1099nec.pdf) | | 1099-R | [1099r.pdf](https://citadelid-resources.s3.us-west-2.amazonaws.com/doc_upload/1099r.pdf) | | SSA-1099 | [ssa1099.pdf](https://citadelid-resources.s3.us-west-2.amazonaws.com/doc_upload/ssa1099.pdf) | | 1040 | [f1040.pdf](https://citadelid-resources.s3.us-west-2.amazonaws.com/doc_upload/f1040.pdf) | For 1099 tax documents, Truv supports parsing formats from any year after 2021. This includes 1099-DIV, 1099-G, 1099-INT, 1099-MISC, 1099-NEC, and 1099-R. *** ## Volunteer documents | Document | Download | | ------------------- | --------------------------------------------------------------------------------------------------------------------- | | Volunteer letter | [volunteer\_letter.pdf](https://citadelid-resources.s3.us-west-2.amazonaws.com/doc_upload/volunteer_letter.pdf) | | Volunteer timesheet | [volunteer\_timesheet.pdf](https://citadelid-resources.s3.us-west-2.amazonaws.com/doc_upload/volunteer_timesheet.pdf) | *** ## Suspicious document detection | Scenario | Description | Downloads | | ----------------------------- | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Tampered documents** | Information is falsified or manipulated | [Tampered 1](https://citadelid-resources.s3.us-west-2.amazonaws.com/doc_upload/f1.paystub.pdf), [Tampered 2](https://citadelid-resources.s3.us-west-2.amazonaws.com/doc_upload/f2.paystub.pdf), [Tampered 3](https://citadelid-resources.s3.us-west-2.amazonaws.com/doc_upload/f3.paystub.pdf) | | **Different SSNs** | Personal information is inconsistent across documents | [SSN 1](https://citadelid-resources.s3.us-west-2.amazonaws.com/doc_upload/ssn1.paystub.pdf), [SSN 2](https://citadelid-resources.s3.us-west-2.amazonaws.com/doc_upload/ssn2.paystub.pdf), [SSN 3](https://citadelid-resources.s3.us-west-2.amazonaws.com/doc_upload/ssn3.paystub.pdf) | | **Different applicant names** | Personal information is inconsistent across documents | [Applicant 1](https://citadelid-resources.s3.us-west-2.amazonaws.com/doc_upload/p1.paystub.pdf), [Applicant 2](https://citadelid-resources.s3.us-west-2.amazonaws.com/doc_upload/p2.paystub.pdf), [Applicant 3](https://citadelid-resources.s3.us-west-2.amazonaws.com/doc_upload/p3.paystub.pdf) | | **No data or invalid data** | Information is missing or unable to be parsed | [No data 1](https://citadelid-resources.s3.us-west-2.amazonaws.com/doc_upload/nd1.paystub.pdf), [No data 2](https://citadelid-resources.s3.us-west-2.amazonaws.com/doc_upload/nd2.paystub.pdf), [No data 3](https://citadelid-resources.s3.us-west-2.amazonaws.com/doc_upload/nd3.paystub.pdf) | *** ## Base64 encoding for Document Collections API The [Document Collections API](/developers/integration/document-processing) accepts base64-encoded file content when creating or uploading to a collection. To encode a test document for use with the API: ```bash theme={null} # Download a test document curl -O https://citadelid-resources.s3.us-west-2.amazonaws.com/doc_upload/most.recent.paystub.pdf # Base64 encode it base64 -i most.recent.paystub.pdf -o most.recent.paystub.b64 # Use the encoded content in your API call cat most.recent.paystub.b64 ``` Pass the base64 string as the `content` field when creating a document collection: ```json theme={null} { "files": [ { "filename": "most.recent.paystub.pdf", "content": "BASE64_ENCODED_CONTENT" } ] } ``` In sandbox mode, the **file name** determines the test scenario, not the actual content. The base64 content can be from any valid PDF — only the filename matters for sandbox behavior. # Caseworker Portal Source: https://truv.com/docs/government/integration/caseworker-portal Create verification orders and send links to clients from your caseworker system using the EmployeePortal demo Create verification orders from your caseworker system and send clients a link to complete verification on their own device. Truv delivers the link via email or SMS, tracks completion, and returns verified data through webhooks. This pattern also supports contact center agents and in-person office visits. **Integration pattern:** [Hosted Orders](/developers/integration/hosted-orders/new-user) | **Products:** VOIE, VOE, VOA | **Demo:** [EmployeePortal](https://github.com/truvhq/demo-apps) *** ## Get started Clone and run the [EmployeePortal demo](https://github.com/truvhq/demo-apps) to see the full caseworker-to-client flow working locally. ```bash theme={null} git clone https://github.com/truvhq/demo-apps.git cd demo-apps npm install && npm start ``` Open `http://localhost:5173`, select **Public Sector > Case Worker Portal**, add a test client with an email address, and send a verification request. The demo tracks order status and displays reports when the client completes Bridge. See [full setup instructions](/developers/quickstarts-overview#demo-apps) for ngrok and environment configuration. The demo follows this sequence: 1. **Create an order** — Your server sends client PII (name, email, phone) and selected products to [POST /v1/orders/](/api-reference/orders/orders_create). The response includes `order_id`, `share_url`, and `user_id`. 2. **Deliver the link** — Truv sends the `share_url` to the client via email and/or SMS automatically. For agency-managed notifications, suppress Truv emails and send the `share_url` through your own messaging system. 3. **Client completes Bridge** — The client opens the link, searches for their employer, and connects their payroll account on their own device. 4. **Receive webhooks** — Truv sends an `order-status-updated` [webhook](/api-reference/webhook-events) when verification completes. Verify the signature using the `X-Webhook-Sign` header with HMAC-SHA256. 5. **Retrieve reports** — Fetch the [VOIE report](/api-reference/user-income-and-employment-reports/users_reports) with `POST /v1/users/{user_id}/reports/` or the [assets report](/api-reference/user-asset-verification-reports/assets-report-create) with `POST /v1/users/{user_id}/assets/reports/`. Each step maps to a specific file in the demo. Use these as reference when building your integration. | Step | Demo file | API reference | | -------------------- | -------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | | Order creation | [`server/routes/orders.js`](https://github.com/truvhq/demo-apps/blob/main/server/routes/orders.js) | [POST /v1/orders/](/api-reference/orders/orders_create) | | Caseworker dashboard | [`src/demos/EmployeePortal.jsx`](https://github.com/truvhq/demo-apps/blob/main/src/demos/EmployeePortal.jsx) | [Hosted Orders](/developers/integration/hosted-orders/new-user) | | Webhook verification | [`server/webhooks.js`](https://github.com/truvhq/demo-apps/blob/main/server/webhooks.js) | [Webhook events](/api-reference/webhook-events) | | Report retrieval | [`server/routes/user-reports.js`](https://github.com/truvhq/demo-apps/blob/main/server/routes/user-reports.js) | [Income reports](/api-reference/user-income-and-employment-reports/users_reports) | *** ## Public Sector-specific configuration ### Case ID tracking Use `external_user_id` to link orders to your agency's case identifier. Group all household member orders under the same case ID for unified tracking. ```json theme={null} { "products": ["income"], "first_name": "John", "last_name": "Doe", "email": "john.doe@example.com", "phone": "4155554193", "external_user_id": "case-12345", "template_id": "YOUR_TEMPLATE_ID", "locale": "es" } ``` Pass `template_id` to apply your agency's [customized template](/developers/customization) (branding, messaging, landing page). Pass `locale` to set the client's language — see [threshold languages](/government/overview#threshold-languages) for all supported values. ### Notification delivery Choose how the client receives the verification link: | Method | Configuration | Best for | | ------------------ | ----------------------------------------------------------------------------------------- | ----------------------------------------------- | | **Truv-managed** | Include `email` and/or `phone` in the order | Automatic delivery with configurable reminders | | **Agency-managed** | Set `suppress_user_notifications: true`, use `share_url` from the response | All communications must come from state systems | | **Dashboard** | Create orders through the [Truv Dashboard](https://dashboard.truv.com) or CSV bulk upload | No code required | For agency-managed notifications, use the `short_share_url` from the order response for SMS and the full `share_url` for email. ### Household members Create a separate order for each household member. Use the same `external_user_id` to group all orders under one case. Truv sends each member their own verification link. ### Renewals and data refresh At recertification time, use the [Order Refresh API](/api-reference/orders/orders_create_refresh_order) to pull updated income and employment data from an existing order's connections. When the session is still active, the client does not need to take any action — Truv reuses the original account link and returns fresh data. #### Refresh workflow When a case is due for recertification, look up the original Truv order ID associated with the client's case record. Send a `POST` request to the original order's endpoint. Specify which product to refresh and, optionally, which employers to include. The refresh creates a **new order** with its own ID. Omit the `employers` array to refresh all connections from the original order. See the [Data Refresh guide](/developers/integration/embedded-orders/data-refresh#create-a-data-refresh-order-server-side) for the full request example. Listen for the `task-status-updated` webhook with `status: "done"` on the new order. Retrieve the refreshed report and pre-fill the caseworker review screen with updated income, employment status, and pay history. #### When refresh fails Refreshes fail when the client's session has expired or their credentials have changed. The webhook returns `login_error` or `mfa_error`. | Scenario | Cause | What to do | | ------------------------ | -------------------------------------------------- | ---------------------------------------------------------------------------------- | | **Session expired** | Payroll provider session timed out or requires MFA | Create a new order and send a fresh verification link through your renewal process | | **Credentials changed** | Client changed their payroll login password | Create a new order — the client re-authenticates through Bridge | | **Provider unavailable** | Payroll provider is temporarily down | Retry the refresh after some time | OAuth-based payroll connections typically expire after \~180 days. For programs with annual recertification cycles, plan for re-authentication on most renewals. For programs with periodic eligibility reviews, refresh success rates are significantly higher. #### Refresh limits * **3 refreshes** per connection per 24-hour period * Each refresh is billed as a separate verification #### Bulk renewals For agencies processing many renewals at once, automate refresh order creation by iterating over cases due for recertification. Check each refresh result: if it succeeds, pre-fill the caseworker screen automatically. If it fails, queue the case for a new verification link. See [Data Refresh](/developers/integration/embedded-orders/data-refresh) for the full implementation guide, including [Bridge Update Mode](/developers/integration/bridge-widget/returning-user) for re-authentication. *** ## Contact center Contact center agents use the same caseworker portal flow — create an order during the phone call and send the verification link while the client is on the line. 1. **Agent creates order** — During the call, the agent enters client details and creates an order through the Dashboard or API. 2. **Send link via SMS** — Use the `short_share_url` from the order response to send an SMS to the client's phone during the call. 3. **Client completes verification** — The client opens the link on their phone and connects their payroll or bank accounts while still on the call (or shortly after). 4. **Agent monitors status** — The Dashboard or your caseworker system shows real-time order status. The agent can confirm completion before ending the call. For contact center deployments, set `first_notification_delay_hours` to a low value (e.g., 1) so clients who don't complete during the call receive a reminder quickly. *** ## In-person QR code For office visits, generate a QR code from the order's `share_url` so clients can verify on their own phone at the office. 1. **Caseworker creates order** — Create an order via the Dashboard or API with the client's case information. 2. **Display QR code** — Generate a QR code from the `share_url` and display it on the caseworker's screen or print it. 3. **Client scans and verifies** — The client scans the QR code with their phone, opens Bridge, and connects their payroll or bank accounts. 4. **Results flow back** — Truv sends verified data through webhooks. The caseworker sees results in the Dashboard or caseworker system. QR codes work with any QR code generator — encode the `share_url` value. The same link works whether scanned from a screen or printed handout. *** ## Follow-up tasks When a client doesn't complete verification after receiving a link, configure [follow-up notifications](/developers/integration/embedded-orders/follow-up) to send automatic reminders. | Setting | Description | | -------------------------------- | --------------------------------------------------------- | | `suppress_user_notifications` | Set to `false` (default) to enable Truv-managed reminders | | `first_notification_delay_hours` | Hours to wait before the first reminder (default: 0) | For caseworker-initiated workflows, the caseworker can also manually resend the link from the Dashboard or trigger a new notification through the API. *** ## Next steps Embed verification in the client-facing portal Extract income data from uploaded documents Full implementation guide for hosted order creation and notification delivery Test with government-specific scenarios # Customer Portal Source: https://truv.com/docs/government/integration/customer-portal Embed income, employment, and asset verification in your benefits portal using the CustomerPortal demo Truv Bridge embedded in a government benefits portal Verify client income, employment, and assets in real-time by embedding Truv Bridge directly in your benefits portal. The client searches for their employer, connects their accounts, and completes verification without leaving your system. **Integration pattern:** [Embedded Orders](/developers/integration/embedded-orders/overview) | **Products:** VOIE, VOE, VOA | **Demo:** [CustomerPortal](https://github.com/truvhq/demo-apps) *** ## Get started Clone and run the [CustomerPortal demo](https://github.com/truvhq/demo-apps) to see the full client self-service flow working locally. ```bash theme={null} git clone https://github.com/truvhq/demo-apps.git cd demo-apps npm install && npm start ``` Open `http://localhost:5173`, select **Public Sector > Customer Portal**, choose a product (income, employment, or assets), and walk through a verification using sandbox credentials (`goodlogin` / `goodpassword`). See [full setup instructions](/developers/quickstarts-overview#demo-apps) for ngrok and environment configuration. The demo follows this sequence: 1. **Search for employer** — Your server calls [GET /v1/company-mappings-search/](/api-reference/companies/company_autocomplete_search) to find the client's employer by name. For asset verification, search financial institutions with [GET /v1/providers/](/api-reference/data-providers/providers-list). 2. **Create an order** — Your server sends client PII, case ID, and selected products to [POST /v1/orders/](/api-reference/orders/orders_create). The response includes a `bridge_token` and `user_id`. 3. **Initialize Bridge** — Your frontend opens [Truv Bridge](/developers/sdks/javascript) with the `bridge_token`. Set `isOrder: true` and optionally pass `companyMappingId` to [deeplink](/developers/integration/embedded-orders/deeplinking) directly to the employer. 4. **Receive webhooks** — Truv sends an `order-status-updated` [webhook](/api-reference/webhook-events) when verification completes. Verify the signature using the `X-Webhook-Sign` header with HMAC-SHA256. 5. **Retrieve reports** — Fetch the [VOIE report](/api-reference/user-income-and-employment-reports/users_reports) with `POST /v1/users/{user_id}/reports/` or the [assets report](/api-reference/user-asset-verification-reports/assets-report-create) with `POST /v1/users/{user_id}/assets/reports/`. Each step maps to a specific file in the demo. Use these as reference when building your integration. | Step | Demo file | API reference | | --------------------- | -------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | | Employer search | [`src/components/CompanySearch.jsx`](https://github.com/truvhq/demo-apps/blob/main/src/components/CompanySearch.jsx) | [Company Search](/api-reference/companies/company_autocomplete_search) | | Order creation | [`server/routes/orders.js`](https://github.com/truvhq/demo-apps/blob/main/server/routes/orders.js) | [POST /v1/orders/](/api-reference/orders/orders_create) | | Bridge initialization | [`src/demos/CustomerPortal.jsx`](https://github.com/truvhq/demo-apps/blob/main/src/demos/CustomerPortal.jsx) | [Bridge SDK](/developers/sdks/javascript) | | Webhook verification | [`server/webhooks.js`](https://github.com/truvhq/demo-apps/blob/main/server/webhooks.js) | [Webhook events](/api-reference/webhook-events) | | Report retrieval | [`server/routes/user-reports.js`](https://github.com/truvhq/demo-apps/blob/main/server/routes/user-reports.js) | [Income reports](/api-reference/user-income-and-employment-reports/users_reports) | *** ## Public Sector-specific configuration ### Case ID tracking Use `external_user_id` to link orders to your agency's case or application identifier. This enables data continuity across verifications, renewals, and household members. ```json theme={null} { "products": ["income", "assets"], "first_name": "John", "last_name": "Doe", "ssn": "222233333", "external_user_id": "case-12345", "template_id": "YOUR_TEMPLATE_ID", "locale": "es" } ``` Pass `template_id` to apply your agency's [customized template](/developers/customization) (branding, messaging, landing page). Pass `locale` to set the client's language — see [threshold languages](/government/overview#threshold-languages) for all supported values. ### Products Request the products your eligibility determination requires: | Product | Use case | Report | | ------------ | ------------------------------------------------- | ------------------------------- | | `income` | SNAP, TANF, Medicaid, housing assistance | VOIE (includes employment data) | | `employment` | Employment status confirmation, compliance checks | VOE | | `assets` | Means testing, housing assistance | VOA + Income Insights | The `income` product includes employment verification automatically. Do not pass both `income` and `employment`. ### Household members Create separate orders for each household member who needs to verify income. Use the same `external_user_id` (case ID) to group orders under one case. | Approach | How it works | Best for | | ---------------- | ------------------------------------------------------------ | ------------------------------------------ | | **Portal tasks** | Create a to-do item in the portal for each household member | Agencies with portal login for all members | | **Email / SMS** | Create an order with contact info and let Truv send the link | Agencies that collect contact consent | ### Content Security Policy If your portal uses a Content Security Policy, allow `my.truv.com` (frame-src) and `cdn.truv.com` (script-src) for Bridge to load. Missing CSP configuration is the most common cause of the widget failing to load. Check your CSP settings first if Bridge doesn't appear. ### Renewals and data refresh When a client's case is due for recertification, use the [Order Refresh API](/api-reference/orders/orders_create_refresh_order) to pull updated data from their existing payroll and bank connections. If the session is still active, the client does not need to do anything — Truv returns fresh data automatically. | Scenario | What happens | Client action | | ------------------------ | ----------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | | **Session still active** | Refresh succeeds. Your system receives updated income and employment data via webhook. Pre-fill the caseworker review screen. | None | | **Session expired** | Refresh fails with `login_error` or `mfa_error`. The client needs to re-authenticate. | Complete verification through a new link | **Recommended renewal flow:** 1. **Attempt a refresh first.** When a case is due for recertification, create a [refresh order](/api-reference/orders/orders_create_refresh_order) against the original order. This is a server-side call — no portal interaction needed. 2. **If the refresh succeeds**, route the updated data to the caseworker review screen. The client's portal can show a "Verification complete" status with no action required. 3. **If the refresh fails**, display a verification task in the client's portal. The client logs in, sees the pending task, and completes a new verification through Bridge. For programs with periodic eligibility reviews, most refreshes succeed because sessions stay active. For annual recertification, expect more re-authentication. Plan your portal UX for both paths. See [Data Refresh](/developers/integration/embedded-orders/data-refresh) for the full implementation guide, including refresh limits (3 per connection per 24 hours) and failure handling. ### Self-certification Enable [self-certification](/developers/integration/embedded-orders/self-certification) to let clients review and confirm retrieved income and employment data before submission. After verification, the client sees their data and marks it as representative or flags discrepancies. Self-certification is especially useful for: * Clients with multiple income sources or irregular pay * Self-employed clients confirming bank transaction data * Programs that require client attestation Retrieve certification results from the [certifications endpoint](/api-reference/orders/orders_certifications_results) after the order completes. ### Email and SMS link delivery For cases where the client verifies outside your portal (e.g., a caseworker sends a link during an office visit or phone call), you can embed the Truv verification link in your own communications: | Field | Use | | ----------------- | ------------------------------ | | `share_url` | Full URL for email links | | `short_share_url` | Shortened URL for SMS messages | To use your own email/SMS system instead of Truv's, set `suppress_user_notifications: true` in the order's `notification_settings` and deliver the `share_url` yourself. Order links expire based on your template configuration. To configure link expiry, set the expiration in your [template settings](/developers/customization) or pass it in the order request. ### Follow-up tasks When a client starts but doesn't complete verification, configure [follow-up notifications](/developers/integration/embedded-orders/follow-up) to bring them back. Truv sends email/SMS reminders automatically based on your `notification_settings`. | Setting | Description | | -------------------------------- | --------------------------------------------------------- | | `suppress_user_notifications` | Set to `false` (default) to enable Truv-managed reminders | | `first_notification_delay_hours` | Hours to wait before the first reminder (default: 0) | For portal-integrated workflows, you can also display incomplete verifications as pending tasks in your portal UI and let the client resume where they left off. *** ## Next steps Send verification links and ingest data into caseworker screens Skip the employer search screen for higher completion rates Test with government-specific scenarios Full implementation guide for order creation, Bridge, callbacks, and data retrieval # Document Processing Source: https://truv.com/docs/government/integration/document-processing Extract structured income data from client documents using the PSDocuments demo Extract income and employment data from pay stubs, W-2s, and tax documents uploaded by clients or caseworkers. Truv validates each document, classifies the type, and returns structured data in the same format as direct payroll connections. Document upload is built into the standard Bridge widget as a fallback. If you're using the [Customer Portal](/government/integration/customer-portal) or [Caseworker Portal](/government/integration/caseworker-portal), clients can already upload documents when they can't connect to their payroll provider. Use this page only if you need the standalone [Document Collections API](/developers/integration/document-processing) for caseworker-driven bulk uploads. **Integration pattern:** [Document Processing](/developers/integration/document-processing) | **Products:** Document extraction | **Demo:** [PSDocuments](https://github.com/truvhq/demo-apps) *** ## Get started Clone and run the [PSDocuments demo](https://github.com/truvhq/demo-apps) to see the full document upload and extraction flow working locally. ```bash theme={null} git clone https://github.com/truvhq/demo-apps.git cd demo-apps npm install && npm start ``` Open `http://localhost:5173`, select **Public Sector > Document Processing**, and process the pre-loaded test pay stubs. You can also upload your own documents. See [full setup instructions](/developers/quickstarts-overview#demo-apps) for ngrok and environment configuration. The demo follows this sequence: 1. **Create a user** — Your server calls [POST /v1/users/](/api-reference/users/users_create) with an optional `external_user_id` (case ID) to create a Truv user. 2. **Create a document collection** — Your server sends base64-encoded documents and the `user_id` to [POST /v1/documents/collections/](/api-reference/document-collections/collections_create). The response includes a `collection_id`. 3. **Poll for validation** — Your server polls [GET /v1/documents/collections//](/api-reference/document-collections/collections_retrieve) until all files reach `status: "successful"`. Truv validates readability and classifies each document type. 4. **Finalize the collection** — Your server calls [POST /v1/documents/collections//finalize/](/api-reference/document-collections/collections_finalize_create) to trigger data extraction. 5. **Receive webhooks** — Truv sends a `task-status-updated` [webhook](/api-reference/webhook-events) with `status: "done"` when extraction completes. The webhook includes a `link_id` for retrieving the report. 6. **Retrieve the report** — Fetch the income report using the `link_id` from the webhook. The extracted data follows the same schema as direct payroll connections. Each step maps to a specific file in the demo. Use these as reference when building your integration. | Step | Demo file | API reference | | -------------------- | ---------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | | Collection creation | [`server/routes/upload-documents.js`](https://github.com/truvhq/demo-apps/blob/main/server/routes/upload-documents.js) | [POST /v1/documents/collections/](/api-reference/document-collections/collections_create) | | Validation polling | [`server/routes/upload-documents.js`](https://github.com/truvhq/demo-apps/blob/main/server/routes/upload-documents.js) | [GET /v1/documents/collections//](/api-reference/document-collections/collections_retrieve) | | Upload UI | [`src/demos/PSDocuments.jsx`](https://github.com/truvhq/demo-apps/blob/main/src/demos/PSDocuments.jsx) | [Document Collections](/api-reference/document-collections/object) | | Finalization | [`server/routes/upload-documents.js`](https://github.com/truvhq/demo-apps/blob/main/server/routes/upload-documents.js) | [POST /v1/documents/collections//finalize/](/api-reference/document-collections/collections_finalize_create) | | Webhook verification | [`server/webhooks.js`](https://github.com/truvhq/demo-apps/blob/main/server/webhooks.js) | [Webhook events](/api-reference/webhook-events) | | Report retrieval | [`server/routes/upload-documents.js`](https://github.com/truvhq/demo-apps/blob/main/server/routes/upload-documents.js) | [Income reports](/api-reference/account-link-income-and-employment-reports/link_detail_reports_income) | *** ## Public Sector-specific configuration ### Government document types Benefits eligibility determinations commonly use these document types: | Document type | Use case | Fields extracted | | ----------------- | ---------------------------------------- | ----------------------------------------------- | | Pay stubs | SNAP, TANF, Medicaid income verification | Employer, gross/net pay, deductions, pay period | | W-2 forms | Annual income verification | Annual wages, federal/state taxes, employer EIN | | 1099 forms | Self-employed and gig income | Payer, non-employee compensation | | SSA-1099 | Social Security benefits | Benefit amounts, tax withholdings | | Volunteer letters | Community service hour verification | Organization, hours, dates | ### Case ID tracking Pass `external_user_id` when creating the user to link document collections to your agency's case identifier. ```json theme={null} { "external_user_id": "case-12345" } ``` ### Consistent data format Documents processed through the Document Collections API return structured data in the same schema as direct payroll connections. Use a single ingestion pipeline for both `data_source: "docs"` and `data_source: "payroll"` in your eligibility system. ### Fallback from payroll connection When a client can't connect their payroll provider through [Customer Portal](/government/integration/customer-portal) or [Caseworker Portal](/government/integration/caseworker-portal), fall back to document upload. Enable document upload in the [Truv Dashboard](https://dashboard.truv.com) to offer it directly within the Bridge widget. *** ## Next steps Embed verification in the client-facing portal Send verification links and ingest data into caseworker screens Full implementation guide for document upload, validation, and extraction Download sample pay stubs and W-2s for testing # Custom Integration Source: https://truv.com/docs/government/integration/overview Choose where to integrate Truv verification in your benefits workflow Integrate Truv income, employment, and asset verification into your agency's systems. Choose the integration channels based on who initiates verification and how the client completes it. Run a demo app locally before building. See [full setup instructions](/developers/quickstarts-overview#demo-apps) for ngrok and environment configuration. *** ## Choose your integration channels | Channel | Who initiates | How the client verifies | Demo | | ------------------------------------------------------------------------------- | ------------- | --------------------------------------------------------------------- | ----------------------------------------------------- | | [Customer Portal](/government/integration/customer-portal) | Client | Embedded Bridge widget in your benefits portal | [CustomerPortal](https://github.com/truvhq/demo-apps) | | [Caseworker Portal](/government/integration/caseworker-portal) | Caseworker | Clicks a link sent via email or SMS | [EmployeePortal](https://github.com/truvhq/demo-apps) | | [Contact Center](/government/integration/caseworker-portal#contact-center) | Phone agent | Agent sends link via SMS during the call | [EmployeePortal](https://github.com/truvhq/demo-apps) | | [In-Person Office](/government/integration/caseworker-portal#in-person-qr-code) | Caseworker | Client scans a QR code on their phone | [EmployeePortal](https://github.com/truvhq/demo-apps) | | [Renewals](/government/integration/caseworker-portal#renewals-and-data-refresh) | Automated | Data refresh from existing connections — no client action when active | — | Document upload is a fallback within any channel, not a separate integration. When a client cannot connect their payroll provider, Bridge offers document upload automatically. See [Document Processing](/government/products/document-processing) for supported document types. *** ## Combine channels Most agencies use multiple channels to reach clients across different touchpoints: * **Customer Portal + Caseworker**: Clients self-serve through the portal. Caseworkers send follow-up links to those who didn't complete verification. * **Caseworker + Contact Center + In-Person**: Caseworkers send links proactively. Contact center agents send links during calls. Office visitors scan QR codes. * **All channels + Renewals**: Use any channel for initial verification. Automate data refresh at recertification time — only re-engage clients whose sessions have expired. *** ## Next steps Embed verification in your client-facing benefits portal Send verification links, manage contact center, and in-person flows Test with government-specific scenarios Full implementation guide for order creation, Bridge, callbacks, and data retrieval # Public Sector Source: https://truv.com/docs/government/overview Income, employment, and asset verification for government programs Truv helps government agencies and social service organizations verify income, employment, and assets for benefit eligibility, program enrollment, and recertification workflows. Reduce application review time with real-time income and employment data Eliminate manual data entry, document collection, and follow-up calls Source-verified data replaces self-reported documents and transcription Clients verify in minutes from any device — no pay stubs to gather *** ## What you can verify * Current income (gross, net) * YTD earnings * Employment status and employer details * Pay frequency and history * W-2 employment and payroll-connected gig work * Self-employment and gig work income via bank transactions * Bank account balances for asset-tested programs * Non-payroll income streams (freelance, cash, family support) * Expense tracking for self-employment *** ## Common use cases Verify income and employment for: * SNAP (Supplemental Nutrition Assistance Program) * TANF (Temporary Assistance for Needy Families) * Medicaid eligibility * Housing assistance programs * Child care subsidies Covers W-2 employees, self-employed clients, and gig workers. For self-employed clients, bank transaction data captures income that payroll verification cannot reach. **Products:** `income`, `assets` Speed up enrollment for: * Low-income energy assistance (LIHEAP) * Free/reduced school lunch programs * Emergency rental assistance * Veterans benefits * Disability assistance **Products:** `income`, `assets` Automate data collection for: * Annual recertification * Periodic eligibility reviews * Change reporting * Program compliance Use the [Order Refresh API](/api-reference/orders/orders_create_refresh_order) to pull updated income and employment data at recertification time without requiring the client to re-verify. When the session has expired, send a new verification link through your renewal workflow. See the [Caseworker Portal](/government/integration/caseworker-portal#renewals-and-data-refresh) guide for the full renewal flow. **Products:** `income` with automatic refresh Verify income for clients without traditional W-2 employment: * Freelancers and independent contractors * Rideshare and delivery drivers * Home daycare, lawn care, cleaning services * Cash-paid and informal work Bank transaction data through the `assets` product makes these income streams visible. Pair with [self-certification](/developers/integration/embedded-orders/self-certification) so clients can confirm or annotate their income sources. **Products:** `income`, `assets` *** ## Integration options ### Option 1: Dashboard (No Code) Truv Dashboard and order landing page Use the Truv Dashboard to create and manage verification orders without any integration: * Create orders manually via the Dashboard UI * Send verification links to clients via email/SMS * Caseworkers can view results directly in the Dashboard * Configure [webhooks](/api-reference/webhooks/object) to automatically sync verified data to your eligibility system when verifications complete [Learn more about Dashboard integration -->](/developers/dashboard) ### Option 2: Custom Integration (Recommended) Portal with embedded order form and Truv Bridge widget Embed Truv directly into your systems for a seamless client and caseworker experience. Choose the channels that fit your workflow. Self-service verification embedded in your online benefits application Send verification links and view pre-filled data in caseworker screens Phone agents create orders and send links during the call Clients scan a QR code at the office to verify on their own device Automatic data refresh at recertification — no client action when sessions are active Document upload is a fallback within any channel, not a separate integration. When a client cannot connect their payroll provider, Bridge automatically offers document upload. See [Document Processing](/government/products/document-processing) for details. ### Channel summary | Channel | How it works | Client action | | --------------------- | ------------------------------------------------------- | --------------------------------------------------- | | **Customer Portal** | Embedded verification in the benefits application flow | Self-service during application | | **Caseworker Portal** | Caseworker creates order, Truv sends link via email/SMS | Clicks link, completes verification on their device | | **Contact Center** | Phone agent creates order during the call, sends link | Completes verification after the call | | **In-Person Office** | Client scans QR code at the office | Verifies on their phone while at the office | | **Renewals** | Automatic data refresh from existing connections | None if session is active; re-verifies if expired | *** ## Benefits for government agencies * Reduce back-and-forth for pay stubs and employment documents * Pre-fill eligibility workflows with verified data * Speed up application review for straightforward cases * Eliminate manual data entry and document collection * Automatic data updates for recertification — no client outreach needed * Staff can focus on complex cases instead of chasing documents * Source-verified data eliminates transcription errors * Real-time income data from payroll systems * Consistent data format across all channels * Reduce staff time spent on verification follow-up * Lower manual processing overhead * Reuse the same workflow for applications and renewals * No need to gather pay stubs or mail documents * Faster approval decisions * Mobile-friendly — clients verify from any device * Available in [multiple languages](#threshold-languages) * Bank transaction data captures income outside traditional payroll * Covers freelancers, gig workers, cash-paid clients * Self-certification lets clients confirm income sources *** ## Compliance & Security Review [Security](/api-reference/security-overview) for current platform security details. If your agency has additional compliance, retention, or procurement requirements, confirm them directly with Truv before rollout. [View security documentation -->](/api-reference/security-overview) *** ## Threshold languages Truv Bridge, emails, SMS messages, and landing pages support multiple languages. Pass the `locale` parameter when [creating an order](/api-reference/orders/orders_create) to set the language for the client's verification experience. | Code | Language | Code | Language | | ----- | -------- | ----- | ---------- | | `en` | English | `ko` | Korean | | `es` | Spanish | `lo` | Lao | | `ar` | Arabic | `pa` | Punjabi | | `cmn` | Mandarin | `pt` | Portuguese | | `zh` | Chinese | `ru` | Russian | | `fa` | Farsi | `so` | Somali | | `hi` | Hindi | `tl` | Tagalog | | `hmn` | Hmong | `th` | Thai | | `hy` | Armenian | `uk` | Ukrainian | | `ja` | Japanese | `vi` | Vietnamese | | `km` | Khmer | `ium` | Mien | Set the `locale` on the order to match the client's preferred language. Bridge, emails, and SMS all render in that language automatically. *** ## Template customization Customize the verification experience — Bridge widget branding, email/SMS copy, and landing page appearance — using [templates](/developers/customization). Pass `template_id` when creating an order to apply a specific template. Manage templates in the [Dashboard](https://dashboard.truv.com) under **Customization > Templates** or via the [Templates API](/api-reference/templates/object). *** ## Implementation timeline | Phase | Dashboard (No Code) | Custom Integration | | -------------- | ----------------------------------------------------------------------------------- | --------------------------------------------------------------------- | | **Setup** | Configure templates, API keys, and order workflows in the Dashboard | Implement order creation, Bridge widget, webhooks, and data ingestion | | **Testing** | Create test orders with [sandbox credentials](/developers/testing/test-credentials) | End-to-end testing with demo apps and sandbox | | **Pilot** | Run a limited rollout with real clients | Deploy to staging, validate data flow into eligibility system | | **Production** | Full rollout | Full rollout with monitoring | *** ## Get started * Quick start with no code? --> [Dashboard Integration](/developers/dashboard) * Building custom? --> Choose a channel above (Customer Portal, Caseworker Portal, Contact Center, or In-Person Office) See a working verification flow locally. [Demo setup instructions](/developers/quickstarts-overview#demo-apps). Use [sandbox credentials](/developers/testing/test-credentials) to test various income scenarios — W-2 employment, self-employment, multiple employers, SSA benefits. Deploy to production and begin running live eligibility workflows. *** ## Resources Choose your integration channels Complete API documentation Import the Postman collection for hands-on API testing Sandbox credentials and test scenarios Talk to our government solutions team [support@truv.com](mailto:support@truv.com) # Document Processing for Government Source: https://truv.com/docs/government/products/document-processing Verify client income and employment from uploaded documents when payroll connections are unavailable Verify client income and employment by processing uploaded documents. Document processing serves as a fallback when clients cannot connect to their payroll provider through Bridge, or as a tool for caseworkers who already have documents on file. It is included as part of the standard orders workflow — no separate implementation is needed when using [Customer Portal](/government/integration/customer-portal) or [Caseworker Portal](/government/integration/caseworker-portal). *** ## Benefits Verify income from paystubs, W-2s, and 1099s without requiring the client to log in Automatic detection of manipulated documents and suspicious metadata Extract employer name, pay period, gross/net pay, and tax withholdings into structured fields Returns the same income and employment data structure as a live payroll connection *** ## What you get * Gross and net pay per period * Year-to-date earnings * Pay frequency and period dates * Tax withholdings and deductions * Employer name and address * Job title and position * Employment dates * Pay basis (salary, hourly) * Document type classification * Readability verification * Suspicious document flagging * Known suspicious template detection * Paystubs * W-2 forms * 1099 tax forms (DIV, G, INT, MISC, NEC, R) * SSA-1099 * Volunteer/community service letters *** ## Government use cases Clients without traditional payroll (freelancers, gig workers, small business owners) can upload 1099s and bank statements to verify income for benefits eligibility. Caseworkers who receive documents by mail or in person can upload them through the Document Collections API for automated processing, replacing manual data entry. When a client's employer isn't supported or the payroll connection fails, document upload provides an alternative verification path within the same workflow. *** ## How to implement | Path | Code required | Best for | | ----------------------------------------------------------------------- | ------------- | ------------------------------------- | | [Document Collections API](/developers/integration/document-processing) | Custom | Caseworker-initiated, bulk processing | | [Bridge fallback](/developers/integration/bridge-widget/overview) | Minimal | Client-initiated via Customer Portal | | [Truv Dashboard](/developers/dashboard) | None | Manual upload, pilot testing | For caseworker-driven workflows, use the [Document Collections API](/developers/integration/document-processing) to upload, validate, finalize, and retrieve structured data. For client-facing portals, enable document upload as a fallback in [Truv Bridge](/developers/sdks/javascript) by setting `data_sources: ["docs"]` in the bridge token. *** ## API reference Create collections, upload files, finalize, and retrieve results Upload and process documents via the Collections API Retrieve parsed and structured data Create tokens with document upload enabled *** ## Next steps Full Document Collections API walkthrough Integrate document processing into caseworker workflows Client-facing verification with Bridge fallback Sample PDFs for sandbox testing # Income & Employment for Government Source: https://truv.com/docs/government/products/income-employment Income and employment verification for government benefits programs Income & Employment (VOIE) verification provides instant access to client income and employment data directly from payroll providers. For public sector agencies, this replaces manual pay stub collection and employer phone calls with real-time, source-verified data. ## Benefits Replace employer phone calls and paper forms with instant payroll data Connects to payroll providers covering 85%+ of US employees. See [coverage](/developers/coverage-payroll) for details. Data comes directly from payroll systems — no self-reported documents Seconds instead of days for income and employment verification *** ## What you get ### Income Data * **Current income:** Base salary, hourly rate, tips, commission, bonus, overtime * **Pay frequency:** Weekly, bi-weekly, semi-monthly, monthly * **YTD earnings:** Year-to-date gross and net pay * **Deductions:** Federal/state taxes, benefits, garnishments, child support * **Pay history:** Historical pay statements across multiple pay periods ### Employment Data * **Employer information:** Name, address, phone number, EIN * **Employment status:** Active, terminated, on leave * **Employment dates:** Start date, end date (if applicable) * **Job title:** Current position and department * **Work schedule:** Full-time, part-time, hours per week ### Documents * Pay stubs (PDF) * W-2 forms (when available) * Employment verification letter *** ## Government use cases Verify household income against program thresholds. Income & Employment verification captures all income streams, including gig work and multiple employers, giving a complete picture for means-tested programs. **Typical product:** `income` (automatically includes employment data) Determine eligibility and subsidy amounts based on verified income. Pay frequency and YTD data help normalize income across different pay schedules. **Typical product:** `income` (automatically includes employment data) Refresh income data automatically at recertification time using the [Order Refresh API](/api-reference/orders/orders_create_refresh_order). When the client's payroll session is still active, Truv pulls fresh pay statements, updated YTD earnings, and current employment status — no client action needed. If the session has expired, create a new order and send a verification link through your renewal workflow. The client re-authenticates through Bridge. For programs with periodic eligibility reviews, most refreshes succeed automatically. For annual recertification, plan for re-authentication on a larger share of cases. See [Data Refresh](/developers/integration/embedded-orders/data-refresh) for implementation details. **Typical product:** `income` (automatically includes employment data) Truv connects to the **Social Security Administration (SSA)** as a distinct provider. This covers clients whose primary income is Social Security benefits rather than payroll employment. **Benefit type classification:** The `job_title` field in the employment response identifies the specific benefit type. Values include: * `"Disability"` -- SSDI benefits * `"Survivors"` -- Survivor benefits * `"Retirement"` -- Retirement benefits **What you receive:** SSA income returns a **Benefits Verification Letter** rather than standard paystubs. This letter confirms the benefit type and monthly payment amount. Standard payroll fields like `w2s`, deductions, and pay frequency are not applicable for SSA connections. **Bank transaction fallback:** Government benefit deposits can also be detected through bank transaction analysis. Include the `assets` product in your order to capture bank-deposited benefit payments when the client cannot authenticate directly with SSA. **Sandbox testing:** In Bridge, search for SSA as the provider and authenticate with `goodlogin` / `goodpassword`. **Typical product:** `income` (automatically includes employment data) *** ## Data coverage Truv connects to payroll providers covering 85%+ of US employees, including ADP, Paychex, Workday, UKG, Paylocity, Gusto, and 100+ more. See the [coverage page](/developers/coverage-payroll) for the full provider list. ### Supported income types | Income type | How it's captured | | -------------------- | --------------------------------------------------------------------------- | | W-2 employment | Direct payroll connection | | 1099 contractors | Payroll provider connection | | Multiple employers | Client connects each employer separately | | Gig / on-demand work | Payroll connection (e.g., Uber, DoorDash) or bank transactions via `assets` | | Self-employment | Bank transactions via `assets` product | For the most complete income picture, include `income` and `assets` products in your order. The `income` product automatically includes employment data — no need to request `employment` separately. This captures W-2 payroll **and** bank-deposited income from self-employment, gig work, and other non-payroll sources. *** ## How to implement | Path | Code required | Best for | | ------------------------------------------------------------------ | ------------- | ------------------------------------------------- | | [Customer Portal](/government/integration/customer-portal) | Minimal | Self-service client verification | | [Caseworker Portal](/government/integration/caseworker-portal) | None | Caseworker-initiated orders via Dashboard | | [Document Processing](/government/integration/document-processing) | Minimal | Upload pay stubs and tax documents for extraction | *** ## Report structure ### API Response The Income & Employment response uses the `IncomeCheck` schema. The top-level object contains an `employments` array, where each entry includes nested `company`, `profile`, income fields, and `statements`. | Field | Path | Example | | -------------- | ----------------------------- | -------------------- | | Annual income | `employments[].income` | `"70000.00"` | | Income period | `employments[].income_unit` | `YEARLY` | | Pay frequency | `employments[].pay_frequency` | `BW` (Bi-Weekly) | | Employer | `employments[].company.name` | `"Acme Corporation"` | | Pay statements | `employments[].statements[]` | Array of pay stubs | | W-2 forms | `employments[].w2s[]` | Array of W-2 docs | ```json theme={null} { "id": "24d7e80942ce4ad58a93f70ce4115f5c", "status": "done", "finished_at": "2024-01-20T14:30:00Z", "access_token": "48427a36d43c4d5aa6324bc06c692456", "provider": "adp", "employments": [ { "id": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4", "income": "60000.00", "income_unit": "YEARLY", "pay_rate": "2307.69", "pay_frequency": "BW", "is_active": true, "job_title": "Medical Technician", "job_type": "F", "start_date": "2021-06-15", "original_hire_date": "2021-06-15", "company": { "name": "City General Hospital", "address": { "street": "500 Main St", "city": "Springfield", "state": "IL", "zip": "62701" }, "phone": "2175550100", "ein": "37-1234567" }, "profile": { "first_name": "Maria", "last_name": "Garcia" }, "statements": [ { "pay_date": "2024-01-19", "net_pay": "1780.00", "net_pay_ytd": "1780.00", "gross_pay": "2450.00", "gross_pay_ytd": "2450.00", "hours": "80.00", "basis_of_pay": "H" } ], "w2s": [ { "year": 2023, "wages": "58000.00", "federal_tax": "7200.00", "gross_pay": "58000.00" } ] } ] } ``` For the full schema, see the [Income & Employment reports reference](/api-reference/user-income-and-employment-reports/object). *** ## API reference Create and manage verification orders Retrieve income verification data Retrieve employment data Receive status notifications *** ## Best practices For benefits eligibility, 12 months provides enough data to calculate average monthly income and identify seasonal patterns. See the [Create Order API reference](/api-reference/orders/orders_create) for all available fields. Many benefits clients have multiple income sources: part-time jobs, gig work, seasonal employment. Include both `income` and `assets` products so clients can connect payroll **and** bank accounts in one session. If your agency already has the client's employer on file, pass a `company_mapping_id` to skip the employer search screen. This improves completion rates. [Learn more about deeplinking](/developers/integration/embedded-orders/deeplinking). Pass the `locale` parameter when creating an order to render Bridge, emails, and SMS in the client's preferred language. See [threshold languages](/government/overview#threshold-languages) for supported languages. Enable [self-certification](/developers/integration/embedded-orders/self-certification) so clients can review and confirm the income and employment data Truv retrieves. This is especially useful for clients with multiple income sources or irregular pay. *** ## Next steps Step-by-step technical setup Integration scenarios across all channels API examples and code patterns Sandbox test credentials # Assets for Government Source: https://truv.com/docs/government/products/self-employed-income Verify self-employment income, gig work, and financial assets for government programs Assets (VOA) verification connects directly to clients' bank accounts to capture income that traditional payroll verification can't reach: **self-employment, gig work, cash deposits, family support, and other non-payroll income streams**. For public sector agencies, this is the primary tool for verifying the hardest-to-document income types. Assets verification also provides account balances for asset-tested programs, replacing manual bank statement collection entirely. **Why Assets verification matters for public sector:** A significant portion of benefits clients earn income outside of traditional W-2 employment: rideshare drivers, freelancers, home daycare providers, cash-paid workers, and those receiving family assistance. Payroll verification alone misses these income streams. Assets verification captures them through bank transaction data. ## Benefits Real-time access to bank account data Data pulled from financial institutions, not self-reported Bank income analysis for clients without traditional payroll Identify business expenses alongside income for complete financial picture *** ## What you get ### Account Information * **Account type:** Checking, savings, money market, CD, investment * **Account ownership:** Verified account holder name(s) * **Current balance:** Real-time balance as of the connection date * **Available balance:** Funds currently available for withdrawal * **Account number:** Masked account number for identification ### Transaction History * **Transaction details:** Date, description, amount, credit/debit type * **Deposit identification:** Payroll deposits, government payments, transfers * **Large deposits:** Flagged for caseworker review * **History depth:** Up to 2 years (30-730 days, configurable via `days_requested`) ### Documents * Bank statements (PDF) * Account verification letter *** ## Government use cases Many clients earn income outside traditional W-2 employment: * **Self-employed:** Home daycare, lawn care, cleaning services, freelance work * **Gig economy:** Rideshare (Uber, Lyft), delivery (DoorDash, Instacart), TaskRabbit — many gig platforms are also available as payroll connections through the `income` product * **1099 contractors:** Independent contractors paid outside of payroll * **Cash and informal income:** Cash-paid work, family support, room rentals * **Government payments:** Social Security, disability, veterans benefits Bank transactions make these income streams visible and verifiable. Deposits are categorized and can be used for [self-certification](/developers/integration/embedded-orders/self-certification) workflows, giving caseworkers documented evidence of income that would otherwise require clients to self-report. **Recommended products:** `income`, `assets` (the `income` product automatically includes employment data) Many benefits programs have asset limits. Assets verification provides verified balances across all connected accounts, giving caseworkers a complete picture of a client's financial resources without collecting paper bank statements. **Typical product:** `assets` Verify that clients meet asset thresholds for Section 8, public housing, or emergency rental assistance programs. Assets verification captures checking, savings, and investment account balances. **Typical product:** `assets` For emergency programs (LIHEAP, disaster relief, emergency food assistance), Assets verification provides rapid financial verification so agencies can process applications quickly. **Typical product:** `assets` Refresh bank account balances and transaction data at recertification time using the [Order Refresh API](/api-reference/orders/orders_create_refresh_order). When the client's bank connection is still active, Truv returns updated balances and recent transactions without requiring the client to reconnect. If the connection has expired, create a new order and send a verification link through your renewal workflow. See [Data Refresh](/developers/integration/embedded-orders/data-refresh) for implementation details. **Typical product:** `assets` *** ## Data coverage ### Financial Institutions Truv connects to thousands of US banks and credit unions: | Institution Type | Examples | | ---------------- | ---------------------------------------------- | | National banks | Chase, Bank of America, Wells Fargo, Citi | | Regional banks | PNC, US Bank, TD Bank, Regions | | Credit unions | Navy Federal, State Employees CU, Pentagon FCU | | Online banks | Ally, Marcus, Discover, Capital One 360 | | Neobanks | Chime, Current, Varo | ### Supported Account Types | Account Type | Balance | Transactions | Ownership | | ---------------------- | ------- | ------------ | --------- | | Checking | Yes | Yes | Yes | | Savings | Yes | Yes | Yes | | Money market | Yes | Yes | Yes | | CD | Yes | Limited | Yes | | Investment / brokerage | Yes | Limited | Yes | *** ## How to implement | Path | Code required | Best for | | ------------------------------------------------------------------ | ------------- | ------------------------------------------------- | | [Customer Portal](/government/integration/customer-portal) | Minimal | Self-service client verification | | [Caseworker Portal](/government/integration/caseworker-portal) | None | Caseworker-initiated orders via Dashboard | | [Document Processing](/government/integration/document-processing) | Minimal | Upload pay stubs and tax documents for extraction | *** ## Report structure ### API Response The Assets response uses the `VoaApplicantReport` schema. The report contains a `links` array (one per financial institution connection), each with an `accounts` array. Each account includes `balances`, `owners`, and `transactions`. | Field | Path | Example | | --------------- | ----------------------------------------------------- | --------------------- | | Account type | `links[].accounts[].type` | `CHECKING`, `SAVINGS` | | Masked number | `links[].accounts[].mask` | `"1234"` | | Account holder | `links[].accounts[].owners[].full_name` | `"Jane Smith"` | | Current balance | `links[].accounts[].balances.current` | `"5420.75"` | | Direct deposit | `links[].accounts[].transactions[].is_direct_deposit` | `true` | ```json theme={null} { "report_id": "7d4fcb86b81a4880955beea558092391", "created_at": "2024-01-15T10:00:00Z", "completed_at": "2024-01-15T10:30:00Z", "days_requested": 60, "borrower": { "first_name": "Maria", "last_name": "Garcia" }, "links": [ { "link_id": "150491a20bdb4292bb2a2ad8554fecba", "provider": "first_national", "provider_name": "First National Bank", "accounts": [ { "id": "4d601895417c46ec99633978db12a866", "type": "CHECKING", "mask": "4521", "owners": [ { "full_name": "Maria Garcia", "email": "maria.garcia@example.com" } ], "balances": { "balance": "2340.75", "available_balance": "2240.75", "currency_code": "USD" }, "transactions": [ { "id": "txn_001", "transacted_at": "2024-01-12T00:00:00Z", "description": "DIRECT DEPOSIT - SPRINGFIELD COUNTY", "amount": "1850.00", "type": "CREDIT", "status": "POSTED" }, { "id": "txn_002", "transacted_at": "2024-01-10T00:00:00Z", "description": "VENMO - PAYMENT FROM J GARCIA", "amount": "500.00", "type": "CREDIT", "status": "POSTED" } ] }, { "id": "5e702906528d53a0bb3b3089ec23b977", "type": "SAVINGS", "mask": "4522", "owners": [ { "full_name": "Maria Garcia" } ], "balances": { "balance": "8500.00", "available_balance": "8500.00", "currency_code": "USD" }, "transactions": [] } ] } ], "summary": { "total_balance": "10840.75" } } ``` For the full schema, see the [Asset verification reports reference](/api-reference/user-asset-verification-reports/object). *** ## API reference Create and manage verification orders Retrieve asset data Financial account details Receive status notifications *** ## Expense tracking For self-employed clients, agencies often need to verify expenses alongside income to determine net self-employment income. Bank transaction data captures both sides: * **Business expenses:** Supplies, equipment, vehicle costs, subcontractor payments * **Income deposits:** Client payments, platform payouts, recurring transfers Transaction descriptions and categorization help caseworkers distinguish business expenses from personal spending. Use self-certification to let the client annotate which transactions are business-related. *** ## Best practices 60 days provides enough history to identify regular deposits, income patterns, and expenses without overwhelming the caseworker with data. Many clients have accounts at more than one institution. Allow at least 3 connections so clients can add all relevant accounts in one session. Bank transactions reveal income that payroll data doesn't capture: gig payments, family transfers, cash deposits. Request both `income` and `assets` products in one order. See the [Create Order API reference](/api-reference/orders/orders_create) for all available fields. For asset-tested programs, use the `summary.total_balance` field to quickly compare against program thresholds. Individual account details are available for caseworker review when needed. Enable [self-certification](/developers/integration/embedded-orders/self-certification) so clients can review and confirm bank transaction data. Clients who receive income outside of traditional payroll (freelance, cash, family support) can annotate their deposits to help caseworkers verify income sources. Pass the `locale` parameter when creating an order to render Bridge, emails, and SMS in the client's preferred language. See [threshold languages](/government/overview#threshold-languages) for supported languages. *** ## Next steps Step-by-step technical setup Integration scenarios across all channels API examples and code patterns Sandbox test credentials # Day 1 Certainty (D1C) Source: https://truv.com/docs/mortgage/d1c-aim/fannie-mae Day 1 Certainty validation through Desktop Underwriter for income, employment, and assets Truv is an authorized report supplier for Fannie Mae's [Desktop Underwriter](https://singlefamily.fanniemae.com/applications-technology/desktop-underwriter) (DU). Truv reports provide representation and warranty relief on validated loan components: income, employment, and assets. Truv's vendor ID is **Truv**. ## How it works ```mermaid theme={null} %%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#EBF0FD', 'primaryBorderColor': '#2C64E3', 'primaryTextColor': '#111827', 'lineColor': '#9CA3AF', 'tertiaryColor': '#FFFFFF', 'edgeLabelBackground': '#FFFFFF'}}}%% sequenceDiagram participant Borrower participant Lender participant Truv participant DU as Fannie Mae DU Lender->>Truv: Create order (VOIE + VOA) Truv->>Borrower: Launch Bridge widget Borrower->>Truv: Connect payroll & bank accounts Truv->>Lender: Webhook: verification complete Lender->>Truv: Retrieve Report ID Lender->>DU: Submit loan with Report ID DU->>Truv: Fetch report data DU->>Lender: DU Findings (D1C eligible) ``` *** ## Day 1 Certainty eligibility Official Fannie Mae resource: [Desktop Underwriter](https://singlefamily.fanniemae.com/applications-technology/desktop-underwriter) D1C provides: * **Rep and warranty relief** on income, employment, and assets * **Reduced documentation** requirements * **Free re-verifications** for up to 90 days after the initial report **"Current as of" date:** For DU, this reflects the end of period from the borrower's last pay statement. *** ## Implementation checklist Use this sequence for a production-ready Fannie Mae flow: 1. Complete your Truv integration using [LOS integrations](/mortgage/integration/los-overview) or [Custom Integration](/mortgage/integration/custom-pos) 2. Collect borrower income and, when needed, asset verification through Truv 3. Retrieve the latest `voie_report_id` and `voa_report_id` 4. Submit the Report ID into Desktop Underwriter 5. Validate DU findings and confirm Day 1 Certainty eligibility 6. If data is refreshed, use the newest Report ID for resubmission *** ## Integrate with Encompass For [ICE Encompass](/mortgage/integration/ice-encompass) clients, Truv's Report ID appears in the **Loan: GSE Additional Provider Data** screen as **Truv (Bor, CoBorr)**. ### VOIE field mapping Write the Report ID to Encompass FieldID `GSEVENDOR.X50`. For borrower and coborrower, comma-separate the Report IDs: ``` borrower_report_id,coborrower_report_id ``` ### VOA field mapping | Borrower | Coborrower | | --------------- | --------------- | | `GSEVENDOR.X37` | `GSEVENDOR.X38` | *** ## Validation checklist Confirm Truv generated the latest VOIE and VOA reports and that the borrower completed all required verifications before you submit to DU. If you use Encompass, verify `GSEVENDOR.X50`, `GSEVENDOR.X37`, and `GSEVENDOR.X38` are populated correctly before DU submission. Submit the current Report ID in Desktop Underwriter and confirm DU can retrieve the report successfully. Check for Day 1 Certainty eligibility, missing data, or any partial-validation conditions caused by incomplete borrower verification. *** ## Reference test data Use shared sandbox credentials from [Test Credentials](/developers/testing/test-credentials) and [Test Credentials](/developers/testing/test-credentials) for end-to-end borrower login testing. Use the Fannie Mae-specific accounts and report IDs below when you need DU-oriented reference data and sample PDFs. ### Borrower test accounts | Username | Password | SSN | Borrower Name | Sample Report | | ------------------- | -------------- | ------------- | --------------- | ------------------------------------------------------------------------------------ | | `firsttimeborrower` | `goodpassword` | `991-91-9991` | Alice Firstimer | [PDF](https://truv.com/wp-content/uploads/2025/01/report-firsttimeborrower.pdf?v=1) | | `fannie-test.case4` | `goodpassword` | `666-00-6666` | Pitt Rock | [PDF](https://truv.com/wp-content/uploads/2025/01/report-fannie-test.case4_.pdf?v=1) | | `fannie-test.case5` | `goodpassword` | `999-60-6666` | Suzi Builder | [PDF](https://truv.com/wp-content/uploads/2025/01/report-fannie-test.case5_.pdf?v=1) | | `fannie-test.case6` | `goodpassword` | `999-40-5000` | John Homeowner | [PDF](https://truv.com/wp-content/uploads/2025/01/report-fannie-test.case6_.pdf?v=1) | | `fannie-test.case7` | `goodpassword` | `999-42-2345` | Lucky Knowscore | [PDF](https://truv.com/wp-content/uploads/2025/01/report-fannie-test.case7_.pdf?v=1) | ### Income & employment report IDs | Report ID | SSN | Borrower | Sample Report | | ---------------------------------- | ------------- | ---------------- | ---------------------------------------------------------------------------------------------- | | `456bdef4a7e944679c613f03fea436f6` | `999-60-1111` | Homer Loanseeker | [PDF](https://truv.com/wp-content/uploads/2025/07/report-456bdef4a7e944679c613f03fea436f6.pdf) | | `57d2e327e2a5436798519917bf36a958` | `999-00-1147` | Jess Sea | [PDF](https://truv.com/wp-content/uploads/2025/07/report-57d2e327e2a5436798519917bf36a958.pdf) | | `c92799ae5fb541b29c727c35b5433b2f` | `999-00-9066` | Ann Sea | [PDF](https://truv.com/wp-content/uploads/2025/07/report-c92799ae5fb541b29c727c35b5433b2f.pdf) | | `193dba3298c140479172a8129e16c36e` | `999-60-6666` | Suzi Builder | [PDF](https://truv.com/wp-content/uploads/2025/07/report-193dba3298c140479172a8129e16c36e.pdf) | ### Assets report IDs | Report ID | SSN | Borrower | Sample Report | | ---------------------------------- | ------------- | ------------------ | ---------------------------------------------------------------------------------------------- | | `be953ec913ac4f2b9086529377e087f8` | `999-60-1111` | Homer Loanseeker | [PDF](https://truv.com/wp-content/uploads/2025/07/report-be953ec913ac4f2b9086529377e087f8.pdf) | | `394fe28b784d4f6a96a746e56c575d69` | `999-12-1234` | Patrick Purchaser | [PDF](https://truv.com/wp-content/uploads/2025/07/report-394fe28b784d4f6a96a746e56c575d69.pdf) | | `2a144c7b7af9419692ce6f1661245425` | `999-56-5678` | Lorraine Purchaser | [PDF](https://truv.com/wp-content/uploads/2025/07/report-2a144c7b7af9419692ce6f1661245425.pdf) | | `d3366e56821540f8b00cceafcfdf6944` | `999-60-6666` | Suzi Builder | [PDF](https://truv.com/wp-content/uploads/2025/07/report-d3366e56821540f8b00cceafcfdf6944.pdf) | *** ## Test in sandbox For shared sandbox setup and reusable credentials, see [Test Credentials](/developers/testing/test-credentials) and [Test Credentials](/developers/testing/test-credentials). For the mortgage-specific validation flow, see [GSE testing](/mortgage/testing/gse-testing). *** ## Next steps Freddie Mac Loan Product Advisor integration Shared report retrieval patterns and Encompass mappings Sandbox credentials and test scenarios Pre-production validation # Asset and Income Modeler (AIM) Source: https://truv.com/docs/mortgage/d1c-aim/freddie-mac Asset and Income Modeler (AIM) integration through Loan Product Advisor for income, employment, and assets Truv is an AIM service provider for Freddie Mac's Loan Product Advisor (LPA). Truv delivers automated assessment of borrower income, employment, and assets through [Asset and Income Modeler (AIM)](https://sf.freddiemac.com/tools-learning/technology-tools/our-solutions/aim-asset-income-modeler), and instant paystub and W-2 assessment through the AIM Check API. Truv's vendor ID is **Truv**. ## How it works ```mermaid theme={null} %%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#EBF0FD', 'primaryBorderColor': '#2C64E3', 'primaryTextColor': '#111827', 'lineColor': '#9CA3AF', 'tertiaryColor': '#FFFFFF', 'edgeLabelBackground': '#FFFFFF'}}}%% sequenceDiagram participant Borrower participant Lender participant Truv participant LPA as Freddie Mac LPA Lender->>Truv: Create order (VOIE + VOA) Truv->>Borrower: Launch Bridge widget Borrower->>Truv: Connect payroll & bank accounts Truv->>Lender: Webhook: verification complete Lender->>Truv: Retrieve Report ID Lender->>LPA: Submit loan with Report ID LPA->>Truv: Fetch report data (AIM) LPA->>Lender: LPA Feedback (AIM assessed) ``` *** ## AIM products Official Freddie Mac resource: [Asset and Income Modeler (AIM)](https://sf.freddiemac.com/tools-learning/technology-tools/our-solutions/aim-asset-income-modeler) ### Income and employment (AIM) Automated income and employment assessment through payroll data. LPA evaluates borrower income using Truv's VOIE report data. ### Assets (AIM) Automated asset assessment from connected bank accounts. LPA evaluates account balances, ownership, and transaction history. ### Document income (AIM Check API) For borrowers without a direct payroll connection, Truv supports the AIM Check API for instant paystub and W-2 assessment. Upload documents through [Document Processing](/developers/integration/document-processing) and submit the report to LPA. **"Current as of" date:** For LPA, this reflects the pay date of the borrower's last pay statement. *** ## Implementation checklist Use this sequence for a production-ready Freddie Mac flow: 1. Complete your Truv integration using [LOS integrations](/mortgage/integration/los-overview) or [Custom Integration](/mortgage/integration/custom-pos) 2. Collect VOIE, VOA, or AIM Check document income based on the borrower workflow 3. Retrieve the latest report identifier for the product you will submit 4. Submit the current Report ID through Loan Product Advisor 5. Review AIM feedback and confirm the result matches the loan scenario 6. If Truv data is refreshed, resubmit using the newest Report ID *** ## Integrate with Encompass For [ICE Encompass](/mortgage/integration/ice-encompass) clients, Truv's Report ID appears in the **Loan: GSE Additional Provider Data** screen under the Freddie Mac section. ### VOA field mapping | Borrower | Coborrower | | --------------- | --------------- | | `GSEVENDOR.X43` | `GSEVENDOR.X44` | ### VOIE field mapping Write the Report ID to the appropriate Encompass Freddie Mac vendor field for your implementation. *** ## Validation checklist Confirm whether the loan is using payroll-based AIM, asset-based AIM, or document-based AIM Check before retrieving the final report. Always use the latest Truv report generated for the borrower. Refreshed data creates a new Report ID and should replace older IDs in LPA submission. If you use Encompass, confirm the Freddie Mac Report ID fields are populated correctly before the loan is submitted. Validate LPA feedback for the exact loan scenario and confirm there are no partial-verification issues caused by incomplete borrower connections. *** ## Reference test data Use shared sandbox credentials from [Test Credentials](/developers/testing/test-credentials) and [Test Credentials](/developers/testing/test-credentials) for end-to-end borrower login testing. Use the Freddie Mac-specific report IDs below when you need AIM-oriented reference data and sample PDFs. ### Income & employment report IDs | Report ID | SSN | Borrower | Sample Report | | ---------------------------------- | ------------- | --------------- | ---------------------------------------------------------------------------------------------- | | `5abf3fddc6cd44a38038c0c6bfd4f26f` | `990-50-0005` | Patrick Freddie | [PDF](https://truv.com/wp-content/uploads/2025/07/report-5abf3fddc6cd44a38038c0c6bfd4f26f.pdf) | | `bf23a64ceaf74988b14570a549d0b1c8` | `990-40-0004` | Amy Freddie | [PDF](https://truv.com/wp-content/uploads/2025/07/report-bf23a64ceaf74988b14570a549d0b1c8.pdf) | | `57868adf572f46fb989adf16a30c1ebd` | `990-70-0007` | Suzi Freddie | [PDF](https://truv.com/wp-content/uploads/2025/07/report-57868adf572f46fb989adf16a30c1ebd.pdf) | | `1a531ae648254ec3a27c4e259ab507f3` | `990-11-0011` | Mom Freddie | [PDF](https://truv.com/wp-content/uploads/2025/07/report-1a531ae648254ec3a27c4e259ab507f3.pdf) | | `776f4e58b115428f94776c884c073d4d` | `990-08-0008` | Alice Freddie | [PDF](https://truv.com/wp-content/uploads/2025/07/report-776f4e58b115428f94776c884c073d4d.pdf) | | `729851aad6404bf9b30248a11445fec5` | `990-30-0003` | Andy Freddie | [PDF](https://truv.com/wp-content/uploads/2025/07/report-729851aad6404bf9b30248a11445fec5.pdf) | ### Assets report IDs | Report ID | SSN | Borrower | Sample Report | | ---------------------------------- | ------------- | ------------- | ---------------------------------------------------------------------------------------------- | | `b8aa127afb1246428f0c8868c863080b` | `990-80-0008` | Alice Freddie | [PDF](https://truv.com/wp-content/uploads/2025/07/report-b8aa127afb1246428f0c8868c863080b.pdf) | | `4f6bfd8bdc6645f199408fd2a35213c4` | `991-10-0011` | Mom Freddie | [PDF](https://truv.com/wp-content/uploads/2025/07/report-4f6bfd8bdc6645f199408fd2a35213c4.pdf) | | `cb893b4564f949bcb20eca3b05c547af` | `991-00-0010` | Dad Freddie | [PDF](https://truv.com/wp-content/uploads/2025/07/report-cb893b4564f949bcb20eca3b05c547af.pdf) | | `415d91bd02a64954a15f254a8b1bb5b5` | `990-20-0002` | Mary Freddie | [PDF](https://truv.com/wp-content/uploads/2025/07/report-415d91bd02a64954a15f254a8b1bb5b5.pdf) | | `668a2ff8101f420e94f0b04c5ada6337` | `990-10-0001` | John Freddie | [PDF](https://truv.com/wp-content/uploads/2025/07/report-668a2ff8101f420e94f0b04c5ada6337.pdf) | | `36d0a637117041c098ee39b8d8f364f1` | `990-70-0007` | Suzi Freddie | [PDF](https://truv.com/wp-content/uploads/2025/07/report-36d0a637117041c098ee39b8d8f364f1.pdf) | *** ## Test in sandbox For shared sandbox setup and reusable credentials, see [Test Credentials](/developers/testing/test-credentials) and [Test Credentials](/developers/testing/test-credentials). For the mortgage-specific validation flow, see [GSE testing](/mortgage/testing/gse-testing). *** ## Next steps Fannie Mae Desktop Underwriter integration Document-based Freddie Mac income workflow Shared report retrieval patterns and Encompass mappings Pre-production mortgage validation # BeSmartee Integration Source: https://truv.com/docs/mortgage/integration/besmartee Verify borrower income and employment within the BeSmartee digital mortgage POS platform Integrating Truv with BeSmartee allows lenders to instantly access and verify borrowers' employment and income details from authenticated payroll sources. This integration enhances the accuracy and speed of the verification process, facilitating quicker loan decisions, all within the BeSmartee point-of-sale system. Quickly verify employment and income during the borrower application Accurate data sourced directly from authenticated payroll accounts Skipped verifications become tasks in the borrower's to-do list for completion later Connected accounts monitored continuously for new payroll documents *** ## How it works During the pre-application phase, borrowers and co-borrowers are prompted to connect their payroll accounts using the **Verify Income** section of their BeSmartee loan application. Once accounts are connected, Truv reports are made available in your connected Loan Origination System (LOS) along with relevant payroll documents. If the Verify Income step is skipped, tasks are automatically assigned to the borrower or co-borrower in their to-do list to complete the verification later. Connected accounts are continuously monitored for new payroll documents, enabling up-to-date verification reports throughout the origination process. *** ## BeSmartee Setup Guide **Step 1:** Contact BeSmartee Customer Success to complete the one-time admin configuration. **Step 2:** Copy your Truv API credentials into the BeSmartee platform: * Log into the [Truv Dashboard](https://dashboard.truv.com) and navigate to **Development → API Keys** * Copy your **Client ID** and **Access Secret** Truv API Keys Dashboard **Step 3:** Configure webhooks in the Truv Dashboard: * BeSmartee utilizes webhooks to listen to events on every order from Truv and get updated statuses. * Ask your BeSmartee Customer Success representative to provide the Sandbox and Production URLs to add to the Truv Dashboard. * Once you have the URLs for both environments, navigate to **Truv Dashboard → Development → Webhooks** and add a URL for your environment. Each environment requires a specific and separate URL. BeSmartee Webhook Configuration **Step 4:** Test the full borrower flow in **Sandbox mode** using Truv's test credentials. **Step 5:** Obtain production access and confirm end-to-end setup with DU (Desktop Underwriter) and LPA (Loan Product Advisor) systems. *** ## Borrower workflow Borrowers enter their employment and income information using the **Verify Income** section of the BeSmartee application. Alternatively, they receive tasks in their **TO-DO list** prompting them to connect their accounts through Truv.