Skip to main content
Start here when you have a new user and don’t know their employer, payroll provider, or bank upfront. Truv Bridge presents a search screen where the user finds and connects their accounts. Embedded order and widget Embedded Orders support the following data source types:
Data sourceProductsUse case
Payrollincome, employmentIncome verification, employment history. Note: income auto-includes employment data. You don’t need to request both.
Banktransactions, assetsAsset verification, transaction history
Documentsincome, employmentDocument upload verification (pay stubs, W-2s, tax forms)
TaxincomeTax return verification
If you already know the user’s employer or provider, use deeplinking to skip the search screen and go directly to the login flow.

How it works

  1. Create an order via API with desired products
  2. User opens the widget using the bridge token
  3. User connects accounts (payroll, banks)
  4. Receive data via webhook notifications
  5. Retrieve results using the order ID

Implement

Step 1: Create an order [Server-side]

Create an Order to link different data providers. The response includes a bridge_token to initialize Truv Bridge.
curl -X POST https://prod.truv.com/v1/orders/ \
  -H "X-Access-Client-Id: YOUR_TRUV_CLIENT_ID" \
  -H "X-Access-Secret: YOUR_TRUV_CLIENT_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "products": ["income"],
    "first_name": "John",
    "last_name": "Doe"
  }'
When you include income in the products array, employment data is automatically included. You do not need to pass both income and employment.
Best practice: Include email and phone on the order along with notification_settings to send a delayed notification if the user doesn’t complete verification during the embedded session:
{
  "notification_settings": {
    "suppress_user_notifications": false,
    "first_notification_delay_hours": 6
  }
}
This gives the user time to finish in-app, then sends a reminder if they haven’t completed within 6 hours.
The create order endpoint accepts additional fields to customize the verification:
FieldDescription
employersPre-populate the employer in Bridge so the user doesn’t have to search. Pass company_name and optionally company_address.
notification_settingsSuppress emails/SMS to the user with suppress_user_notifications: true, or delay the first notification with first_notification_delay_hours.
loanAttach loan metadata: loan_number (required), originator_name, originator_email, loan_processor_name, loan_processor_email.
external_user_idYour internal identifier for the user.
order_numberYour internal reference number for this order.
ssnLast 4 or full 9 digits. Enables SSN matching on the verification.
email / phoneContact info for sending the order link via email or SMS.
template_idCustomization template to apply.
Explore the full request schema →
Orders can be configured in two modes that control how users interact with pre-populated employers:
ModeBehaviorBest for
Open orderUser can skip pre-populated employers and add new ones not on the original orderFlexible flows where users may have changed jobs
Closed orderUser must attempt all pre-populated employers. Cannot add new ones.Strict verification where specific employers are required
Within open orders, two skip behaviors are available:
  • Require attempt, then allow skip — User must try connecting before they can skip
  • Allow skip without attempting — User can skip immediately
This is an account-level setting. Contact your Truv representative or support@truv.com to configure.
Extract the bridge_token from the response.
{
  "id": "39aa1486ccca4bc19cda071ffc1ba392",
  "order_number": "truv-o-39aa1486",
  // ... additional order fields
  "user_id": "b1e24b60b8d84b9da11e13f46a830f41",
  "bridge_token": "93be103a3ccd4d4fa38af0b1bfcf3be8"
  // ... full response includes status, timestamps, share_url, and more
}

Step 2: Initialize widget [Client-side]

Load Truv Bridge and pass the bridge_token from Step 1.
isOrder: true is required for Embedded Orders. Initializing without it causes unexpected behavior.
<script src="https://cdn.truv.com/bridge.js"></script>
<script>
  var bridgeToken = ''; // bridge_token from your server

  var bridge = TruvBridge.init({
    isOrder: true,
    bridgeToken: bridgeToken,
    onLoad: function() {
      console.log('Bridge loaded');
    },
    onSuccess: function() {
      console.log('User completed all connections');
    },
    onClose: function() {
      console.log('Widget closed');
    },
    onEvent: function(type, payload, source) {
      console.log('Event:', type, source);
      if (type === 'COMPLETED' && source === 'order') {
        // Order is fully finished — advance the user to the next step
        navigateToNextStep();
      }
    }
  });
</script>
Wait for the COMPLETED event with source: "order" before advancing the user in your application. This event fires when the order reaches its final state: all connections succeeded or were skipped. Do not use onSuccess or onClose to advance the user, as the order may still have pending connections.

Callbacks

CallbackDescriptionRequired
onLoadBridge finished loading the order pageOptional
onSuccessUser connected all accounts and clicked “I’m done”Optional
onCloseBridge closed the order pageOptional
onEventReceives events from the order page (source: "order") and the connection widget (source: "bridge"). See Bridge Events for all types.Optional

Display modes

Control how the widget appears using the position property. Bridge: Dialog mode vs. Inline mode
// Dialog mode (default) — overlays the page
var bridge = TruvBridge.init({
  isOrder: true,
  bridgeToken: bridgeToken
});

// Inline mode — renders inside a container element
var bridge = TruvBridge.init({
  isOrder: true,
  bridgeToken: bridgeToken,
  position: {
    type: 'inline',
    container: document.querySelector('#order-container')
  }
});
When using inline mode:
  1. The container element must remain stable. Do not unmount or reparent it while the bridge is open.
  2. Manually close the bridge before removing the container (e.g., on SPA navigation).
  3. Only one bridge instance can be open at a time.

Step 3: Test in sandbox

Test your implementation with sandbox credentials.
UsernamePasswordDescription
goodlogingoodpasswordFull-time current employment
hourly.part-timegoodpasswordHourly part-time worker
multiple.employmentsgoodpasswordMultiple employers
See Test Credentials for all scenarios.

Step 4: Monitor webhooks [Server-side]

Webhooks notify you when task and order statuses change. Use user_id to match events to a specific order. Task-level webhook, fires as each connection progresses.
{
  "webhook_id": "17a80437ce23411dbfd656694d19a8c6",
  "event_type": "task-status-updated",
  "event_created_at": "2024-07-11T21:43:08.073930Z",
  "product": "income",
  "link_id": "d8a8945ee2b049b193110cfba643f5df",
  "user_id": "adbe707dddee4334bffaeb5866272740",
  "data_source": "payroll",
  "task_id": "871fef2e79ea444ea2019c8845305d31",
  "tracking_info": null,
  "status": "done",
  "template_id": null,
  "updated_at": "2024-07-11T21:43:08.075540+00:00"
}
Order-level webhook, fires when the user finishes the order.
{
  "webhook_id": "0aac461e7b774a38a72fd9c7c0eef8ee",
  "event_type": "order-status-updated",
  "event_created_at": "2024-07-11T21:40:48.424610Z",
  "product": "income",
  "link_id": "d8a8945ee2b049b193110cfba643f5df",
  "user_id": "adbe707dddee4334bffaeb5866272740",
  "data_source": "payroll",
  "order_id": "ddd192646b3c48be96651a0ff25cef85",
  "order_number": "4138538",
  "employer_id": "d7166cffbfef4bd6a9e830cf5508e615",
  "status": "completed",
  "template_id": null,
  "updated_at": "2024-07-11T21:40:48.424655+00:00"
}
See Task lifecycle for all status transitions.

Step 5: Retrieve data [Server-side]

Fetch order details using the order_id. The response includes employer data, employment history, income statements, and report IDs.
curl https://prod.truv.com/v1/orders/{order_id}/ \
  -H "X-Access-Client-Id: YOUR_TRUV_CLIENT_ID" \
  -H "X-Access-Secret: YOUR_TRUV_CLIENT_SECRET"
See Order object for the full response schema.

Content Security Policy (CSP)

If your application uses a Content Security Policy, you must allow these domains for the embedded widget to load and function correctly:
DomainPurpose
my.truv.comTruv Bridge application
cdn.truv.comTruv Bridge JavaScript SDK
Content-Security-Policy: frame-src my.truv.com; script-src cdn.truv.com;
Missing CSP configuration is one of the most common causes of the widget failing to load in embedded contexts. If the widget doesn’t appear or shows a blank frame, check your CSP settings first.

Demo apps

Application Demo

Applicant verifies income, employment, or assets through Bridge in a single session.

Follow-up Demo

Applicant returns to complete multiple verification tasks tied to one file.

Next steps

Add Employer

Add additional employers to an existing order

Data Refresh

Pull updated data without user re-authentication

Deeplinking

Skip employer search for higher conversion