# Retrieve an employment history report for a link
Source: https://docs.truv.com/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://docs.truv.com/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://docs.truv.com/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](/api-reference/tasks/lifecycle) |
| finished\_at | string | Time when report was finished |
| completed\_at | string | ~~Time when report was completed~~ **(Deprecated, invalid datetime format)** |
| access\_token | string, null | Access token for Link to payroll provider |
| tracking\_info | string | Information passed to Truv Bridge from partner |
| is\_suspicious | boolean | Flag indicating the data from the source is suspicious (e.g. fraud detected in uploaded documents or the user's SSN does not match the data) |
| refresh\_status | string | Status of most recent refresh task |
| employments | array of objects | List of employments, see [Employments object](#employments-object) |
| pdf\_report | uri, null | Verification report in PDF format |
| provider | string | Payroll provider name |
| data\_source | string | Source of data: `payroll` - Payroll provider parsing, `docs` - User-uploaded documents, `financial_accounts` - Data from linked financial accounts |
## 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, `V` - Volunteer |
| start\_date | date | Employee's hire date |
| original\_hire\_date | date | Original hire date |
| end\_date | date | Employee's end date |
| external\_last\_updated | 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, null | 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, `M` - Monthly |
| 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://docs.truv.com/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://docs.truv.com/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 fields plus the `numbers` object, both 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 fields below plus a `numbers` object with account and routing numbers grouped by network type.
## Account object
| Attribute | Type | Description |
| :-------------- | :----------- | :----------------------------------------------------------------------------------------- |
| `id` | string | Unique ID |
| `created_at` | date-time | Timestamp when the account was created in Truv |
| `updated_at` | date-time | Timestamp when the account was updated in Truv |
| `type` | string, null | The account's type |
| `subtype` | string, null | The account's subtype |
| `mask` | string | Last 4 digits of account number |
| `nickname` | string, null | User-defined name for the account |
| `is_open` | boolean | Indicates whether the account is currently open |
| `balances` | object | Balance information, see [Balances object](/api-reference/balances/object#balances-object) |
| `provider` | string | Data provider ID |
| `provider_name` | string | Data provider name |
| `numbers` | object | Account and routing numbers grouped by network type, see [Numbers object](#numbers-object) |
## 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://docs.truv.com/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
**Protect each Link's `access_token`**
The `access_token` returned when a user connects a provider grants ongoing access to that user's data. Keep it on your backend, never in client-side code, and associate it with the user in your system. See [Bridge token best practices](/developers/best-practices/bridge-token).
***
## 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) section.
***
## Next steps
Understand orders, links, tasks, and the Truv data model
Data protection, encryption, and compliance guidelines
# List all balances
Source: https://docs.truv.com/api-reference/balances/balances-list
GET /v1/links/{link_id}/balances/
The endpoint allows developers to receive balances.
# The Balances object
Source: https://docs.truv.com/api-reference/balances/object
Current balance data for connected financial accounts.
Each balance belongs to an account. 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
The balances endpoint returns a paginated list of accounts, each with a nested `balances` object.
| Attribute | Type | Description |
| :--------- | :--------------- | :------------------------------------------------------ |
| `count` | integer | Total number of accounts |
| `next` | uri | URL of the next page of results, `null` if none |
| `previous` | uri | URL of the previous page of results, `null` if none |
| `results` | array of objects | List of accounts, see [Account object](#account-object) |
## Account object
| Attribute | Type | Description |
| :----------- | :-------- | :----------------------------------------------------------- |
| `id` | string | Unique ID |
| `created_at` | date-time | Timestamp when the account was created in Truv |
| `updated_at` | date-time | Timestamp when the account was updated in Truv |
| `type` | string | The account's type |
| `subtype` | string | The account's subtype |
| `mask` | string | Last 4 digits of account number |
| `nickname` | string | Description of account |
| `balances` | object | Balance information, see [Balances object](#balances-object) |
## Balances object
| Attribute | Type | Description |
| :------------------ | :----- | :--------------------------------------------------------------------------------- |
| `currency_code` | string | Three-character ISO 4217 currency code (e.g., `USD`) |
| `balance` | string | Current account balance (nullable) |
| `available_balance` | string | Available balance for use. `PENDING` transactions may not be reflected. (nullable) |
| `credit_limit` | string | Credit limit, `null` for non-credit accounts (nullable) |
# Endpoints
* [List all balances](/api-reference/balances/balances-list)
# Example response
```json theme={null}
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"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"
}
}
]
}
```
# Bank Account Webhook Events
Source: https://docs.truv.com/api-reference/bank-accounts/events
Webhook events for bank account creation and updates.
Subscribe to these events via [Webhooks](/api-reference/webhooks) to receive notifications when bank account data becomes available or changes during a refresh.
All webhook payloads include these common fields:
| Field | Description |
| ------------------ | ------------------------------------------ |
| `webhook_id` | Unique identifier for this webhook request |
| `event_type` | The event classification |
| `event_created_at` | Timestamp when the event occurred |
| `user_id` | Associated Truv user identifier |
All Bank Account events on this page also include these fields:
| Field | Description |
| --------------- | ------------------------------------------------------------------------------ |
| `link_id` | Identifier of the Link |
| `product` | The product the event relates to, such as `income`, `employment`, or `assets` |
| `data_source` | Source of data: `payroll`, `docs`, `insurance`, `financial_accounts`, or `tax` |
| `tracking_info` | Custom metadata passed via `bridge_token` (nullable) |
| `task_id` | The associated Task |
| `employment_id` | The associated employment record |
| `objects_count` | Number of bank accounts retrieved |
***
## 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.
```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"
}
```
***
## 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.
```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"
}
```
# List all bank accounts
Source: https://docs.truv.com/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://docs.truv.com/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, null | User-friendly account name for bank account |
| account\_type | string, null | Account type of bank account, includes two types: `C` - Checking account, `S` - Savings account |
| deposit\_type | string, null | 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, null | Deposit value of selected bank account |
| bank\_name | string, null | Bank name |
***
## Endpoints
The item below is the available endpoint.
* [List all bank accounts](/api-reference/bank-accounts/link-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"
}
]
```
# Retrieve the most recent bank income report
Source: https://docs.truv.com/api-reference/bank-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.
# The Bank Income Report Object
Source: https://docs.truv.com/api-reference/bank-income-insights/object
Find more information about bank income reports.
# Attributes
The table below has the values and descriptions of the bank income report responses.
| Attribute | Type | Description |
| :-------------- | :--------------- | :-------------------------------------------------------------------------------------------------------------------------------- |
| status | string | Status of report, possible values `success`, `processing` |
| completed\_at | date-time | Time when report was completed |
| days\_requested | int32 | Requested number of days for specified transactions |
| tracking\_info | string | Additional optional identifier passed by user |
| provider | string | Data provider identifier |
| access\_token | string | Access token of existing Link |
| companies | array of strings | List of companies person works for |
| accounts | array of objects | List of bank accounts, see [Accounts object](#accounts-object) |
| income | array of objects | List of bank income sources, see [Income object](#income-object) |
| summary | object | Bank account information summary, see [Summary object](#summary-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 object
The values in this table are for the Accounts object.
| Attribute | Type | Description |
| :---------- | :--------------- | :---------------------------------------------------------------------- |
| id | string | Unique identifier of account |
| created\_at | date-time | Date and time when account was created in Truv |
| updated\_at | date-time | Date and time when account was last updated in Truv |
| type | string | Parent type of account, example `CHECKING` or `SAVINGS` |
| subtype | string | Account subtype, example `PLAN_401_K`, `MONEY_MARKET`, or `HOME_EQUITY` |
| mask | string | Masked banking account number associated with specific account |
| nickname | string | Alternate account name |
| owners | array of objects | List of account's owners |
## Owner object
The values in this table are for the Owner object.
| Attribute | Type | Description |
| :------------- | :----- | :----------------------------------- |
| id | string | Unique identifier of the owner |
| full\_name | string | Full name of the owner |
| email | string | Email of the owner |
| phone | string | Phone of the owner |
| address | object | Address of the owner |
| relation\_type | string | Relation of the owner to the account |
## Income object
This table contains the attributes in the Income object.
Attribute
Type
Description
start\_date
date
Minimum of all dates within specific income sources in user bank accounts for days requested by client
end\_date
date
Maximum of all dates within specific income sources in user bank accounts for days requested by client
account\_id
string
Unique identifier of account
income\_description
string
Original description for underlying income transactions
income\_category
string
Income category, see [Income categories](#income-categories) for possible values and gross-up details
avg\_deposit\_amount
number
The average amount received per deposit, typically net of taxes and deductions
avg\_gross\_deposit\_amount
number
The average gross payment per deposit. Gross pay is predicted based on the transaction data
pay\_frequency
string
Frequency of direct deposit posted into bank account, see values below
`M` - Monthly\
`SM` - Semi-monthly\
`W` - Weekly\
`BW` - Bi-weekly\
`A` - Annually\
`SA` - Semi-annually\
`C`- Commission
next\_payment\_date
date
The next payment date for the income source
total\_amount
number
Total amount of earnings for the income source of the user in the summary
iso\_currency\_code
string
The ISO 4217 currency code of the amount or balance
transaction\_count
integer
Number of income transactions per end user for specific source
historical\_summary
array of objects
List of bank statements for each period, see [Historical summary object](#historical-summary-object)
### Income categories
Each income source in the report is assigned one of the following categories. For categories that support gross-up, `avg_gross_deposit_amount` contains the estimated gross payment before taxes and deductions. For categories without gross-up, `avg_gross_deposit_amount` equals `avg_deposit_amount`.
| Category | Value | Grossed up |
| :-------------------- | :---------------------- | :--------- |
| Paycheck | `PAYCHECK` | Yes |
| Retirement | `RETIREMENT` | Yes |
| Government Employment | `GOVERNMENT_EMPLOYMENT` | Yes |
| EWA Payroll | `EWA_PAYROLL` | Yes |
| Gig Economy | `GIG_ECONOMY` | No |
| Government Benefits | `GOVERNMENT_BENEFITS` | No |
| Rental | `RENTAL` | No |
| Unemployment | `UNEMPLOYMENT` | No |
| Private Benefits | `PRIVATE_BENEFITS` | No |
| Cash or Check | `CASH_OR_CHECK` | No |
| Tax Credits | `TAX_CREDITS` | No |
| P2P Transfer | `P2P_TRANSFER` | No |
### Historical summary object
The table below contains the attributes from the Historical summary object.
Attribute
Type
Description
start\_date
date
Start date of period covered in specific monthly summary, value is set to first day of month unless covered month is partial\
*NOTE: Partial months are the first month included in the summary when the requested date range does not begin with the first day of the month.*
end\_date
date
End date of period included in specific monthly summary, value is set to last day of the month unless covered month is partial\
*NOTE: Partial months are the last month included in the summary when the requested date range does not end with the last day of the month.*
total\_amount
number
Total amount of earnings for the income source of the user for the month in the summary
iso\_currency\_code
string
The ISO 4217 currency code of the amount or balance
transactions
array of objects
List of transactions, see [Transactions object](#transactions-object)
### Transactions object
View information about the attributes in the Income object below.
| Attribute | Type | Description |
| :------------------ | :------ | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| amount | string | Settled value of transaction, denominated in transactions currency as stated in `iso_currency_code`, positive value when money moves out of account and negative otherwise. |
| iso\_currency\_code | string | ISO 4217 currency code of amount or balance |
| date | date | Date transaction occurred |
| check\_number | string | Check number for transaction |
| description | string | Human-readable transaction description |
| pending | Boolean | Status of transaction as pending or not set |
| transaction\_id | string | Unique identifier of transaction |
## Summary object
View information about the attributes in the Summary object below.
| Attribute | Type | Description |
| :-------------------------- | :------ | :--------------------------------------------------------------------------------------------- |
| start\_date | date | Minimum of all dates between income sources in user bank accounts for days requested by client |
| end\_date | date | Maximum of all dates between income sources in user bank accounts for days requested by client |
| income\_sources\_count | integer | Number of income sources per end user |
| income\_categories\_count | integer | Number of income categories per end user |
| income\_transactions\_count | integer | Number of income transactions per end user |
| total\_amount | string | Total amount of earnings for user income in summary |
| iso\_currency\_code | string | ISO 4217 currency code of amount or balance |
# Endpoints
View more information about the available endpoints below.
* [Retrieves a bank income report](/api-reference/bank-income-insights/bank-income-report-retrieve)
# Example response
The JSON sample below is from the bank income response.
```json theme={null}
{
"access_token": "a1685cadf2fe4e179cf883d2c166efd0",
"accounts": [
{
"created_at": "2024-11-25T15:46:30.668062Z",
"id": "3aed25abdbc246138b84a2afd46cb05b",
"mask": "******0685",
"nickname": null,
"owners": [
{
"address": {
"city": "Redwood City",
"country": null,
"state": "CA",
"street": "35 Dry Ridge Rd",
"zip": "94062"
},
"email": "john.doe@example.com",
"full_name": "John Doe",
"id": "a43909f402f84f2392257d1e6eaf715b",
"phone": "14155554193",
"relation_type": null
}
],
"subtype": null,
"type": "CHECKING",
"updated_at": "2024-11-25T15:46:30.668073Z"
}
],
"companies": [
"string"
],
"completed_at": "2024-11-25T15:46:47.498456Z",
"days_requested": 61,
"income": [
{
"account_id": "3aed25abdbc246138b84a2afd46cb05b",
"avg_deposit_amount": "1327.84",
"avg_gross_deposit_amount": "1765.19",
"end_date": "2024-11-24",
"historical_summary": [
{
"end_date": "2024-09-30",
"iso_currency_code": "USD",
"start_date": "2024-09-25",
"total_amount": "1327.84",
"transactions": [
{
"amount": "1327.84",
"check_number": null,
"date": "2024-09-27",
"description": "string",
"iso_currency_code": "USD",
"pending": false,
"transaction_id": "c08230e3b20c4cd0b319bc5c3062ae1d"
}
]
},
{
"end_date": "2024-10-31",
"iso_currency_code": "USD",
"start_date": "2024-10-01",
"total_amount": "2655.68",
"transactions": [
{
"amount": "1327.84",
"check_number": null,
"date": "2024-10-11",
"description": "string",
"iso_currency_code": "USD",
"pending": false,
"transaction_id": "a9b3aee936e04e6788af36c467206d29"
},
{
"amount": "1327.84",
"check_number": null,
"date": "2024-10-25",
"description": "string",
"iso_currency_code": "USD",
"pending": false,
"transaction_id": "4c262810f0534067b4f86fa76873a5f8"
}
]
},
{
"end_date": "2024-11-24",
"iso_currency_code": "USD",
"start_date": "2024-11-01",
"total_amount": "2655.68",
"transactions": [
{
"amount": "1327.84",
"check_number": null,
"date": "2024-11-08",
"description": "string",
"iso_currency_code": "USD",
"pending": false,
"transaction_id": "1d1c70529fb940918bcabbb235216679"
},
{
"amount": "1327.84",
"check_number": null,
"date": "2024-11-22",
"description": "string",
"iso_currency_code": "USD",
"pending": false,
"transaction_id": "67e88c96515c40d29e454bb27d407406"
}
]
}
],
"income_category": "PAYCHECK",
"income_description": "string",
"iso_currency_code": "USD",
"pay_frequency": "BW",
"start_date": "2024-09-25",
"total_amount": "6639.20",
"transaction_count": 5
}
],
"is_suspicious": false,
"provider": "9f732f7a-b6e2-4c60-81eb-af6274f411dc",
"status": "success",
"summary": {
"end_date": "2024-11-24",
"income_categories_count": 1,
"income_sources_count": 1,
"income_transactions_count": 5,
"iso_currency_code": "USD",
"start_date": "2024-09-25",
"total_amount": "6639.20"
},
"tracking_info": null
}
```
# List all bank statements
Source: https://docs.truv.com/api-reference/bank-statements/link-bank-statements
GET /v1/links/{link_id}/bank_statements/
The endpoint returns a list of bank statement PDFs collected for the link's accounts.
# The Bridge Token object
Source: https://docs.truv.com/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://docs.truv.com/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://docs.truv.com/api-reference/companies/company_autocomplete_search
GET /v1/company-mappings-search/
The endpoint provides company search using prefix.
# Get company information
Source: https://docs.truv.com/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://docs.truv.com/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://docs.truv.com/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. Each company typically maps to one [data provider](/api-reference/data-providers/object) — the payroll system or bank that stores the data.
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` | String | Predicted success rate as a numeric string (`"0.0"`–`"1.0"`; values ≥ 0.5 indicate high success) |
| `success_rate` | String | Predicted verification success: `"high"` — expected to succeed; `"low"` — may succeed (send if the user knows their payroll provider and is confident); `"unsupported"` — payroll verification not feasible; `null` — not enough attempts to determine |
| `mapping_status` | String | Mapping to the payroll system: `"verified"` — Truv manually verified the mapped provider; `"mapped"` — a provider is mapped and the user won't select one in Bridge; `"unmapped"` — no provider mapped, the user must select one manually |
***
## 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 when creating the Bridge token. The user lands straight on the login screen for their employer. No search step needed.
```javascript theme={null}
// 1. Search for the company (the response is an array of companies)
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 company_mapping_id when creating the Bridge token (server-side),
// then initialize Truv Bridge with the returned token.
const bridgeToken = await createBridgeToken({ company_mapping_id });
TruvBridge.init({ bridgeToken }).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://docs.truv.com/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
***

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) or the [Tasks API](/api-reference/tasks/tasks_read) to track progress.
# The Data Providers object
Source: https://docs.truv.com/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`
### Supported data sources
`payroll`, `docs`, `insurance`, `financial_accounts`, `tax`, `scoring_attributes`
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 | Source of data: `payroll`, `docs`, `insurance`, `financial_accounts`, `tax`, or `scoring_attributes` |
| `logo_url` | String | URL to the provider's logo |
| `is_disabled` | Boolean, null | `true` if the provider has not implemented the queried `product_type` yet; `null` when the `product_type` query parameter is omitted |
| `success_rate` | String | Predicted verification success: `"high"` — expected to succeed; `"low"` — may succeed (send if the user knows their payroll provider and is confident); `"unsupported"` — payroll verification not feasible; `null` — not enough attempts to determine |
***
## 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://cdn.truv.com/providers/adp.svg",
"is_disabled": false,
"success_rate": "high"
}
],
"next": "",
"previous": ""
}
```
# Retrieve a data provider
Source: https://docs.truv.com/api-reference/data-providers/providers-detail
GET /v1/providers/{id}/
This endpoint retrieves a data provider.
# List all data providers
Source: https://docs.truv.com/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://docs.truv.com/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) 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.
## 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, and each Link carries its own `access_token`, so a User with multiple connections has multiple access\_tokens.
## 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.
## 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://docs.truv.com/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.
# The User Deposit Switch Object
Source: https://docs.truv.com/api-reference/dds-reports/object
Find reference information on this page for Direct Deposit Switch (DDS) reports.
Direct Deposit Switch (DDS) reports contain financial institution information from the user’s accounts. Learn more below about the data provided from reports.
# Attributes
The tables below cover the fields and descriptions from the responses.
| Attribute | Type | Description |
| :------------ | :--------------- | :------------------------------------------------------ |
| completed\_at | date-time | Timestamp when report was completed |
| links | array of objects | List of assets links, see [Links object](#links-object) |
## Links object
The attributes and descriptions below are for the Links object.
| Attribute | Type | Description |
| :--------------- | :----- | :------------------------------------------------------------------------------------------------------------------------------------------- |
| link\_id | string | Unique identifier of Link |
| tracking\_info | string | Additional optional identifier passed by user |
| access\_token | string | Access token of existing Link |
| provider | object | Provider information, see [Provider object](#provider-object) |
| deposit\_details | object | Bank account info, for Direct Deposit Switch (DDS) and Paycheck Linked Lending (PLL), see [Deposit details object](#deposit-details-object) |
### Provider object
The values in the table below are for the Provider object.
| Attribute | Type | Description |
| :-------------------------------- | :--------------- | :------------------------------------- |
| id | string | Data provider identifier |
| supported\_bank\_account\_actions | array of strings | List of supported bank account actions |
### Deposit details object
View the info for the deposit details object below.
Attribute
Type
Description
account\_number
string
Account number
account\_type
string
Account type, see possible values below
`checking` - Checking account\
`savings` - Savings account
routing\_number
string
Routing number
bank\_name
string
Bank name
deposit\_type
string
Deposit type, see possible values below
`entire` - Entire paycheck\
`percent` - Percentage of paycheck\
`amount` - Fixed amount from paycheck
deposit\_value
string
Deposit value
# Endpoint
The page below is for the available endpoint for DDS reports.
* [Retrieve a deposit switch report](/api-reference/dds-reports/dds-report-retrieve)
# Example response
The JSON below is an example DDS report response.
```json theme={null}
{
"completed_at": "2022-05-04T11:30:00Z",
"links": [
{
"link_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"tracking_info": "string",
"access_token": "99dd17074ac94aa9ace2621d657c7610",
"provider": {
"id": "adp",
"supported_bank_account_actions": [
"create"
]
},
"deposit_details": {
"account_number": "16002600",
"account_type": "checking",
"routing_number": "123456789",
"bank_name": "TD Bank",
"deposit_type": "entire",
"deposit_value": "50.00"
}
}
]
}
```
# Retrieve a direct deposit switch report for a link
Source: https://docs.truv.com/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://docs.truv.com/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://docs.truv.com/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](/api-reference/tasks/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 |
| is\_suspicious | boolean | Flag to indicate if the data from the source is suspicious. E.g. fraud detected in uploaded documents or SSN of the user does not match with the data |
| deposit\_details | object | Bank account info, for Direct Deposit Switch (DDS) and Paycheck Linked Lending (PLL), see [Deposit details object](#deposit-details-object) |
| initial\_accounts | array of objects | List of initial accounts (nullable), see [Initial accounts object](#initial-accounts-object) |
| pdf\_report | string | URL that points to the PDF file containing the report |
| employer | object, null | Employer information, see [Employer object](#employer-object) |
| provider | object | Payroll provider, see [Provider object](#provider-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 |
| account\_type | string | Account type: `checking` - Checking account, `savings` - Savings account |
| account\_name | string | Account name |
| 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 |
### Employer object
This table covers the employer object attributes.
| Attribute | Type | Description |
| :-------- | :----------- | :------------------ |
| id | string | Employer ID |
| name | string | Employer name |
| logo\_url | string, null | Employer logo image |
### Provider object
This table covers the payroll provider object attributes.
| Attribute | Type | Description |
| :-------- | :----- | :----------------------- |
| id | string | Data provider ID |
| name | string | Data provider name |
| logo\_url | string | Data provider logo image |
***
## Endpoints
Use the following endpoints to get information for Deposit Switch Reports.
* [Retrieve a direct deposit switch report for a link](/api-reference/deposit-switch/link_detail_reports_dds)
* [Retrieve a paycheck linked loan report](/api-reference/deposit-switch/link_detail_reports_pll)
***
## 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://docs.truv.com/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://docs.truv.com/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://docs.truv.com/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://docs.truv.com/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://docs.truv.com/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://docs.truv.com/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://docs.truv.com/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://docs.truv.com/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://docs.truv.com/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://docs.truv.com/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://docs.truv.com/api-reference/employment/events
Webhook events for employment data creation and updates.
Subscribe to these events via [Webhooks](/api-reference/webhooks) to receive notifications when employment data becomes available or changes during a refresh.
All webhook payloads include these common fields:
| Field | Description |
| ------------------ | ------------------------------------------ |
| `webhook_id` | Unique identifier for this webhook request |
| `event_type` | The event classification |
| `event_created_at` | Timestamp when the event occurred |
| `user_id` | Associated Truv user identifier |
All Employment events on this page also include these fields:
| Field | Description |
| --------------- | ------------------------------------------------------------------------------ |
| `link_id` | Identifier of the Link |
| `product` | The product the event relates to, such as `income`, `employment`, or `assets` |
| `data_source` | Source of data: `payroll`, `docs`, `insurance`, `financial_accounts`, or `tax` |
| `tracking_info` | Custom metadata passed via `bridge_token` (nullable) |
| `task_id` | The associated Task |
| `object_id` | The employment record ID |
***
## 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.
```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"
}
```
***
## employment-updated
Fires when employment data has changed during a refresh Task.
```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"
}
```
# List all employments
Source: https://docs.truv.com/api-reference/employment/link-employments
GET /v1/links/{link_id}/employments/
The endpoint returns a list of all employments.
# Retrieve an employment
Source: https://docs.truv.com/api-reference/employment/link-last-employment
GET /v1/links/{link_id}/employment/
Get the most recent employment data
# The Employment object
Source: https://docs.truv.com/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, `SA` - Semiannually, `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, null | 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"
}
}
```
# Errors & Rate Limits
Source: https://docs.truv.com/api-reference/errors
HTTP error codes, API error response format, task error states, Bridge error codes, and rate limiting behavior
Use the `code` field in the error response body to drive error-handling logic in your integration. The `message` field is human-readable and intended for logging and debugging.
***
## HTTP errors
### Error response format
Most error responses return an `error` object with a machine-readable `code` and a `message`:
```json theme={null}
{
"error": {
"code": "incorrect_parameters",
"message": "Incorrect request parameters",
"extra": {
"invalid-params": []
}
}
}
```
The `extra` field appears on `400` responses only. It lists the specific fields that failed validation.
`404` responses use a different shape: `{"detail": "Not Found."}` rather than the standard `error` object.
### Status codes
| Status | `error.code` | Description |
| ---------------------------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `400 Bad Request` | `incorrect_parameters` | A required field is missing, a field value is invalid, or a combination of fields is not allowed. Check `extra.invalid-params` for specifics. |
| `401 Unauthorized` | `authentication_failed` | The `X-Access-Client-Id` or `X-Access-Secret` header is missing, malformed, or the credentials do not match any key in the environment. |
| `403 Forbidden` | `not_authenticated` | Credentials are valid but do not have permission to access this resource. Common cause: using sandbox credentials against a production resource. |
| `404 Not Found` | *(see above)* | The requested resource ID does not exist or belongs to a different client. |
| `405 Method Not Allowed` | — | The HTTP method is not supported on this endpoint. Check the [API Reference](/api-reference/openapi) for the supported method. |
| `406 Not Acceptable` | — | The server can't produce a response matching the `Accept` header in your request. Truv responses are always `application/json` — remove restrictive `Accept` headers. |
| `410 Gone` | `expired_token` | A token used in the Bridge flow is no longer valid. Most often a `public_token` exchange after expiry or reuse — see the [410 Gone response example](#response-examples) for recovery. |
| `415 Unsupported Media Type` | — | The request payload format is unsupported. Set `Content-Type: application/json` and send a valid JSON body. |
| `429 Too Many Requests` | `throttled` | Request rate limit exceeded. Back off and retry. See [Rate limits](#rate-limits). |
| `500 / 502 / 503` | — | Truv-side error. Retry with exponential backoff. If errors persist, check status and contact [support@truv.com](mailto:support@truv.com). |
### Response examples
Each entry in `invalid-params` carries a `field` (the offending parameter name) and a `message` (the validation reason).
```json theme={null}
{
"error": {
"code": "incorrect_parameters",
"message": "Incorrect request parameters",
"extra": {
"invalid-params": [
{ "field": "products", "message": "This field is required." },
{ "field": "user.email", "message": "Enter a valid email address." }
]
}
}
}
```
```json theme={null}
{
"error": {
"code": "authentication_failed",
"message": "No such token"
}
}
```
```json theme={null}
{
"error": {
"code": "not_authenticated",
"message": "Authentication credentials were not provided."
}
}
```
```json theme={null}
{
"detail": "Not Found."
}
```
The most common trigger is calling `POST /v1/link-access-tokens/` with a `public_token` that was already exchanged or has aged out — `public_token` is single-use and short-lived. Less commonly, the upstream `bridge_token` has expired (valid for 6 hours from creation).
```json theme={null}
{
"error": {
"code": "expired_token",
"message": "Public token expired: 48427a36d43c4d5aa6324bc06c692456"
}
}
```
**Recovery**
| Token | Action |
| -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `public_token` expired or reused | Re-run Truv Bridge so `onSuccess` returns a fresh `public_token`, then exchange it immediately at `POST /v1/link-access-tokens/`. |
| `bridge_token` expired | Call [Create Bridge Token](/api-reference/bridge-token/users_tokens) for a new `bridge_token`, then re-initialize Bridge on the client. |
See the [`bridge_token → public_token → access_token`](/developers/best-practices/bridge-token#understand-the-token-flow) flow for the full token lifecycle.
```json theme={null}
{
"error": {
"code": "throttled",
"message": "Request was throttled."
}
}
```
***
## Rate limits
Truv applies rate limits to protect platform stability and to keep latency predictable for every customer. Limits apply per access secret key. Sandbox and production have separate keys, so their limits are tracked independently.
### Standard limits
| Surface | Limit | Scope |
| ------------------------------------- | ------------------------------------------------ | --------------------- |
| All API requests | **300 requests / minute** | Per access secret key |
| Refresh endpoints, per `access_token` | **1 initial request + 3 refreshes per 24 hours** | Per `access_token` |
The 300/minute limit covers all API requests authenticated with a given access secret key, across every endpoint. Requests over the limit return a `429 Too Many Requests` error.
The per-`access_token` refresh limit covers `POST /v1/refresh/tasks/` and `GET /v1/refresh/tasks/{task_id}/`, plus `GET /v1/links/{link_id}/` re-fetches. Requests beyond the allowed window return the error message `Refresh limit for the access_token exceeded`. See the canonical [Links](/api-reference/links/object) and [Refresh](/api-reference/refresh/object) reference pages for the per-endpoint detail.
These are the defaults for new accounts. Higher limits are available — see [Request a higher limit](#request-a-higher-limit) below.
### Handle 429 responses
When a request exceeds a rate limit, Truv returns `429 Too Many Requests` with `error.code: throttled`. The connection is not penalized — subsequent requests succeed once your traffic drops back under the limit.
Respect the `Retry-After` response header on `429` responses. The value is the number of seconds to wait before retrying. If the header is not present, fall back to exponential backoff starting at 1 second and capped at 60 seconds.
```text theme={null}
# Pseudocode — Retry-After backoff with exponential fallback (capped at 60s)
attempt = 0
loop:
response = HTTP request
if response.status != 429:
return response
retry_after = response.headers.get("Retry-After") # seconds, if Truv supplied it
fallback = min(2 ** attempt, 60) # 1, 2, 4, 8, 16, 32, 60, 60, ...
sleep(int(retry_after) if retry_after else fallback)
attempt += 1
```
Always check the response status before sleeping. The pseudocode above retries only on `429`; on `5xx` responses, [Truv-side error retry guidance](#status-codes) applies instead. On `2xx` or `4xx` other than `429`, return the response immediately — never retry blindly.
### Best practices
* **Webhooks over polling.** Polling for status changes burns through your rate limit. Subscribe to [`order-status-updated` and `task-status-updated`](/api-reference/webhooks) and only call the API when a webhook fires.
* **Stagger bulk jobs.** Spread high-volume work across time rather than bursting it, so you stay under the 300 / minute limit.
* **Refresh deliberately.** The per-`access_token` refresh limit is designed for human-paced re-verification. Programmatic refresh on every page load exhausts the limit within minutes.
* **Don't retry blindly.** Order creation is not idempotent — retrying a failed `POST /v1/orders/` creates a new Order. Store your application-level reference and de-duplicate before retrying.
### Request a higher limit
Higher limits are available on request. To request one, contact your Truv Technical Account Manager or email [support@truv.com](mailto:support@truv.com) with:
* Truv account name and environment (sandbox or production).
* Current peak RPM and target peak RPM.
* Time window when peaks occur (e.g., 7–9 PM ET on weekdays).
* Use case context — e.g., "Recertification batch — 50,000 applicants over a 4-hour window."
***
## Task error states
For all task error states, their causes, and recommended actions, see [Task Lifecycle — Error states](/api-reference/tasks/lifecycle#error-states). Subscribe to `task-status-updated` webhooks to receive error notifications in real time.
***
## Bridge errors
Truv Bridge fires client-side errors through the `onEvent` callback when `type === 'ERROR'`. These are distinct from task error states — they fire in the browser during the connection flow, not through webhooks.
```javascript theme={null}
onEvent: function(type, payload) {
if (type === 'ERROR') {
console.error(payload.error.error_code, payload.error.error_message);
}
}
```
For the full error code reference (`LOGIN_ERROR`, `MFA_ERROR`, `UNAVAILABLE`, `NO_DATA`, `LINK_EXISTS`, `ERROR`), error object shape, and recommended fallback routing, see [Bridge Events — Errors](/developers/sdks/bridge-events#errors).
***
## Document processing errors
For document upload errors — `config_error` and `no_data` messages, fraud detection, and the complete review workflow — see [Fraud & Manual Review](/developers/fraud-and-manual-review).
***
## Webhook delivery retries
For webhook timeout, retry policy, and signature verification, see [Webhooks — delivery and retries](/api-reference/webhooks).
***
## Next steps
Complete task status flow and error state transitions
Client-side error codes and fallback routing
Document fraud detection and review workflows
Real-time notifications for task and order status changes
# Identity Webhook Events
Source: https://docs.truv.com/api-reference/identity/events
Webhook events for identity profile creation and updates.
Subscribe to these events via [Webhooks](/api-reference/webhooks) to receive notifications when identity data becomes available or changes during a refresh.
All webhook payloads include these common fields:
| Field | Description |
| ------------------ | ------------------------------------------ |
| `webhook_id` | Unique identifier for this webhook request |
| `event_type` | The event classification |
| `event_created_at` | Timestamp when the event occurred |
| `user_id` | Associated Truv user identifier |
All Identity events on this page also include these fields:
| Field | Description |
| --------------- | ------------------------------------------------------------------------------ |
| `link_id` | Identifier of the Link |
| `product` | The product the event relates to, such as `income`, `employment`, or `assets` |
| `data_source` | Source of data: `payroll`, `docs`, `insurance`, `financial_accounts`, or `tax` |
| `tracking_info` | Custom metadata passed via `bridge_token` (nullable) |
| `task_id` | The associated Task |
| `object_id` | The identity profile record ID |
***
## 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.
```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"
}
```
***
## profile-updated
Fires when identity and profile information has changed during a refresh Task.
```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"
}
```
# Retrieve an identity
Source: https://docs.truv.com/api-reference/identity/link-identity
GET /v1/links/{link_id}/identity/
Get the identity data for the user
# The Identity object
Source: https://docs.truv.com/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, null | Middle initials |
| email | string, null | Email address |
| `ssn` | string | Social Security Number, full or last 4 digits |
| date\_of\_birth | date, null | 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"
}
}
```
# Create a user bank income insights report
Source: https://docs.truv.com/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://docs.truv.com/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://docs.truv.com/api-reference/income-insights/object
Find more information on data returned by the user-level Income Insights 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 |
| days\_available | integer | Days of transaction history available at report generation time, from earliest transaction to report date (inclusive) |
| 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 |
***
## Income source qualification
Truv groups a user's deposits into candidate sources and then decides which to surface as `bank_income_source` entries. Patterns that don't qualify still appear in the underlying transactions; they're just not surfaced as an income source.
Two checks gate the decision:
| Check | Rule |
| :-------- | :------------------------------------------------------------------------ |
| Recurring | A pay frequency is detected — weekly, bi-weekly, semi-monthly, or monthly |
| Current | The most recent deposit is no more than 3 pay periods old |
In practice a qualifying source needs at least 3 deposits. The "≥3" floor isn't a separate gate — it's enforced upstream by the employer-grouping step and by the pay-frequency model, both of which require at least 3 transactions before they'll emit a result.
When the source-level total and per-period average are computed, major outlier deposits are trimmed (IQR filter). This shapes the published averages but is not a qualification check — a noisy source is still surfaced.
These rules describe **regular** income. Irregular categories — `GIG_ECONOMY`, `RENTAL`, `EWA_PAYROLL`, `P2P_TRANSFER`, `TAX_CREDITS`, `CASH_OR_CHECK` — skip the Recurring check and use a relaxed Current tolerance (2 months). See the [Income category enum](#income-category-enum) for the full list.
***
## 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) |
| next\_payment\_date | date | The next payment date for the income source |
| 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. |
| avg\_deposit\_amount | string | The average amount received per deposit, typically net of taxes and deductions |
| avg\_gross\_deposit\_amount | string | The average gross payment per deposit. Gross pay is predicted based on the transaction data |
| 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. The `income_category` and `pay_frequency` fields are nullable and may return `null`.
***
## 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 |
| INTEREST | Interest income | No |
| INVESTMENT | Investment income | No |
| OTHER | Other income | No |
***
## Pay frequency enum
| Value | Pay frequency |
| :---- | :------------ |
| `M` | Monthly |
| `SM` | Semi-Monthly |
| `W` | Weekly |
| `BW` | Bi-Weekly |
| `A` | Annually |
| `SA` | Semiannually |
| `C` | Commission |
## Permissible purpose enum
A permissible purpose is required when creating an Income Insights report, passed in the `consumer_report_permissible_purpose` field. It 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](/api-reference/income-insights/income-insights-report-create)
* [Retrieve an income-insights report](/api-reference/income-insights/income-insights-report-retrieve)
# 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",
"provider_name": "Chase Bank",
"tracking_info": "string",
"accounts": [
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"mask": "****1234",
"nickname": "My account",
"type": "CHECKING",
"subtype": "MONEY_MARKET",
"days_available": 365,
"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",
"next_payment_date": "2022-06-01",
"avg_deposit_amount": "5000.00",
"avg_gross_deposit_amount": "6000.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://docs.truv.com/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://docs.truv.com/api-reference/insurance/link_detail_reports_insurance_auto
GET /v1/links/{link_id}/insurance/report/auto/
The endpoint returns the auto insurance report.
# Retrieve a home insurance report
Source: https://docs.truv.com/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://docs.truv.com/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](/api-reference/tasks/lifecycle) |
| finished\_at | string | Time report was finished |
| access\_token | string, null | Access token for Link to payroll provider |
| tracking\_info | string | Information passed to Truv Bridge from partner |
| is\_suspicious | boolean | Flag indicating if data from the source is suspicious, e.g. fraud detected in uploaded documents or the user's SSN does not match the data |
| insurance | object | List of insurances, see Insurance object |
| provider | string | Insurance Provider ID |
| identity | object | Person's identity information |
| pdf\_report | uri, null | Insurance report in PDF format |
### Insurance object
These values are for the insurance object field.
| Attribute | Type | Description |
| :--------------- | :--------------- | :---------------------- |
| policies | array of objects | List of policies |
| drivers | array of objects | List of drivers |
| addresses | array of objects | List of addresses |
| driving\_records | array of objects | List of driving records |
| agents | array of objects | 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` `NAMED_NON_OWNER` `CLASSIC_CAR` `BOAT` `CONDO` `FARMOWNER` `FLOOD` `HOMEOWNERS` `LANDLORD` `LIFE` `MOTORCYCLE` `TERM_LIFE` `UNIVERSAL_LIFE` `WHOLE_LIFE` `RENTERS` `SNOWMOBILE` `UMBRELLA` `RECREATIONAL_VEHICLE` `FIRE` `TRAILER` `PERSONAL_ARTICLES` `EARTHQUAKE` `BUSINESS_OWNERS` `COMMERCIAL_UMBRELLA` `COMMERCIAL_AUTO` `COMMERCIAL_FIRE` `COMMERCIAL_AGRIBUSINESS` `COMMERCIAL_PACKAGE` `COMMERCIAL_PROPERTY` `COMBO` `OFFROAD_VEHICLE` `WORKERS_COMPENSATION` `MOBILE_HOME` `PET` `PERSONAL_LIABILITY` `GENERAL_LIABILITY` `ERRORS_AND_OMISSIONS` `INLAND_MARINE` `GARAGE` `EXCESS_LIABILITY` `CYBER` `IDENTITY_THEFT` `COMMERCIAL_CRIME` `ARTISAN_AND_SERVICE_CONTRACTORS` `FARM_POLLUTION_LIABILITY` `FARM_UMBRELLA` `MANAGEMENT_LIABILITY` `GOLF_CART` `YACHT` `PERSONAL_WATERCRAFT` `STANDARD_PROPERTY` |
| 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` `RESCINDED` |
| 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_STRUCTURES` `PERSONAL_PROPERTY` `BUSINESS_PROPERTY` `ORDINANCE_OR_LAW` `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` `FLOOD` `PORTABLE_ELECTRONICS` `FASHION_ITEMS` `FINE_ART` `BICYCLE` `CAMERA` `JEWELRY` `MUSICAL_INSTRUMENT` `BUILDING` `CONTENTS` `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) |
| drivers | array of objects | List of vehicle drivers, see [Vehicles drivers object](#vehicles-drivers-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` `SPARE_PARTS` |
| 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\_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 |
#### 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` `PERSONAL_AND_ADVERTISING_INJURY` `EMPLOYEE_INJURY_OR_ILLNESS` `PRODUCT_LIABILITY` `STRUCK_BY_AN_OBJECT` `REPUTATIONAL_HARM` `VEHICULAR_ACCIDENT` `WINDSHIELD_DAMAGE` `STRIKE_RIOT_OR_CIVIL_COMMOTION` `EMERGENCY_ROADSIDE_ASSISTANCE` |
| 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 |
| address\_nature | string | The type of address `MAILING` `PHYSICAL` `LIENHOLDER` `INCIDENT_LOCATION` `AGENCY_LOCATION` `MORTGAGEE` |
| 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, null | 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-30T15: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"
}
```
# List all investment holdings
Source: https://docs.truv.com/api-reference/investments/link-investments-list
GET /v1/links/{link_id}/investments/
The endpoint returns a paginated list of investment accounts and their associated holdings, including positions, quantities, values, and asset details. Supports optional filtering by account IDs, account subtypes, and holding types.
# Retrieve liabilities
Source: https://docs.truv.com/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://docs.truv.com/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
## Accounts
The `accounts` array lists each liability account. The credit and loan terms below reference these accounts by `account_id`.
| Attribute | Type | Description |
| :--------- | :----------- | :----------------------------------------------------------------------------------- |
| `id` | string | Unique account identifier |
| `type` | string | Account type (see [Account types](#account-types)) |
| `subtype` | string, null | Account subtype (see [Account types](#account-types)) |
| `mask` | string, null | Last 4 digits of account number |
| `nickname` | string, null | User-friendly account name |
| `balances` | object | Balance information: `currency_code`, `balance`, `available_balance`, `credit_limit` |
## 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 |
| `balance_as_of` | date-time | Date and time the balance was last updated |
| `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 |
| `balance_as_of` | date-time | Date and time the balance was last updated |
| `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
An account has a `type` and an optional `subtype`.
**`type`** — one of: `LOAN`, `CREDIT_CARD`, `LINE_OF_CREDIT`, `MORTGAGE`, `CHECKING_LINE_OF_CREDIT`
**`subtype`** — one of (nullable): `BROKERAGE`, `STUDENT`, `AUTO`, `PERSONAL`, `PERSONAL_WITH_COLLATERAL`, `HELOC`, `HOME_EQUITY`, `RV`, `SMALL_BUSINESS`
## 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.
Liabilities data comes from a connected financial account. The member connects their bank account through Truv Bridge using either the Transactions or Assets (VOA) product. Once the connection is established, the liabilities endpoint returns outstanding loan balances, credit obligations, and payment history for the connected accounts. See [Financial Accounts](/developers/coverage-financial-accounts) for supported institutions and account types.
Liabilities data is derived from the financial institution connection created by the Transactions or Assets product. No separate connection step is required — connect the account with either product, 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://docs.truv.com/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://docs.truv.com/api-reference/links/events
Webhook events for Account Link connections, disconnections, and deletions
Subscribe to these events via [Webhooks](/api-reference/webhooks) to track Account Link state changes in real time.
All webhook payloads include these common fields:
| Field | Description |
| ------------------ | ------------------------------------------ |
| `webhook_id` | Unique identifier for this webhook request |
| `event_type` | The event classification |
| `event_created_at` | Timestamp when the event occurred |
| `user_id` | Associated Truv user identifier |
All Account Link events on this page also include these fields:
| Field | Description |
| --------------- | ------------------------------------------------------------------------------ |
| `link_id` | The Link identifier |
| `product` | The product the event relates to, such as `income`, `employment`, or `assets` |
| `data_source` | Source of data: `payroll`, `docs`, `insurance`, `financial_accounts`, or `tax` |
| `tracking_info` | Custom metadata passed via `bridge_token` (nullable) |
***
## link-connected
Fires when a Link connection is successfully established.
```json theme={null}
{
"webhook_id": "e5f6a7b8c9d0e1f2a3b4c5d6a7b8c9d0",
"event_type": "link-connected",
"event_created_at": "2022-08-24T13:54:00.000000Z",
"link_id": "d39d86dcc20c46e0ae75ba9ab1311a21",
"product": "income",
"data_source": "payroll",
"tracking_info": null,
"user_id": "88fef4cea64c40b5ad6727cc9b0b9fdc"
}
```
***
## 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",
"link_id": "d39d86dcc20c46e0ae75ba9ab1311a21",
"product": "income",
"data_source": "payroll",
"tracking_info": null,
"user_id": "88fef4cea64c40b5ad6727cc9b0b9fdc"
}
```
***
## 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",
"link_id": "d39d86dcc20c46e0ae75ba9ab1311a21",
"product": "income",
"data_source": "payroll",
"tracking_info": null,
"user_id": "88fef4cea64c40b5ad6727cc9b0b9fdc"
}
```
# Retrieve a link token
Source: https://docs.truv.com/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://docs.truv.com/api-reference/links/links-item
GET /v1/links/{link_id}/
# List all links
Source: https://docs.truv.com/api-reference/links/links-list
GET /v1/links/
# The Account Links object
Source: https://docs.truv.com/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](/developers/integration/bridge-widget/overview). 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](/api-reference/tasks/lifecycle) related to account Link |
| user\_external\_id | string | 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-30T15:00:00Z",
"tracking_info": "user123456",
"status": "new",
"user_external_id": "user123456",
"provider_id": "adp",
"link_hash": "bc917458a3da4b2c8cc8282aa1707aaa"
}
```
***
## 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)
# OpenAPI Spec
Source: https://docs.truv.com/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://docs.truv.com/api-reference/orders/events
Webhook events for Order status changes and refresh failures
Subscribe to these events via [Webhooks](/api-reference/webhooks) to track Order progress in real time.
All webhook payloads include these common fields:
| Field | Description |
| ------------------ | ------------------------------------------ |
| `webhook_id` | Unique identifier for this webhook request |
| `event_type` | The event classification |
| `event_created_at` | Timestamp when the event occurred |
| `user_id` | Associated Truv user identifier |
All Order events on this page also include these fields:
| Field | Description |
| -------------- | --------------------------------------------- |
| `order_id` | The Order identifier |
| `order_number` | Human-readable order number (nullable) |
| `template_id` | Associated template, if applicable (nullable) |
| `updated_at` | Time event occurred |
The following fields appear only in `order-created`, `order-status-updated`, and `order-refresh-failed`:
| Field | Description |
| ------------- | ----------------------------------------------------------------------------------------- |
| `status` | Current status of the event |
| `employer_id` | Associated employer (nullable) |
| `link_id` | Identifier of the Link associated with the Task (nullable) |
| `product` | The product the event relates to, such as `income`, `employment`, or `assets` |
| `data_source` | Source of data: `payroll`, `docs`, `insurance`, `financial_accounts`, or `tax` (nullable) |
***
## 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`.
```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 each time a suborder — a single employer or financial account — changes status. Unlike `task-status-updated`, it does not fire on individual login attempts.
`order-status-updated` tracks suborder status changes, not individual login attempts. To capture every connection attempt in real time, 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.
```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": "ddd192646b3c48be96651a0ff25cef85",
"order_number": "ORD-2024-001",
"employer_id": "31e2fdc5bf0c42d4bd2eb16f49066b0d",
"status": "completed",
"user_id": "88fef4cea64c40b5ad6727cc9b0b9fdc",
"template_id": null,
"product": "income",
"link_id": null,
"data_source": 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.
```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": "ddd192646b3c48be96651a0ff25cef85",
"order_number": "ORD-2024-001",
"employer_id": "31e2fdc5bf0c42d4bd2eb16f49066b0d",
"status": "login_error",
"user_id": "88fef4cea64c40b5ad6727cc9b0b9fdc",
"template_id": null,
"product": "income",
"link_id": null,
"data_source": null
}
```
***
## order-finalized
Fires when an order group reaches its terminal state and is marked final. No further data collection or refresh occurs.
```json theme={null}
{
"webhook_id": "0aac461e7b774a38a72fd9c7c0eef8ee",
"event_type": "order-finalized",
"event_created_at": "2024-07-11T21:40:48.424610Z",
"user_id": "adbe707dddee4334bffaeb5866272740",
"order_id": "ddd192646b3c48be96651a0ff25cef85",
"order_number": "4138538",
"template_id": "c41bec89-5d88-4d96-945f-92a9a3176cdb",
"updated_at": "2024-07-11T21:40:48.424655+00:00"
}
```
***
## certification-completed
Fires when an applicant submits their income self-certification, confirming which bank transactions or employment records represent the data for their order.
```json theme={null}
{
"webhook_id": "0aac461e7b774a38a72fd9c7c0eef8ee",
"event_type": "certification-completed",
"event_created_at": "2024-07-11T21:40:48.424610Z",
"user_id": "adbe707dddee4334bffaeb5866272740",
"order_id": "ddd192646b3c48be96651a0ff25cef85",
"order_number": "4138538",
"template_id": "c41bec89-5d88-4d96-945f-92a9a3176cdb",
"updated_at": "2024-07-11T21:40:48.424655+00:00"
}
```
# The Orders object
Source: https://docs.truv.com/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/bridge-token/object), and produces a personalized landing page for the user to connect their account.
The following diagram illustrates the Order lifecycle.
```mermaid theme={null}
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. Truv fires an `order-status-updated` webhook each time a suborder — an employer or financial account — changes status, for example as each connection resolves.
5. You retrieve the verification data from the [Retrieve an order](/api-reference/orders/orders_read) endpoint.
6. Truv fires an `order-finalized` webhook once the order reaches its terminal state — no further data collection or refresh occurs.
| Webhook | Scope | Use for |
| ---------------------- | ----------------------------------------- | ---------------------------------------------------------------------------------- |
| `task-status-updated` | Per employer/account connection | Monitoring individual connection progress, processing data as it arrives |
| `order-status-updated` | Per suborder (employer/financial account) | Suborder progress; fires on status changes, not on login attempts |
| `order-finalized` | Entire order group | Knowing the order is permanently final, with no further data collection or refresh |
In a multi-employer order, `task-status-updated` fires for every connection attempt, including failed logins. `order-status-updated` fires whenever a suborder — an employer or financial account — changes status, but not on individual login attempts. Use `task-status-updated` for fine-grained, real-time progress; use `order-status-updated` to track suborder status changes.
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 | Client name displayed on the order page |
| 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 | boolean | Status of Order expiration |
| user\_consent\_at | string, null | ISO 8601 time when the user first gave consent. |
| 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 | object | 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, null | Access token to perform data refresh |
| pdf\_report | uri, null | 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 | object | 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 | object | 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\_updated | 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, null | 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, `M` - Monthly |
| 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, null | Access token to perform data refresh |
| pdf\_report | uri, null | 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 | object | 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, null | Access token to perform data refresh |
| pdf\_report | uri, null | 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 | object | 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) |
#### 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 | Last 4 digits of the 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": "6789"
}
]
}
],
"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://docs.truv.com/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://docs.truv.com/api-reference/orders/order_group_invoice_detail
GET /v1/orders/{id}/invoice/
The endpoint returns an order invoice.
# Cancel an order
Source: https://docs.truv.com/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://docs.truv.com/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://docs.truv.com/api-reference/orders/orders_create
POST /v1/orders/
The endpoint creates an order
# Create a data refresh order
Source: https://docs.truv.com/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://docs.truv.com/api-reference/orders/orders_events_list
GET /v1/orders/{id}/events/
Returns a list of events for the specified order.
# List orders
Source: https://docs.truv.com/api-reference/orders/orders_list
GET /v1/orders/
The endpoint returns a list of orders.
# Get list of orders by SSN
Source: https://docs.truv.com/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://docs.truv.com/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://docs.truv.com/api-reference/orders/orders_read
GET /v1/orders/{id}/
The endpoint returns the order.
# List all parsed documents
Source: https://docs.truv.com/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://docs.truv.com/api-reference/parsed-documents/object
Access parsed document data retrieved through Truv Bridge connections.
Parsed Documents contain structured data extracted from documents uploaded and processed through Truv Bridge. Currently, only **volunteer letters** (`VOLUNTEER_LETTER`) are available through this endpoint; support for additional document types such as paystubs will be added in future releases.
# Attributes
The table below covers the fields in a parsed document.
| Attribute | Type | Description |
| :---------------- | :----------- | :--------------------------------------------------------------------- |
| id | string | Parsed document ID |
| document\_type | string | Document type. Currently only `VOLUNTEER_LETTER` is supported. |
| document\_subtype | string, null | Document subtype, valid values below `VOL_TRANSCRIPT`, `VOL_HOURS_LOG` |
| file | uri, null | Parsed document file link |
| md5sum | string | Parsed document MD5 checksum |
# 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)
# Example response
The sample below is a JSON response for the List endpoint.
```json theme={null}
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"id": "24d7e80942ce4ad58a93f70ce4115f5c",
"document_type": "VOLUNTEER_LETTER",
"document_subtype": "VOL_TRANSCRIPT",
"file": "https://cdn.truv.com/files_examples/VOLUNTEER_LETTER.pdf",
"md5sum": "24d7e80942ce4ad58a93f70ce4115f5c"
}
]
}
```
# Retrieve parsed document
Source: https://docs.truv.com/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://docs.truv.com/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.
***
## 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.
# Retrieve recurring transactions (inflows and outflows) for a user
Source: https://docs.truv.com/api-reference/recurring-transactions/applicant-recurring-transactions
GET /v1/users/{user_id}/transactions/recurring/
Returns recurring transaction patterns detected across the user's linked bank accounts, split into recurring outflows (subscriptions, bills, and other recurring expenses) and recurring inflows (salary, benefits, and other recurring income sources).
# The Task Refresh object
Source: https://docs.truv.com/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](/api-reference/refresh/refresh_task_create) endpoint with the **access\_token** from the original connection.
3. Use webhooks, the [Retrieve a data refresh status](/api-reference/refresh/refresh_task) 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://docs.truv.com/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://docs.truv.com/api-reference/refresh/refresh_task_create
POST /v1/refresh/tasks/
The endpoint creates a link data refresh task.
# Report Sizes
Source: https://docs.truv.com/api-reference/report-sizes
Typical and long-tail payload sizes for Truv reports, so you can plan storage, request timeouts, and bandwidth.
Use this page to size storage, request timeouts, and ingestion buffers for Truv report endpoints.
PDFs are predictable and bounded. JSON payloads — especially for assets and AIM — tail to **multiple megabytes** at the long tail. Size your reads accordingly.
***
## Sizes by report
Tap a report to see size distributions for each format it returns. Use the **max** and **p99** columns to drive buffer and timeout sizing for the formats you fetch.
Returned by [VOIE report retrieve](/api-reference/user-income-and-employment-reports/users_get_report).
| Format | p50 | p90 | p95 | p99 | max |
| :----- | :------ | :------- | :------- | :------ | :------ |
| pdf | 17.2 KB | 19.5 KB | 21.9 KB | 26.3 KB | 40.3 KB |
| json | 46.7 KB | 661.9 KB | 801.7 KB | 1.2 MB | 1.3 MB |
Returned by [Assets report retrieve](/api-reference/user-asset-verification-reports/assets-report-retrieve).
| Format | p50 | p90 | p95 | p99 | max |
| :----- | :------- | :------- | :------- | :------- | :------- |
| pdf | 39.4 KB | 87.4 KB | 167.9 KB | 298.4 KB | 306.8 KB |
| json | 131.6 KB | 599.3 KB | 1.4 MB | 2.9 MB | 3.4 MB |
Returned by [Assets report retrieve](/api-reference/user-asset-verification-reports/assets-report-retrieve). The raw JSON variant carries account-level detail and is the largest format Truv produces — start your buffer and timeout sizing here.
| Format | p50 | p90 | p95 | p99 | max |
| :------- | :------- | :------ | :------ | :--------- | :---------- |
| pdf | 24.2 KB | 24.5 KB | 24.6 KB | 24.7 KB | 24.7 KB |
| json | 33.9 KB | 34.8 KB | 34.9 KB | 35.4 KB | 35.4 KB |
| raw json | 463.5 KB | 2.4 MB | 4.1 MB | **9.9 MB** | **10.9 MB** |
Returned by [Assets report retrieve](/api-reference/user-asset-verification-reports/assets-report-retrieve). Multi-megabyte even at the median.
| Format | p50 | p90 | p95 | p99 | max |
| :----- | :------- | :----- | :----- | :----- | :----- |
| json | 784.7 KB | 2.7 MB | 3.5 MB | 6.1 MB | 6.4 MB |
Returned by [Assets report retrieve](/api-reference/user-asset-verification-reports/assets-report-retrieve). Typical payload is small, but the long tail reaches >1 MB on borrowers with deep transaction history.
| Format | p50 | p90 | p95 | p99 | max |
| :----- | :----- | :----- | :----- | :------- | :----- |
| json | 3.0 KB | 5.5 KB | 9.0 KB | 512.8 KB | 1.6 MB |
Returned by [Income Insights retrieve](/api-reference/income-insights/income-insights-report-retrieve). Single-link income summary.
| Format | p50 | p90 | p95 | p99 | max |
| :----- | :------ | :------ | :------ | :------ | :------ |
| pdf | 24.9 KB | 34.3 KB | 34.4 KB | 39.5 KB | 42.8 KB |
Returned by [Assets report retrieve](/api-reference/user-asset-verification-reports/assets-report-retrieve). Verifies employment from deposit patterns when a direct payroll connection isn't available.
| Format | p50 | p90 | p95 | p99 | max |
| :----- | :------ | :------- | :------- | :------- | :------ |
| pdf | 20.0 KB | 32.0 KB | 36.3 KB | 45.8 KB | 77.3 KB |
| json | 62.7 KB | 213.8 KB | 267.2 KB | 722.3 KB | 1.8 MB |
***
## Planning guidance
**Buffers.** Most clients default to a 1 MB or 5 MB response buffer. The JSON payloads for Freddie AIM Check (raw), Freddie Mac VOA Submission, and the VOA Report regularly exceed those at p95+. Set client read buffers to at least **16 MB** for the AIM raw JSON and **8 MB** for the VOA and Freddie VOA JSON to avoid truncation under the long tail.
**Timeouts.** Default HTTP client timeouts of 10–15 seconds can truncate raw-JSON downloads on slower connections. For the multi-megabyte JSON payloads above, set a request timeout of at least **60 seconds** (longer if your client runs from a constrained network). PDFs and the smaller JSON variants are well-served by default timeouts.
For capacity planning, multiply your monthly report volume by the per-report average. The four heaviest payloads: Freddie Mac VOA Submission JSON \~1.2 MB, Freddie AIM Check raw JSON \~1.1 MB, VOA Report JSON \~306 KB, VOIE Report JSON \~192 KB. Every other format averages under 60 KB.
Across all formats the cross-cutting average is \~255 KB per report. A workflow that pulls VOIE JSON + VOIE PDF + AIM raw JSON + Freddie VOA JSON averages \~2.5 MB per completed verification.
The Freddie AIM Check raw JSON has a >1 MB average and a 10.9 MB max. If you only need the AIM check decision and not the raw account-level detail, download the standard JSON variant of the AIM Check instead — it is \~30× smaller and bounded around 35 KB.
PDFs are uniformly small and predictable (typically under 100 KB). JSON formats carry transaction-level data, which scales with `days_requested` and account count. If you only need a human-readable artifact, request the PDF format to avoid the JSON tail.
***
## Next steps
Retrieval patterns and Encompass field mappings
Get notified when a report is ready instead of polling
How Truv assembles report data
Connect the Truv MCP server to your AI tooling
# The Scoring Attributes Report object
Source: https://docs.truv.com/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-31",
"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://docs.truv.com/api-reference/scoring-attributes/scoring-attributes-report-create
POST /v1/scoring_attributes/reports
# Retrieve a scoring attributes report
Source: https://docs.truv.com/api-reference/scoring-attributes/scoring-attributes-report-retrieve
GET /v1/scoring_attributes/reports/{report_id}
# Security
Source: https://docs.truv.com/api-reference/security
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.
***
## 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/webhooks#security) for verification examples, retry behavior, IP allowlisting, and handling guidance.
***
## mTLS API endpoints
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.
| 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. The following 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.
For the source IP addresses Truv uses to deliver webhooks, see [Webhook Security](/api-reference/webhooks#originating-ip-addresses).
***
## Privacy and compliance
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](#mtls-api-endpoints) 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/webhooks#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](https://trust.truv.com/) or contact the Truv compliance team at [compliance@truv.com](mailto:compliance@truv.com).
***
## Contact
[security@truv.com](mailto:security@truv.com)
[compliance@truv.com](mailto:compliance@truv.com)
# Shift Webhook Events
Source: https://docs.truv.com/api-reference/shifts/events
Webhook events for shift data creation and updates.
Subscribe to these events via [Webhooks](/api-reference/webhooks) to receive notifications when shift data becomes available or changes during a refresh.
All webhook payloads include these common fields:
| Field | Description |
| ------------------ | ------------------------------------------ |
| `webhook_id` | Unique identifier for this webhook request |
| `event_type` | The event classification |
| `event_created_at` | Timestamp when the event occurred |
| `user_id` | Associated Truv user identifier |
All Shift events on this page also include these fields:
| Field | Description |
| --------------- | ------------------------------------------------------------------------------ |
| `link_id` | Identifier of the Link |
| `product` | The product the event relates to, such as `income`, `employment`, or `assets` |
| `data_source` | Source of data: `payroll`, `docs`, `insurance`, `financial_accounts`, or `tax` |
| `tracking_info` | Custom metadata passed via `bridge_token` (nullable) |
| `task_id` | The associated Task |
| `employment_id` | The associated employment record |
| `objects_count` | Number of shifts retrieved |
***
## shifts-created
Fires when shift data has been extracted. This occurs for any successful non-refresh [Task](/api-reference/tasks/object). Multiple responses are sent when additional shifts are found.
```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"
}
```
***
## shifts-updated
Fires when the shift count changes during a refresh Task. For example, if a person had 8 shifts and now has 9.
```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"
}
```
# List all shifts
Source: https://docs.truv.com/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://docs.truv.com/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, null | Link to next page |
| previous | string, null | 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 |
| time\_entries\[].id | string | Unique time entry ID |
| time\_entries\[].external\_id | string | Time entry external ID |
| time\_entries\[].created\_at | string | Time entry creation timestamp |
| time\_entries\[].updated\_at | string | Time entry update timestamp |
| time\_entries\[].entry\_date | string | Entry date of event in time tracking system |
| time\_entries\[].start | string | Date and time when work shift started |
| time\_entries\[].end | string | Date and time when work shift ended |
| earnings | array of objects | Aggregated earnings for shift |
| earnings\[].name | string | Name of earnings (required) |
| earnings\[].amount | string (decimal) | Amount of earnings (required) |
| earnings\[].category | string | Category of earnings (required), one of: `regular`, `overtime`, `bonus`, `commission`, `other_pay` |
| earnings\[].rate | string (decimal), null | Rate of earnings |
| earnings\[].units | string (decimal), null | Units of earnings |
| 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://docs.truv.com/api-reference/statements/events
Webhook events for pay statement creation and updates.
Subscribe to these events via [Webhooks](/api-reference/webhooks) to receive notifications when pay statements become available or change during a refresh.
All webhook payloads include these common fields:
| Field | Description |
| ------------------ | ------------------------------------------ |
| `webhook_id` | Unique identifier for this webhook request |
| `event_type` | The event classification |
| `event_created_at` | Timestamp when the event occurred |
| `user_id` | Associated Truv user identifier |
All Pay Statement events on this page also include these fields:
| Field | Description |
| --------------- | ------------------------------------------------------------------------------ |
| `link_id` | Identifier of the Link |
| `product` | The product the event relates to, such as `income`, `employment`, or `assets` |
| `data_source` | Source of data: `payroll`, `docs`, `insurance`, `financial_accounts`, or `tax` |
| `tracking_info` | Custom metadata passed via `bridge_token` (nullable) |
| `task_id` | The associated Task |
| `employment_id` | The associated employment record |
| `objects_count` | Number of statements retrieved |
***
## 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.
```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"
}
```
***
## 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.
```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"
}
```
# List all statements
Source: https://docs.truv.com/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://docs.truv.com/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: `S` - Salary, `H` - Hourly, `D` - Daily, `W` - Weekly, `M` - Monthly |
| 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 |
### Earnings object
Each item in `earnings` and `earnings_ytd` has this shape.
| Attribute | Type | Description |
| :-------- | :----- | :---------------------------------------------------------------- |
| name | string | Name of the earning |
| amount | string | Amount of the earning |
| category | string | One of: `regular`, `overtime`, `bonus`, `commission`, `other_pay` |
| rate | string | Rate of the earning (nullable) |
| units | string | Units for the earning (nullable) |
### Deductions object
Each item in `deductions` and `deductions_ytd` has this shape.
| Attribute | Type | Description |
| :-------- | :----- | :-------------------------------------------------------------------------------------------------------------------- |
| name | string | Name of the deduction |
| amount | string | Amount of the deduction |
| category | string | One of: `memo`, `medicare`, `retirement`, `socialsec`, `federal`, `state`, `benefit`, `garnishment`, `local`, `other` |
***
## 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://docs.truv.com/api-reference/statements/retrieve-statement
GET /v1/links/{link_id}/statements/{statement_id}/
Get the pay statement
# Task Webhook Events
Source: https://docs.truv.com/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) to track Task progress and data availability in real time.
All webhook payloads include these common fields:
| Field | Description |
| ------------------ | ------------------------------------------ |
| `webhook_id` | Unique identifier for this webhook request |
| `event_type` | The event classification |
| `event_created_at` | Timestamp when the event occurred |
| `user_id` | Associated Truv user identifier |
All Task events on this page also include these fields:
| Field | Description |
| --------------- | -------------------------------------------------------------------------------- |
| `task_id` | The Task identifier |
| `link_id` | Account connection ID (use to retrieve `access_token`) |
| `product` | The product the event relates to, such as `income`, `employment`, or `assets` |
| `data_source` | Source of data: `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)) |
| `updated_at` | Time event occurred |
| `template_id` | Associated template, if applicable (nullable) |
***
## task-status-updated
Fires for each Task status change during the connection lifecycle. This is the primary event for tracking verification progress.
```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.
# Task Lifecycle
Source: https://docs.truv.com/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
Every task authenticates through the Link first, then follows one of two paths depending on its type. A task may skip `mfa` when the provider doesn't require multi-factor authentication.
### Standard tasks
A standard task collects data from the connected account:
```
new → login → mfa → parse → full_parse → done
```
```mermaid theme={null}
flowchart TD
N[new] --> LG[login]
LG -->|login_error| E[error]
LG --> MFA[mfa]
LG -->|no MFA required| P[parse]
MFA -->|mfa_error| E
MFA --> P
P -->|error| E
P --> FP[full_parse]
FP --> D[done]
classDef active fill:#2C64E3,stroke:#1E4BB8,color:#FFFFFF
classDef error fill:#DC2626,stroke:#B91C1C,color:#FFFFFF
class N,LG,MFA,P,FP,D active
class E error
```
### DDS tasks
A Direct Deposit Switch task replaces `parse` and `full_parse` with `switch_deposit`:
```
new → login → mfa → switch_deposit → done
```
```mermaid theme={null}
flowchart TD
N[new] --> LG[login]
LG -->|login_error| E[error]
LG --> MFA[mfa]
LG -->|no MFA required| SD[switch_deposit]
MFA -->|mfa_error| E
MFA --> SD
SD -->|error| E
SD --> D[done]
classDef active fill:#2C64E3,stroke:#1E4BB8,color:#FFFFFF
classDef error fill:#DC2626,stroke:#B91C1C,color:#FFFFFF
class N,LG,MFA,SD,D active
class E error
```
***
## 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 | Recommended action |
| --------------------- | ------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| **login\_error** | Authentication failed: incorrect credentials | Prompt the user to re-authenticate via [Bridge Update Mode](/developers/integration/bridge-widget/returning-user) |
| **mfa\_error** | Multi-factor authentication was not completed | Prompt the user to retry, or offer document upload as fallback |
| **config\_error** | Provider integration or configuration issue. Also raised when uploaded documents fail fraud/tampering checks. | Fetch the task record for the specific `error_message`. For document tampering, see [Fraud & Manual Review](/developers/fraud-and-manual-review). |
| **account\_locked** | The payroll or bank account is locked | Ask the user to unlock their account directly with the provider before retrying |
| **unable\_to\_reset** | Failed to reset credentials at the provider | Route the user to manual verification |
| **no\_data** | Provider connected successfully but returned no data | Offer document upload as fallback. Do not treat as verified \$0 income. |
| **unavailable** | Provider service is temporarily inaccessible | Retry later or route to document upload. Not user-fixable. |
| **not\_supported** | Provider or HRIS system is not supported | Inform the user and offer document upload |
| **error** | Generic connection failure | Log the `task_id` and contact support if the error persists |
Subscribe to [`task-status-updated` webhooks](/api-reference/webhooks) to receive error states in real time. 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://docs.truv.com/api-reference/tasks/object
A job created on a Link to pull, refresh, or update data in the linked account.
A Task is a job created for a specific Link to pull, refresh, or update data in the linked account. Each task records its product type, data source, provider, and current processing status, and moves through the [task lifecycle](/api-reference/tasks/lifecycle).
## Attributes
The attributes of Tasks are below.
| Attribute | Type | Description |
| :------------- | :----------- | :--------------------------------------------------------------------------------------------------------------------------------------------- |
| id | string | Unique ID of the task |
| status | string | Current status of the task. See [Task Lifecycle](/api-reference/tasks/lifecycle) for all status values, error states, and recommended actions. |
| product\_type | string | Type of data product being processed: `income`, `employment`, `deposit_switch`, `pll`, `insurance`, `transactions`, or `assets` |
| provider | object | Data provider that served this task (see [Provider object](#provider-object)) |
| created\_at | datetime | Timestamp when the task was created |
| updated\_at | datetime | Timestamp when the task was last updated |
| error\_message | string, null | Error details if task failed |
| tracking\_info | string, null | Optional tracking information provided by partner |
| bridge\_token | string, null | Bridge token used for authentication |
| data\_source | string | Source of the verification data: `payroll`, `docs`, `insurance`, `financial_accounts`, or `tax` |
| link\_id | string | ID of the associated Link (connection) |
| is\_suspicious | boolean | Whether the task or link is flagged as suspicious |
| user\_id | string | ID of the user associated with this task |
| order\_id | string, null | ID of the order associated with this task |
### Provider object
| Attribute | Type | Description |
| :-------- | :----------- | :----------------------- |
| id | string | Data provider ID |
| name | string | Data provider name |
| logo\_url | string (uri) | Data provider logo image |
***
## 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://docs.truv.com/api-reference/tasks/tasks_list
GET /v1/tasks/
The endpoint returns a list of Tasks.
# Retrieve a task
Source: https://docs.truv.com/api-reference/tasks/tasks_read
GET /v1/tasks/{id}/
The endpoint returns a Task.
# The Tax Documents object
Source: https://docs.truv.com/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. One of: W2, F1099, F1040 |
| document\_subtype | string, null | Subtype of document (nullable). One of: F1099\_DIV, F1099\_G, F1099\_INT, F1099\_MISC, F1099\_NEC, F1099\_R, F\_SSA1099 |
| 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)
* [Retrieve a tax document](/api-reference/tax/tax-document)
# 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",
"document_subtype": null,
"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://docs.truv.com/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://docs.truv.com/api-reference/tax/tax-documents
GET /v1/links/{link_id}/tax/
The endpoint returns a list of tax documents.
# The Templates object
Source: https://docs.truv.com/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. Supported document types include `paystub`, `w2`, `f1099`, `f1040`, `insurance_home_policy`, `insurance_auto_policy`, `volunteer_letter`, `freddie_aim_check`, and `other` |
| data | object | Settings for returned documents |
| reports | object | Report settings, including Income Insights configuration |
| data\_sources\_flow | object | Data source flow configuration |
| created\_at | datetime | Timestamp for created customizable template |
| updated\_at | datetime | Timestamp for updated customizable template |
When the `other` document type is enabled in `document_upload`, end users can upload arbitrary documents that don't fit the other categories. Truv does not parse these documents into structured data (they are captured only) — you can collect the uploaded files through the [Uploaded Documents API](/api-reference/uploaded-documents/object) (`GET /v1/links/{link_id}/documents/`).
***
## Endpoints
The table below covers the available endpoints for customizable templates.
* [List all customizable templates](/api-reference/templates/templates_list) - GET /v1/templates/
* [Create a customizable template](/api-reference/templates/templates_create) - POST /v1/templates/
* [Retrieve a customizable template](/api-reference/templates/templates_read) - GET /v1/templates/\{template\_id}/
* [Update a customizable template](/api-reference/templates/templates_partial_update) - PATCH /v1/templates/\{template\_id}/
* [Delete a customizable template](/api-reference/templates/templates_delete) - DELETE /v1/templates/\{template\_id}/
***
## What templates control
Templates give you fine-grained control over the verification experience across several areas:
| Area | Capabilities |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Bridge UI** | Customize search header and per-product success-screen text, and toggle the Truv logo and support button |
| **Branding** | Set company logo, accent and background colors, 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.notification_settings` configuration. Its companion field `first_notification_delay_hours` is ignored when suppression is on.
***
## Example response
The `bridge.texts` object is deprecated. Use `bridge.product_settings` instead to configure per-product Bridge text; `texts` will be removed in a future version.
View the JSON response example below.
```json theme={null}
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"name": "My template",
"products": ["income"],
"default_for_products": false,
"bridge": {
"product_settings": [
{
"product_type": "assets",
"data_source": "financial_accounts",
"texts": {
"search_header": "Find your bank",
"success_title": "Success!",
"success_subtitle": "Your bank account has been connected",
"success_cta": "Continue"
}
}
],
"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,
"freddie_aim_check": {
"is_enabled": true,
"seller_id": "00601"
},
"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
},
"volunteer_letter": {
"is_enabled": true,
"is_required": true,
"title": "Upload volunteer letter and timesheet",
"description": "PDF files only under 15 MB.",
"button": "Upload",
"submit_title": "Did you upload volunteer letter and timesheet?",
"min_count": 1,
"max_count": 1
},
"other": {
"is_enabled": true,
"is_required": false,
"title": "Upload supporting documents",
"description": "PDF files only under 15 MB.",
"button": "Upload",
"submit_title": "Did you upload supporting documents?",
"min_count": 1,
"max_count": 1
}
},
"data": {
"paystubs_count": 6,
"w2_count": 3,
"paystubs_ytd_count": 3,
"extended_history": {
"statements_history_days": 180
}
},
"reports": {
"hidden_sections": {
"deposits": false,
"large_deposits": false,
"historical_payment_summary": false
},
"days_requested": 60,
"large_deposit_threshold": 500,
"transaction_categories": ["Food & Dining", "Travel", "Shopping"],
"transaction_account_types": ["CHECKING", "SAVINGS"],
"transaction_account_subtypes": ["FIXED_ANNUITY", "LOCKED_IN_RETIREMENT_ACCOUNT", "PLAN_401_A"],
"income_insights": {
"days_requested": 60,
"consumer_report_permissible_purpose": "WRITTEN_INSTRUCTION_OTHER"
}
},
"data_sources_flow": {
"employment": {
"flow": "fallback",
"data_sources": ["payroll", "docs"]
},
"income": {
"flow": "fallback",
"data_sources": ["payroll", "financial_accounts"]
},
"insurance": {
"flow": "fallback",
"data_sources": ["insurance", "docs"]
}
},
"created_at": "2022-05-04T11:30:00Z",
"updated_at": "2022-05-04T12:00:00Z"
}
```
# Create a customization template
Source: https://docs.truv.com/api-reference/templates/templates_create
POST /v1/templates/
The endpoint creates a customization template.
# Delete a customization template
Source: https://docs.truv.com/api-reference/templates/templates_delete
DELETE /v1/templates/{template_id}/
The endpoint deletes a customization template.
# List all customization templates
Source: https://docs.truv.com/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://docs.truv.com/api-reference/templates/templates_partial_update
PATCH /v1/templates/{template_id}/
The endpoint updates a customization template.
# Retrieve a customization template
Source: https://docs.truv.com/api-reference/templates/templates_read
GET /v1/templates/{template_id}/
This endpoint retrieves a customization template.
# List all bank transactions
Source: https://docs.truv.com/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://docs.truv.com/api-reference/transactions/object
Transaction history from connected financial accounts.
# Attributes
The information in this table is for the top-level transactions response.
| Attribute | Type | Description |
| :----------- | :--------------- | :-------------------------------------------------------------------- |
| count | integer | Total number of transactions |
| next | uri | URL of the next page of results, `null` if none |
| previous | uri | URL of the previous page of results, `null` if none |
| accounts | array of objects | List of accounts, see [Accounts object](#accounts-object) |
| transactions | array of objects | List of transactions, see [Transactions object](#transactions-object) |
## 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 | Last 4 digits of account number |
| nickname | string | Alternate name for account |
| balances | object | 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, one of `POSTED`, `PENDING`, `AUTHORIZATION`, or `MEMO` |
| type | string | Type of transaction, one of `CREDIT`, `DEBIT`, or `MEMO` |
| 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\_name | string | Merchant name extracted from the transaction description (nullable) |
| merchant\_category\_code | number | 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](/api-reference/transactions/link-bank-data-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_name": "Starbucks",
"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://docs.truv.com/api-reference/uploaded-documents/list-documents
GET /v1/links/{link_id}/documents/
The endpoint returns a list of documents.
**Note:** When the `other` document type is enabled in the document upload settings of your customization template, end users can upload arbitrary documents that don't fit the other categories. Truv does not parse these `OTHER` documents into structured data (they are captured only), but you can collect the uploaded files through this Uploaded Documents API.
# The Uploaded Documents object
Source: https://docs.truv.com/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`, `VOLUNTEER_LETTER`, `INSURANCE_HOME_POLICY`, `INSURANCE_AUTO_POLICY`, `OTHER` |
| 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.
When the `other` document type is enabled in the document upload settings of your [customization template](/api-reference/templates/object), end users can upload arbitrary documents that don't fit the other categories. Truv does not parse these `OTHER` documents into structured data (they are captured only), but you can collect the uploaded files through this Uploaded Documents API.
# 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://docs.truv.com/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://docs.truv.com/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://docs.truv.com/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://docs.truv.com/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.
# 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 | |
| as\_of\_date | date | End date of the report period. Start date is as\_of\_date minus days\_requested. Defaults to the current date if not provided | \\ |
| 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 | object | 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: `POSTED`, `PENDING`, `AUTHORIZATION`, or `MEMO` |
| type | string | Type of transaction: `CREDIT`, `DEBIT`, or `MEMO` |
| posted\_at | date-time | Timestamp when transaction was posted |
| transacted\_at | date-time | Timestamp when transaction took place |
| merchant\_name | string | Merchant name extracted from the transaction description |
| 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\_BENEFICIARY | Beneficiary of the account |
| CUSTODIAN | Custodian of the account |
| OTHER | Other relationship to the account |
## 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,
"as_of_date": "2022-05-01",
"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_name": "Starbucks",
"merchant_category_code": 5967,
"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://docs.truv.com/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 link-exclusive fields like `status`, `is_suspicious`, and `access_token`. User-level reports (`POST /v1/users/{user_id}/reports/`) aggregate across all connections, exposing the top-level `report_id` plus the per-employment `gse_accepted` flag (nested under `links[].employments[]`) for GSE submission. Both report types include `provider`. 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\_updated | 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, null | 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, `M` - Monthly |
| 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://docs.truv.com/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://docs.truv.com/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://docs.truv.com/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://docs.truv.com/api-reference/users/users_create
POST /v1/users/
The endpoint creates a user.
# Delete a user
Source: https://docs.truv.com/api-reference/users/users_delete
DELETE /v1/users/{user_id}/
The endpoint deletes a user.
# List all users
Source: https://docs.truv.com/api-reference/users/users_list
GET /v1/users/
The endpoint returns a list of users.
# Update a user
Source: https://docs.truv.com/api-reference/users/users_partial_update
PATCH /v1/users/{user_id}/
The endpoint updates a user.
# Retrieve a user
Source: https://docs.truv.com/api-reference/users/users_read
GET /v1/users/{user_id}/
This endpoint retrieves a user.
# Webhooks
Source: https://docs.truv.com/api-reference/webhooks
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 |
| `event_created_at` | Timestamp when the event occurred |
| `user_id` | Associated Truv user identifier |
Additional fields vary by event type — see [Events by object](#events-by-object) below.
***
## 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.
### 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
Always verify signatures using the **raw request body**, not parsed JSON. 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;
}
}
```
### 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`
### Additional authentication options
Beyond signature verification, Truv supports:
* Truv-signed certificates for webhook mTLS
* Client-signed certificates for webhook mTLS
* OAuth 2.0, where Truv obtains access tokens for secure webhook delivery (optional, configured with Truv)
* Custom headers such as client ID and client secret, configured with Truv
See [mTLS](/api-reference/security#mtls-for-webhooks) if you need mutual certificate-based authentication for webhook delivery.
***
## 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** |
| **Failed delivery** | After the 3 retry attempts fail, Truv stops retrying that event and marks the delivery failed |
***
## 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 `event_created_at` field to sequence events correctly in your system, rather than relying on delivery order. When you need the authoritative full resource state, fetch it from the API instead of relying on the webhook payload alone.
***
## 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 |
| Failed deliveries | Each event is retried up to 3 times (30s apart), then marked failed. Use the [Webhook request history](/api-reference/webhooks/object#webhook-request-history) to find and debug failed deliveries |
## Events by object
**Orders** ([see more](/api-reference/orders/events))
| 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 |
| `order-finalized` | Order group reaches its terminal, final state |
| `certification-completed` | Applicant submits their income self-certification |
**Tasks** ([see more](/api-reference/tasks/events))
| Event | Trigger |
| --------------------- | ----------------------- |
| `task-status-updated` | Task status transitions |
**Bank Accounts** ([see more](/api-reference/bank-accounts/events))
| Event | Trigger |
| ----------------------- | -------------------------------- |
| `bank-accounts-created` | First bank account discovery |
| `bank-accounts-updated` | Bank accounts changed on refresh |
**Shift** ([see more](/api-reference/shifts/events))
| Event | Trigger |
| ---------------- | ------------------------- |
| `shifts-created` | First shift extraction |
| `shifts-updated` | Shifts changed on refresh |
**Pay Statement** ([see more](/api-reference/statements/events))
| Event | Trigger |
| -------------------- | ------------------------- |
| `statements-created` | First statement retrieval |
| `statements-updated` | New statements on refresh |
**Identity** ([see more](/api-reference/identity/events))
| Event | Trigger |
| ----------------- | -------------------------- |
| `profile-created` | First profile extraction |
| `profile-updated` | Profile changed on refresh |
**Employment** ([see more](/api-reference/employment/events))
| Event | Trigger |
| -------------------- | ----------------------------- |
| `employment-created` | First employment extraction |
| `employment-updated` | Employment changed on refresh |
**Links** ([see more](/api-reference/links/events))
| Event | Trigger |
| ------------------- | ---------------------------- |
| `link-connected` | Successful connection |
| `link-disconnected` | Refresh connection failure |
| `link-deleted` | Data and credentials removed |
# The Webhook Endpoint object
Source: https://docs.truv.com/api-reference/webhooks/object
Learn how to create a webhook configuration to receive updates from Truv platform
Webhooks provide a way for Truv to communicate to your servers when specific events happen. For example, when an account link connects successfully or new pay statements were added, you can receive notifications in realtime.
To start receiving webhooks, your web application needs to expose a publicly accessible URL. Use that URL to create a webhook configuration.
After creating a webhook configuration, you will receive POST requests with the event payloads that contain information about the events that have been triggered.
# Attributes
| Attribute | Type | Description |
| :----------- | :------ | :------------------------------------------------------------ |
| id | string | Unique ID of webhook configuration |
| name | string | Public name for webhook configuration |
| webhook\_url | string | Webhook URL to send event data |
| events | string | List of events connected to webhook URL |
| env\_type | string | Type of environment, `sandbox`, `dev`, or `prod` |
| enabled | boolean | Whether the webhook is active |
| created\_at | string | ISO 8601 value for when the webhook configuration was created |
| updated\_at | string | ISO 8601 value for when the webhook configuration was updated |
Truv may automatically disable a production webhook endpoint that fails continuously. The owner is notified by email before and after the endpoint is disabled, and delivery stops until you re-enable it. Re-enable a disabled endpoint by sending `"enabled": true` to the [update endpoint](/api-reference/webhooks/webhooks_partial_update).
# Endpoints
Available endpoints for Webhooks are in the list below.
* [List all webhook endpoints](/api-reference/webhooks/webhooks_list) - GET /webhooks/
* [Create a webhook endpoint](/api-reference/webhooks/webhooks_create) - POST /webhooks/
* [Retrieve a webhook endpoint](/api-reference/webhooks/webhooks_read) - GET webhooks/\{id}/
* [Update a webhook endpoint](/api-reference/webhooks/webhooks_partial_update) - PATCH webhooks/\{id}/
* [Delete a webhook endpoint](/api-reference/webhooks/webhooks_delete) - DELETE webhooks/\{id}/
# Example response
View the response for the Webhooks endpoints below.
```json theme={null}
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"name": "string",
"webhook_url": "http://example.com/",
"events": [
"task-status-updated",
"order-status-updated"
],
"env_type": "dev",
"enabled": true,
"created_at": "2022-05-04T11:30:00Z",
"updated_at": "2022-05-04T12:00:00Z"
}
```
# Webhook request history
## Overview
Use the Webhook request history endpoint to review and debug webhook delivery attempts made by Truv to your configured webhook URLs.
This endpoint returns a paginated list of webhook delivery attempts, including metadata such as delivery status and timestamps. It can help you:
* Confirm that Truv attempted to send a webhook
* Investigate failed deliveries (non-2xx responses, timeouts, etc.)
* Correlate webhook attempts with your internal logs
* Audit recent webhook activity
**Note:** Only webhook requests from the last 30 days are available.
## Endpoints
* [List webhook request history](/api-reference/webhooks/webhook_requests_list) - GET /webhook-requests/
## Example response
View the response for the Webhook request history endpoint below.
```json theme={null}
{
"next": null,
"previous": null,
"results": [
{
"webhook_id": "48427a36d43c4d5aa6324bc06c692456",
"event_type": "task-status-updated",
"event_created_at": "2024-01-15T10:30:00Z",
"status_code": 200,
"error_message": null,
"webhook_payload": {
"webhook_id": "a3f5b7c9d1e2f4a6b8c0d2e4f6a8b0c2",
"event_type": "order-status-updated",
"event_created_at": "2026-01-27T00:00:16.279921Z",
"product": "assets",
"link_id": null,
"user_id": "b4c6d8e0f2a4b6c8d0e2f4a6b8c0d2e4",
"order_id": "c5d7e9f1a3b5c7d9e1f3a5b7c9d1e3f5",
"status": "expired"
},
"webhook_url": "https://example.com/webhooks/truv"
}
]
}
```
# List webhook request history
Source: https://docs.truv.com/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 endpoint
Source: https://docs.truv.com/api-reference/webhooks/webhooks_create
POST /v1/webhooks/
The endpoint creates a webhook.
# Delete a webhook endpoint
Source: https://docs.truv.com/api-reference/webhooks/webhooks_delete
DELETE /v1/webhooks/{webhook_id}/
The endpoint deletes a webhook.
# List all webhook endpoints
Source: https://docs.truv.com/api-reference/webhooks/webhooks_list
GET /v1/webhooks/
The endpoint returns a list of webhooks.
# Update a webhook endpoint
Source: https://docs.truv.com/api-reference/webhooks/webhooks_partial_update
PATCH /v1/webhooks/{webhook_id}/
The endpoint updates a webhook.
# Retrieve a webhook endpoint
Source: https://docs.truv.com/api-reference/webhooks/webhooks_read
GET /v1/webhooks/{webhook_id}/
This endpoint retrieves a webhook.
# Direct Deposit Switch
Source: https://docs.truv.com/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:** [Direct Deposit Switch](/developers/demos/retail-banking/direct-deposit-switch)
***
## Get started
Clone and run the [Direct Deposit Switch demo](/developers/demos/retail-banking/direct-deposit-switch) 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/overview) 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/webhooks) 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/overview) |
| Webhook handling | [`server/webhooks.js`](https://github.com/truvhq/demo-apps/blob/main/server/webhooks.js) | [Webhooks](/api-reference/webhooks) |
| 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://docs.truv.com/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
**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://docs.truv.com/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 instantlyUp to 2 years of categorized transactionsIdentify recurring payroll deposits automatically30/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 BridgeFinancial account detailsAccount balance dataCreate 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://docs.truv.com/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 BridgeDeposit switch reportDDS link detail reportCreate 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://docs.truv.com/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 documentsPaystubs, W-2s, 1099s, bank statements, and moreAutomatic document type and readability checksSeamless 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. With [intelligent intake](/developers/integration/document-processing#intelligent-intake), users can upload any mix of files — including phone photos — and Truv flags unreadable scans up front and recognizes which files count.
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 APIManage document collectionsRetrieve parsed data
***
## Next steps
Platform-level document processing guide
Full API reference for document collections
# Smart Login
Source: https://docs.truv.com/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://docs.truv.com/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)
Files can be PDFs or phone photos. With [intelligent intake](/developers/integration/document-processing#intelligent-intake), Truv classifies each uploaded file, flags unreadable scans up front, and lets you finalize only the documents you need.
***
## Configure bridge token
When creating a [Truv Bridge](/developers/sdks/overview) [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://prod.truv.com/v1/permalink/most.recent.paystub.pdf)
* [Next recent paystub](https://prod.truv.com/v1/permalink/next.recent.paystub.pdf)
* [First paystub](https://prod.truv.com/v1/permalink/first.paystub.pdf)
* [W2](https://prod.truv.com/v1/permalink/w2.pdf)
### 1099 Tax Forms
* [1099-DIV](https://prod.truv.com/v1/permalink/1099div.pdf), [1099-G](https://prod.truv.com/v1/permalink/1099g.pdf), [1099-INT](https://prod.truv.com/v1/permalink/1099int.pdf), [1099-MISC](https://prod.truv.com/v1/permalink/1099misc.pdf), [1099-NEC](https://prod.truv.com/v1/permalink/1099nec.pdf), [1099-R](https://prod.truv.com/v1/permalink/1099r.pdf), [SSA-1099](https://prod.truv.com/v1/permalink/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://docs.truv.com/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/overview), 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://docs.truv.com/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:** [Bank Income](/developers/demos/consumer-credit/bank-income)
***
## Get started
Clone and run the [Bank Income demo](/developers/demos/consumer-credit/bank-income) 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/overview) with the `bridge_token`. The applicant connects their bank account.
5. **Receive webhooks** -- Truv sends a `task-status-updated` [webhook](/api-reference/webhooks) 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/overview) |
| Webhook verification | [`server/webhooks.js`](https://github.com/truvhq/demo-apps/blob/main/server/webhooks.js) | [Webhooks](/api-reference/webhooks) |
| 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://docs.truv.com/credit/integration/implementation
Choose the right verification method for your lending workflow
Verify applicant income, employment, and assets by embedding [Truv Bridge](/developers/sdks/overview) 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/overview) with the `bridge_token`. The applicant connects their provider.
4. **Receive webhooks** -- Truv sends a `task-status-updated` [webhook](/api-reference/webhooks) 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://docs.truv.com/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:** [Payroll Income](/developers/demos/consumer-credit/payroll-income)
***
## Get started
Clone and run the [Payroll Income demo](/developers/demos/consumer-credit/payroll-income) 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/overview) with the `bridge_token`. The applicant connects their payroll account.
5. **Receive webhooks** -- Truv sends a `task-status-updated` [webhook](/api-reference/webhooks) 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/overview) |
| Webhook verification | [`server/webhooks.js`](https://github.com/truvhq/demo-apps/blob/main/server/webhooks.js) | [Webhooks](/api-reference/webhooks) |
| 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://docs.truv.com/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/overview), 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:** [Paycheck-Linked Loans](/developers/demos/consumer-credit/paycheck-linked-loans)
***
## Get started
Clone and run the [Paycheck-Linked Loans demo](/developers/demos/consumer-credit/paycheck-linked-loans) 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/overview) 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/webhooks) 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/overview) |
| Webhook verification | [`server/webhooks.js`](https://github.com/truvhq/demo-apps/blob/main/server/webhooks.js) | [Webhooks](/api-reference/webhooks) |
| 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://docs.truv.com/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:** [Smart Routing](/developers/demos/consumer-credit/smart-routing)
***
## Get started
Clone and run the [Smart Routing demo](/developers/demos/consumer-credit/smart-routing) 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/overview) with the `bridge_token`. The applicant connects their provider.
5. **Receive webhooks** -- Truv sends a `task-status-updated` [webhook](/api-reference/webhooks) 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/overview) |
| Webhook verification | [`server/webhooks.js`](https://github.com/truvhq/demo-apps/blob/main/server/webhooks.js) | [Webhooks](/api-reference/webhooks) |
| 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://docs.truv.com/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)
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)
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://docs.truv.com/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 dataData from Chase, Bank of America, and thousands more30/60/90-day balance averages and deposit patternsVerified 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/overview) 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 BridgeRetrieve asset dataFinancial account detailsCreate 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://docs.truv.com/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/overview) 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 capacityExtend credit to thin-file and underserved borrowersIdentify recurring deposits without payroll connection30-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 BridgeAccount balance dataFinancial account detailsCreate 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://docs.truv.com/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 secondsADP, Paychex, Workday, UKG, and 100+ payroll providersStructured data ready for your decision engineW-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/overview) 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 BridgeRetrieve income dataRetrieve employment dataCreate 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://docs.truv.com/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/overview).
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 BridgePaycheck Linked Lending reportPLL link detail reportCreate 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://docs.truv.com/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 creditScore borrowers with limited credit historyScores derived from real bank activity, not modelsAnalyze 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 schemaCreate tokens for Truv BridgeCreate and manage users
***
## Next steps
Full API reference and schema
Transaction data that feeds scoring reports
# Widget-only Best Practices
Source: https://docs.truv.com/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://docs.truv.com/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://docs.truv.com/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://docs.truv.com/llms.txt) | \~3.5 KB | Structured overview with links to docs sections |
| [`llms-full.txt`](https://docs.truv.com/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
### Seed your rules file
Drop this into `CLAUDE.md`, `AGENTS.md`, or `.cursorrules` so your AI tool follows Truv conventions without re-deriving them each time:
```md theme={null}
# Truv API conventions
- Base URL: https://prod.truv.com/v1/ (credentials select sandbox vs production)
- Auth headers: X-Access-Client-Id and X-Access-Secret (never Authorization: Bearer)
- Money amounts are decimal strings, e.g. "50000.00"
- Products: income, employment, assets, deposit_switch, pll
## Bridge (frontend)
- Embedded Orders: initialize TruvBridge with isOrder: true
- User Token flows (e.g. Deposit Switch): initialize WITHOUT isOrder
- Callbacks: onSuccess, onLoad, onEvent, onClose
- Errors surface in onEvent with type=ERROR and an ErrorData payload — there is no onError callback
## Statuses
- Task lifecycle: new → login → mfa → parse → full_parse → done
- Income/employment emit full_parse (base data) before done; assets (VOA) emit done only
- Error statuses: login_error, mfa_error, account_locked, unavailable
## Webhooks
- Verify the X-WEBHOOK-SIGN header: HMAC-SHA256 of the raw request body, format v1={hash}
- Respond with 2xx within 10 seconds; dedupe on webhook_id
## Enums (report output)
- pay_frequency: M, SM, W, BW, A, SA, C
- income_unit: YEARLY, MONTHLY, WEEKLY, DAILY, HOURLY
- job_type: F, P, S, D, C, V
- account_type: C, S — deposit_type: E, P, A
- Deposit Switch INPUT (deposit_details) uses words instead: account_type checking/savings, deposit_type entire/percent/amount
```
***
## 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` |
| Deposit Switch input uses report codes (`C`/`S`, `E`/`P`/`A`) | Input `deposit_details` uses words: `account_type` is `checking`/`savings`, `deposit_type` is `entire`/`percent`/`amount`. Only the report output uses the single-letter codes. |
| Fetch the report when status is `done` | Income and employment fire `full_parse` (base data) before `done`; assets (VOA) only fire `done` |
***
## 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.
```
```
Build a server-side poller that fetches a Truv income report via
GET /v1/links/{link_id}/income/report/ using X-Access-Client-Id and
X-Access-Secret headers. Poll until the link status is full_parse or done;
stop on error, no_data, or unavailable. Respect the documented rate limit.
```
```
Trigger a Truv data refresh for an existing link without re-prompting the user.
Create a refresh task at POST /v1/refresh/tasks/ for the stored access_token,
then handle the task-status-updated webhook the same way as the initial run.
```
```
Write a function that takes a Truv income verification report and extracts:
- Current employer name, job title, start_date, is_active status, and pay_frequency
- Most recent pay statement: gross_pay, net_pay, pay_date, gross_pay_ytd
- Annual income breakdown by year from annual_income_summary
- All bank accounts (bank_accounts) with routing_number and deposit_type
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://docs.truv.com/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://docs.truv.com/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://docs.truv.com/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/overview) 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.
| 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
### 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
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
### 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.
**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://docs.truv.com/developers/dashboard
Your central hub for managing verifications, teams, customization, billing, integrations and more.
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/overview) 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) 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.
***
## 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://docs.truv.com/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.
### 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.
***
## Orders
The Orders tab shows every Truv verification order in your account.
### 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.
### Create an order
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) 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.
### 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 |
### 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**
### 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
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://docs.truv.com/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.
* 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.
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.
* 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://docs.truv.com/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.
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.
| 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.
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.
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://docs.truv.com/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.
### 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.
### 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.
### 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 [Webhooks](/api-reference/webhooks) for the full list of supported event types and payload schemas, plus 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://docs.truv.com/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.
| 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#universal-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.
***
## 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://docs.truv.com/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.
### 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://docs.truv.com/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
| 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.
### 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.
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.
| 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.
### 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://docs.truv.com/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.
***
## 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
# Bank Income Demo
Source: https://docs.truv.com/developers/demos/consumer-credit/bank-income
Verify applicant income from bank transactions when payroll data is unavailable
The Bank Income demo shows how to verify income by connecting to an applicant's bank account and analyzing transaction history — use this when payroll data isn't available for the applicant's employer. **Source:** [GitHub](https://github.com/truvhq/demo-apps#consumer-credit)
```bash theme={null}
git clone https://github.com/truvhq/demo-apps.git
cd demo-apps && npm install && cp .env.example .env
npm start && npm run dev # select "Consumer Credit" → "Bank Income"
```
## Flow
The backend creates a user and generates a bridge token restricted to financial accounts.
```
POST /v1/users/
POST /v1/users/{id}/tokens/
# { product_type: "income", data_sources: ["financial_accounts"] }
```
Bridge opens showing only financial institutions. The applicant selects their bank and logs in.
Sandbox credentials: `goodlogin` / `goodpassword`
`task-status-updated` fires on completion. Fetch the Income Insights report.
```
POST /v1/users/{user_id}/income_insights/reports/
```
**Integration pattern:** [Bridge Widget](/developers/integration/bridge-widget/overview) | **Products:** Income Insights
# Paycheck-Linked Loans Demo
Source: https://docs.truv.com/developers/demos/consumer-credit/paycheck-linked-loans
Verify income and set up automatic loan repayment through payroll deductions in one flow
The Paycheck-Linked Loans demo shows how to verify income and configure automatic loan repayment via payroll deductions in one Bridge flow. Payments start on the next pay cycle once the applicant connects their payroll provider. **Source:** [GitHub](https://github.com/truvhq/demo-apps#consumer-credit)
```bash theme={null}
git clone https://github.com/truvhq/demo-apps.git
cd demo-apps && npm install && cp .env.example .env
npm start && npm run dev # select "Consumer Credit" → "Paycheck-Linked Loans"
```
## Flow
The backend creates a user and generates a bridge token with `product_type: pll`.
```
POST /v1/users/
POST /v1/users/{id}/tokens/
# { product_type: "pll", account_details: true }
```
Bridge opens. The applicant selects their employer, logs in, and authorizes the payroll deduction.
Sandbox credentials: `goodlogin` / `goodpassword`
`task-status-updated` fires on completion. Fetch both the VOIE report and the deposit switch report.
```
POST /v1/users/{user_id}/reports/
GET /v1/users/{user_id}/deposit_switch/report/
```
**Integration pattern:** [Bridge Widget](/developers/integration/bridge-widget/overview) | **Products:** PLL
# Payroll Income Demo
Source: https://docs.truv.com/developers/demos/consumer-credit/payroll-income
Verify income and employment directly from payroll data for fast lending decisions
The Payroll Income demo shows the fastest path to income verification: connect directly to the applicant's payroll provider to return current income, employment status, and pay history in a single flow. **Source:** [GitHub](https://github.com/truvhq/demo-apps#consumer-credit)
```bash theme={null}
git clone https://github.com/truvhq/demo-apps.git
cd demo-apps && npm install && cp .env.example .env
npm start && npm run dev # select "Consumer Credit" → "Payroll Income"
```
## Flow
The backend creates a user and generates a bridge token restricted to payroll providers.
```
POST /v1/users/
POST /v1/users/{id}/tokens/
# { product_type: "income", data_sources: ["payroll"] }
```
Bridge opens showing only payroll providers. The applicant selects their employer and logs in.
Sandbox credentials: `goodlogin` / `goodpassword`
`task-status-updated` fires on completion. Fetch the VOIE report.
```
POST /v1/users/{user_id}/reports/
```
**Integration pattern:** [Bridge Widget](/developers/integration/bridge-widget/overview) | **Products:** VOIE
# Smart Routing Demo
Source: https://docs.truv.com/developers/demos/consumer-credit/smart-routing
Check employer payroll coverage and route applicants to the fastest verification method
The Smart Routing demo checks an employer's payroll coverage and recommends the best verification path — payroll, bank transactions, or document upload — based on actual coverage data. **Source:** [GitHub](https://github.com/truvhq/demo-apps#consumer-credit)
```bash theme={null}
git clone https://github.com/truvhq/demo-apps.git
cd demo-apps && npm install && cp .env.example .env
npm start && npm run dev # select "Consumer Credit" → "Smart Routing"
```
## Flow
The applicant enters their employer name. The backend checks payroll coverage and returns a `success_rate`.
```
GET /v1/company-mappings-search/?query=...
```
Based on `success_rate`, the UI recommends a `data_sources` value. The backend creates a user and token.
```
POST /v1/users/
POST /v1/users/{id}/tokens/
# { product_type: "income", data_sources: [...] }
```
Bridge opens with the selected method. After completion, fetch the report.
```
POST /v1/users/{user_id}/reports/
```
**Integration pattern:** [Bridge Widget](/developers/integration/bridge-widget/overview) | **Products:** VOIE
# Document Processing Demo
Source: https://docs.truv.com/developers/demos/mortgage/document-processing
Upload pay stubs, W-2s, and tax returns and extract structured income data for underwriting
The Document Processing demo shows how to validate and extract structured income data from documents already collected — pay stubs, W-2 forms, tax returns, and bank statements — without launching Bridge. **Source:** [GitHub](https://github.com/truvhq/demo-apps#mortgage)
```bash theme={null}
git clone https://github.com/truvhq/demo-apps.git
cd demo-apps && npm install && cp .env.example .env
npm start && npm run dev # select "Mortgage" → "Document Processing"
```
## Flow
Upload pay stubs, W-2s, 1040s, or bank statements. The backend creates a user and a document collection.
```
POST /v1/users/
POST /v1/documents/collections/
```
Poll until all files reach a terminal status.
```
GET /v1/documents/collections/{id}/
```
Finalize the collection to generate the structured income report.
```
POST /v1/documents/collections/{id}/finalize/
GET /v1/documents/collections/{id}/finalize/
```
**Integration pattern:** [Document Processing](/developers/integration/document-processing) | **Products:** Pay stubs, W-2s, 1040s, bank statements
# LOS Demo
Source: https://docs.truv.com/developers/demos/mortgage/los
Create verification orders from your LOS and send borrowers a link to complete on their own
The LOS demo shows server-side order creation: a loan processor creates verification orders using borrower data already on file, and Truv sends the borrower an email or SMS link to complete verification on their own device. **Source:** [GitHub](https://github.com/truvhq/demo-apps#mortgage)
```bash theme={null}
git clone https://github.com/truvhq/demo-apps.git
cd demo-apps && npm install && cp .env.example .env
npm start && npm run dev # select "Mortgage" → "LOS"
```
## Flow
Enter borrower PII from the LOS. The backend creates an order and receives a `share_url`.
```
POST /v1/orders/
# Returns order_id + share_url
```
Truv delivers the `share_url` to the borrower via email or SMS. No Bridge embedding needed on your end.
The borrower opens the link and connects their employer. `order-status-updated` fires on completion.
```
POST /v1/users/{user_id}/reports/
```
**Integration pattern:** [Hosted Orders](/developers/integration/hosted-orders/new-user) | **Products:** VOIE, VOE
# POS Application Demo
Source: https://docs.truv.com/developers/demos/mortgage/pos-application
Verify borrower income or assets in real time during the loan application
The POS Application demo shows how a borrower fills out a loan application and verifies income or assets inline, without leaving the point-of-sale. **Source:** [GitHub](https://github.com/truvhq/demo-apps#mortgage)
```bash theme={null}
git clone https://github.com/truvhq/demo-apps.git
cd demo-apps && npm install && cp .env.example .env
npm start && npm run dev # select "Mortgage" → "POS Application"
```
## Flow
Enter applicant PII. The app searches for the employer and creates an Order.
```
GET /v1/company-mappings-search/?query=...
POST /v1/orders/
```
Truv Bridge opens inline. The borrower selects their employer and logs in.
Sandbox credentials: `goodlogin` / `goodpassword`
`order-status-updated` fires on completion. Fetch the structured report.
```
POST /v1/users/{user_id}/reports/
```
**Integration pattern:** [Embedded Orders](/developers/integration/embedded-orders/overview) | **Products:** VOIE, VOA
# POS Tasks Demo
Source: https://docs.truv.com/developers/demos/mortgage/pos-tasks
Complete outstanding income, employment, and asset verifications after loan submission
The POS Tasks demo shows the follow-up flow: after submitting a loan application, the borrower returns to complete outstanding verification tasks — income, employment, and assets — all linked by a shared `external_user_id`. **Source:** [GitHub](https://github.com/truvhq/demo-apps#mortgage)
```bash theme={null}
git clone https://github.com/truvhq/demo-apps.git
cd demo-apps && npm install && cp .env.example .env
npm start && npm run dev # select "Mortgage" → "POS Tasks"
```
## Flow
The loan processor creates separate orders for income, employment, and assets — all sharing the same `external_user_id`.
```
POST /v1/orders/ # income
POST /v1/orders/ # employment
POST /v1/orders/ # assets
```
Each order returns a `bridge_token`. Bridge opens for each task in sequence.
Sandbox credentials: `goodlogin` / `goodpassword`
`order-status-updated` fires per task. Fetch the appropriate report for each.
```
POST /v1/users/{user_id}/reports/
POST /v1/users/{user_id}/assets/reports/
```
**Integration pattern:** [Embedded Orders](/developers/integration/embedded-orders/overview) (multi-task) | **Products:** VOIE, VOE, VOA
# Case Worker Portal Demo
Source: https://docs.truv.com/developers/demos/public-sector/case-worker-portal
Create verification orders from applicant data and send a link for self-service completion
The Case Worker Portal demo shows server-side order creation for government workflows: a caseworker creates verification orders using applicant data on file, and Truv sends the applicant a link to complete verification on their own device. **Source:** [GitHub](https://github.com/truvhq/demo-apps#public-sector)
```bash theme={null}
git clone https://github.com/truvhq/demo-apps.git
cd demo-apps && npm install && cp .env.example .env
npm start && npm run dev # select "Public Sector" → "Case Worker Portal"
```
## Flow
Enter applicant PII from the case management system. The backend creates an order and receives a `share_url`.
```
POST /v1/orders/
# Returns order_id + share_url
```
Truv delivers the `share_url` to the applicant via email or SMS.
The applicant opens the link and connects their employer. `order-status-updated` fires on completion.
```
POST /v1/users/{user_id}/reports/
```
**Integration pattern:** [Hosted Orders](/developers/integration/hosted-orders/new-user) | **Products:** VOIE, VOE
# Customer Portal Demo
Source: https://docs.truv.com/developers/demos/public-sector/customer-portal
Let benefit applicants verify income and employment through a self-service portal
The Customer Portal demo shows a self-service benefits portal where an applicant verifies their income and employment through an embedded Truv flow — no caseworker required. **Source:** [GitHub](https://github.com/truvhq/demo-apps#public-sector)
```bash theme={null}
git clone https://github.com/truvhq/demo-apps.git
cd demo-apps && npm install && cp .env.example .env
npm start && npm run dev # select "Public Sector" → "Customer Portal"
```
## Flow
The applicant enters their PII in the benefits portal. The backend searches for the employer and creates an Order.
```
GET /v1/company-mappings-search/?query=...
POST /v1/orders/
```
Truv Bridge opens inline. The applicant connects their payroll provider.
Sandbox credentials: `goodlogin` / `goodpassword`
`order-status-updated` fires on completion. Fetch income and employment data for eligibility.
```
POST /v1/users/{user_id}/reports/
```
**Integration pattern:** [Embedded Orders](/developers/integration/embedded-orders/overview) | **Products:** VOIE, VOE
# Document Processing Demo
Source: https://docs.truv.com/developers/demos/public-sector/document-processing
Process pay stubs, W-2s, and tax returns for benefit eligibility decisions
The Public Sector Document Processing demo shows how to extract structured income data from documents submitted by benefit applicants for eligibility determination. **Source:** [GitHub](https://github.com/truvhq/demo-apps#public-sector)
```bash theme={null}
git clone https://github.com/truvhq/demo-apps.git
cd demo-apps && npm install && cp .env.example .env
npm start && npm run dev # select "Public Sector" → "Document Processing"
```
## Flow
Upload documents submitted by the applicant. The backend creates a user and a document collection.
```
POST /v1/users/
POST /v1/documents/collections/
```
Poll until all files reach a terminal status.
```
GET /v1/documents/collections/{id}/
```
Finalize to generate the structured income report for eligibility determination.
```
POST /v1/documents/collections/{id}/finalize/
GET /v1/documents/collections/{id}/finalize/
```
**Integration pattern:** [Document Processing](/developers/integration/document-processing) | **Products:** Pay stubs, W-2s, 1040s, bank statements
# Direct Deposit Switch Demo
Source: https://docs.truv.com/developers/demos/retail-banking/direct-deposit-switch
Switch a customer's direct deposit to your bank through their payroll provider
The Direct Deposit Switch demo shows how a new customer connects their payroll provider and redirects their direct deposit routing to your bank. The change takes effect on the next pay cycle. **Source:** [GitHub](https://github.com/truvhq/demo-apps#retail-banking)
```bash theme={null}
git clone https://github.com/truvhq/demo-apps.git
cd demo-apps && npm install && cp .env.example .env
npm start && npm run dev # select "Retail Banking" → "Direct Deposit Switch"
```
## Flow
The backend creates a user and generates a bridge token with `product_type: deposit_switch`.
```
POST /v1/users/
POST /v1/users/{id}/tokens/
# { product_type: "deposit_switch", account_details: true }
```
Bridge opens. The customer selects their employer and logs in to authorize the deposit switch.
Sandbox credentials: `goodlogin` / `goodpassword`
`task-status-updated` fires on completion. Fetch the deposit switch report.
```
GET /v1/users/{user_id}/deposit_switch/report/
```
**Integration pattern:** [Bridge Widget](/developers/integration/bridge-widget/overview) | **Products:** DDS
# Fraud Detection & Manual Review
Source: https://docs.truv.com/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 validation and classification](/developers/integration/document-processing#step-4-monitor-validation-and-classification-server-side)) 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}
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
Complete error code reference
Client-side event reference for error handling and fallback routing
# Welcome
Source: https://docs.truv.com/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
HTTP error codes, response shapes, rate limits, and 429 backoff
***
## 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://docs.truv.com/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}
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://docs.truv.com/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}
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/webhooks) 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 [Webhooks](/api-reference/webhooks) 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://docs.truv.com/developers/integration/bridge-widget/overview
The client-side widget for secure account connections
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** | `