Skip to main content

What is asset verification?

Asset verification is the process of confirming a borrower’s asset balances and account information to assess their ability to cover down payment, closing costs, and required reserves. Lenders must verify that borrowers have sufficient funds in their accounts to complete the mortgage transaction. Traditionally, asset verification has been a manual, time-consuming process requiring borrowers to:
  • Upload bank statements (typically 2-3 months)
  • Provide account verification letters (VOA/VOD)
  • Manually enter account balances and transaction history
  • Wait for manual document review and verification
Pylon automates this entire process using Day 1 Certainty (D1C) and Asset and Income Modeler (AIM) approved services that verify asset data automatically, reducing manual documentation and speeding up loan processing.

Why D1C/AIM asset verification matters

Day 1 Certainty (D1C) and Asset and Income Modeler (AIM) are programs from Fannie Mae and Freddie Mac that allow lenders to use automated verification sources to reduce conditions and speed up loan processing. When asset data comes from D1C/AIM approved sources, it’s considered a “verified” source, meaning no additional documentation is typically required, underwriting conditions are reduced, and loan processing is faster.

Pylon’s asset verification integrations

Pylon currently uses Plaid for D1C/AIM approved asset verification. Pylon will expand to support Truv for asset verification in the future.
  • Plaid - Account connection-based asset verification (requires borrower opt-in and your API call)
Assets only: Plaid is approved for D1C and AIM for assets only. While Plaid offers income verification products, those are not yet approved for D1C/AIM, so income items still require traditional documentation. See Income Verification for income verification options.

Plaid

Plaid is an account connection-based asset verification service that allows borrowers to connect their bank accounts to automatically verify asset balances and account information. Pylon is a reseller of Plaid and will create an account and API credentials on your behalf. Plaid is driven entirely through Pylon’s GraphQL API, and Pylon supports two integration paths depending on who drives the borrower’s connection:
  • Embedded widget — the borrower connects their bank account in-flow, inside your application, using the Plaid Link component.
  • Hosted link — an LO or processor requests a link on the borrower’s behalf and sends it to them (email, text, your own portal). The borrower completes the connection later, out-of-flow, on Plaid’s own hosted page. No widget embed required.
Both paths converge on the same backend: once the borrower connects, Pylon retrieves verified asset data asynchronously and populates the loan file identically either way.

Choosing an integration path

Both paths require the borrower to opt in and connect their account—Plaid asset verification is never fully automatic.

Option 1: Embedded widget (borrower connects in-flow)

How the embedded widget works

1

Request initialization token from Pylon

You request an initialization token from Pylon for the borrower. Pylon provides you with a linkToken to initialize the Plaid Link component.
2

Initialize Plaid Link component

Use the linkToken provided by Pylon to initialize the Plaid Link component for that borrower in your application.
3

Borrower opts in and connects accounts

The borrower opts in and connects their bank accounts through Plaid’s secure connection flow. This allows Plaid to access account balance and transaction information.
4

Widget exchanges public token

After the borrower completes authentication, the Plaid Link widget automatically exchanges the publicToken with Pylon via the onSuccess callback (passed as a parameter to the widget). This establishes permanent access to those accounts—you don’t need to explicitly exchange the token.
5

Pylon handles data retrieval

Pylon automatically retrieves verified asset data from Plaid asynchronously. This includes account balances, account types, and institution information.
6

Pylon uses verified data

Verified asset data is automatically stored in the loan file. Pylon uses this verified data for underwriting and qualification calculations.
7

No additional documentation needed

Since the data comes from Plaid (a D1C and AIM approved source), no additional asset documentation is typically required. Pylon’s underwriting system accepts the verified data without additional documentation.

Embedded widget characteristics

  • Client opt-in required: Borrowers must opt in and connect their accounts through Plaid’s connection flow
  • You must call it: Request an initialization token from Pylon and initialize the Plaid Link component—it does not happen automatically
  • >95% coverage: Plaid has over 95% coverage of banks and financial institutions
  • Assets only: Plaid is approved for D1C/AIM for assets only, not income verification
  • Pylon handles data mapping: Pylon automatically maps all account types (checking, savings, etc.) to appropriate Pylon asset fields—no work required on your end

Handling stale credentials (update mode)

After a borrower connects their bank account through Plaid, the connection can become stale — for example, if the borrower changes their bank password or their session expires. When this happens, Plaid reports an ITEM_LOGIN_REQUIRED error, and the asset report cannot be refreshed until the borrower re-authenticates. Pylon exposes an update mode flow that lets the borrower fix their credentials without creating a new Plaid Item or losing their existing connection.
1

Detect stale credentials

When Pylon encounters an ITEM_LOGIN_REQUIRED error from Plaid, the error is surfaced in the GraphQL response’s errorDetails.plaidErrorCode field. Your application should watch for this error code.
2

Request an update mode token

Call the createUpdateModeToken mutation with the borrower ID and the Plaid item ID that needs re-authentication. Pylon returns a linkToken scoped to the existing item.
Input fields:
  • borrowerId — ID of the borrower whose connection is stale
  • itemId — Plaid item ID of the specific connection that needs re-authentication
3

Open Plaid Link in update mode

Use the returned linkToken to initialize the Plaid Link component. Because the token is scoped to an existing item, Plaid Link opens in update mode — the borrower only needs to re-enter their credentials for the specific bank, not go through the full account selection flow.
4

Pylon automatically retries

After the borrower re-authenticates, Plaid notifies Pylon via a LOGIN_REPAIRED webhook. Pylon automatically retries the asset report generation — no additional API call is needed from your side.
Automatic recovery: Once the borrower re-authenticates, Pylon handles everything else — retrying the asset report, retrieving the data, and updating the loan file. You only need to detect the stale credential error and present the update mode Plaid Link to the borrower.
Instead of embedding a widget in your own frontend, you can ask Pylon to create a hosted verification link and send it to the borrower yourself—by email, text, or through your own portal. The borrower opens the link later and completes the connection on Plaid’s hosted page, entirely outside your application. There is no widget to embed.
Off by default. This path needs to be enabled for your organization before you can call requestLink—the embedded widget flow is unaffected either way. Ask your account manager to turn it on.
This path requires the update:loan scope for the requestLink/refreshLink mutations, and read:loan for the items/links queries (the embedded widget’s verify mutations require update:borrower).
1

Request a link from Pylon

Call the requestLink mutation under the assetVerification namespace with the borrower’s ID. Pylon creates a Plaid hosted Link session and returns a hostedUrl—the borrower-facing hosted link—along with the link’s status and expiresAt.
Variables
RequestLinkInput fields:
  • borrowerId (ID!): the borrower being verified
RequestLinkResponse fields:
  • linkId (String!): Pylon’s ID for this hosted link
  • status (AssetVerificationLinkStatus!): PENDING, COMPLETED, or FAILED—a freshly created link is always PENDING
  • expiresAt (DateTime!): when the link stops being usable
  • hostedUrl (String): the hosted link to send the borrower; null if the link has no usable URL
2

Send the link to the borrower

Deliver hostedUrl to the borrower through whatever channel your application uses—email, SMS, an in-app notification, or your own borrower portal. Pylon does not deliver the link on your behalf.
3

Borrower connects on Plaid's hosted page

The borrower opens the link at any point before expiresAt, selects their bank, and authenticates through Plaid’s own hosted flow—no widget embed, and no active session in your application required.
4

Pylon retrieves and maps the data

Exactly as with the embedded widget: once the borrower connects, Pylon retrieves verified asset data from Plaid asynchronously and maps account types to the appropriate Pylon asset fields. No data-mapping work is required on your end.
5

Read the verified data

Once mapping completes, the verified balance lands on each Asset entity’s amount field. Poll the GraphQL API to detect completion (see Checking asset verification status).

Refreshing a stale hosted connection

A hosted link creates a Plaid Item just like the embedded widget does, so it can go stale the same way—for example, if the borrower changes their bank password. Where the embedded widget’s fix is update mode through a new verify.createUpdateModeToken call, the hosted-link equivalent is the refreshLink mutation: it re-authenticates the same Item (accounts keep their ids) instead of minting a new one.
Variables
RefreshLinkInput fields:
  • borrowerId (ID!): the borrower whose connection is stale
  • itemId (ID!): the specific bank connection (Plaid Item) that needs re-authentication—get this from assetVerification.items
The response shape matches requestLink; send the returned hostedUrl to the borrower the same way.
Prefer refresh over a fresh request for an already-connected institution. Requesting a brand-new link for an institution the borrower already connected mints a new Plaid Item and re-creates every account under new ids. Use refreshLink to re-authenticate the existing Item in place instead.
Use assetVerification.items to see the borrower’s currently linked institutions—useful for deciding whether to request a fresh link (new institution) or a refresh link (existing one):
Use assetVerification.links to see the borrower’s recent hosted links (both CONNECT and REFRESH kinds), newest first:
This returns the borrower’s 10 most recent links, newest first. hostedUrl is only populated while a link is PENDING and unexpired—expired, completed, or failed links return null. itemId is null on a fresh CONNECT link until the borrower completes it.
No cancel operation. Unlike Truv’s income-verification orders, there’s currently no mutation to cancel a hosted asset link. An unwanted link simply expires at expiresAt.
  • No widget required: GraphQL calls only—no Plaid Link SDK embed
  • Out-of-flow: The borrower can complete verification later, from an email or text, entirely outside your application session
  • You initiate it: An LO, processor, or your API caller explicitly requests the link—it does not happen automatically for every borrower
  • You own delivery: Pylon returns hostedUrl; sending it to the borrower is your responsibility
  • Connect or refresh: requestLink adds a new institution; refreshLink re-authenticates an existing one in place, without minting a new Item
  • Off by default: Ask your account manager to enable this capability for your organization before using it
  • Same downstream pipeline: Once the borrower connects, data retrieval and asset mapping work identically to the embedded widget path

Plaid reseller program

Pylon is a reseller of Plaid, which means:
  • Credentials managed by Pylon: Pylon can obtain Plaid credentials on behalf of clients
  • Billing through Pylon: Plaid usage is billed through Pylon’s main account
  • Simplified setup: Clients don’t need to manage their own Plaid account or credentials
Simplified integration: As a Plaid reseller, Pylon handles credential management and billing, making it easier for clients to integrate Plaid without managing separate accounts.

Integration options

Pylon clients integrate Plaid using Plaid Link, Plaid’s standard web-based authentication component. Plaid Link is a pre-built UI component that handles the entire bank connection flow, allowing borrowers to securely connect their bank accounts through a modal interface. How Plaid Link works:
  • Borrower clicks a button in your application
  • Plaid Link modal opens
  • Borrower selects their bank and authenticates
  • Asset report is generated and sent to Pylon
Seamless experience: Plaid Link provides a seamless borrower experience and is the standard integration method for Plaid asset verification. For complete implementation details, see the Plaid Link documentation.

Checking asset verification status

After asset verification is initiated (after borrower opt-in for Plaid), check the amount field on Asset entities to see if verification was successful. When assets are verified through Plaid, the amount field will be populated with verified account balances, and Pylon will use this verified data for underwriting without requiring additional documentation. For complete details on querying asset data, understanding asset types, and all asset fields, see the Assets entity guide.

GraphQL query example

Poll Pylon’s GraphQL API to check for verified asset values. The amount field will be populated when assets have been successfully verified through Plaid:
Key fields:
  • amount: The verified account balance. null if not yet verified, or a number if verified through Plaid
  • __typename: The concrete asset kind (e.g., CheckingAccountAsset, SavingsAccountAsset), used to select the matching inline fragment
  • institutionName: The name of the financial institution (for financial account assets)
  • accountIdentifier: The account identifier or account number (for financial account assets)
Verification status:
  • amount === null: Asset has not been verified yet, or verification is not available
  • amount > 0: Asset has been successfully verified through D1C/AIM approved sources

Node.js/TypeScript polling example

Here’s a complete example of polling for verified asset values using Node.js and TypeScript:
Key implementation details:
  • Polling strategy: The function polls at regular intervals (default: every 2 seconds) until verified assets are found or max attempts are reached
  • Verification check: Checks if amount is not null and greater than 0
  • Error handling: Includes error handling and fallback logic for when verification isn’t available
  • Multiple borrowers: Handles loans with multiple borrowers and collects all assets
  • Asset types: Handles different asset types (checking, savings, retirement accounts, etc.)

Benefits

For borrowers

  • No document upload: No need to upload bank statements when verification is successful
  • Real-time data: Asset data is current and accurate
  • Faster processing: Automated verification is faster than manual document review
  • Better experience: Seamless connection process vs. manual document collection

For lenders

  • Reduced conditions: Pylon’s underwriting system generates fewer conditions when assets are verified through D1C/AIM sources
  • Fewer borrower tasks: Pylon creates fewer tasks for borrowers when verification is successful
  • Faster closes: Pylon’s automated processing accelerates loan processing and reduces time to close
  • Better accuracy: Verified data from Plaid is more accurate than manual entry or document review
  • Cost savings: Reduced manual processing and document review costs

Limitations and fallbacks

When automated verification doesn’t work

Asset verification through Plaid may not be available if:
  • Plaid opt-in not completed: The borrower didn’t opt in to Plaid or didn’t complete the account connection process
  • Bank not covered: The borrower’s bank doesn’t participate in Plaid
  • Account type not supported: Some account types may not be supported by Plaid
  • Connection issues: Technical issues preventing successful account connection

Fallback to traditional methods

When automatic verification isn’t available, Pylon will request traditional asset verification documentation from borrowers:
  • Bank statements: Recent bank statements (typically 2-3 months)
  • Account verification letters: VOA (Verification of Assets) or VOD (Verification of Deposit) letters from banks
  • Account statements: Investment account statements, retirement account statements, etc.
  • Gift letters: For gift funds, gift letters and transfer documentation
Always have a fallback: Don’t assume all borrowers will have assets verified through Plaid. Plaid requires borrower opt-in, and some banks may not be covered. Always be prepared to use traditional verification methods when automated verification isn’t available.

Best practices

Monitoring verification status

  • Poll regularly: Check asset verification status as part of your loan status polling workflow
  • For Plaid (embedded widget): Request initialization tokens from Pylon and initialize the Plaid Link component for borrowers who opt in
  • For Plaid (hosted link): Call assetVerification.requestLink and send the returned hostedUrl to the borrower yourself; use assetVerification.items to decide between a fresh link and a refreshLink for an existing institution
  • Handle failures gracefully: If verification fails or isn’t available, immediately switch to traditional verification methods

Using verified data

  • Combine with other verifications: Use Plaid alongside other D1C/AIM approved sources (like Truv or The Work Number for income verification) for maximum benefit
  • Pylon updates qualification automatically: Once assets are verified, Pylon automatically recalculates qualification and eligibility, as verified assets may affect loan terms and reserve requirements