Skip to main content
Disclosures are regulatory documents that borrowers must review and sign at various stages of the loan process. Pylon automatically generates and sends disclosures, but you need to retrieve signing links and track signing status.

Types of disclosures

Disclosure TypeWhen IssuedPurpose
Initial DisclosureAfter rate lock or 3 days after attaching product structureLoan Estimate and initial disclosures (TRID requirement)
RedisclosureWhen loan terms change after initial disclosureUpdated Loan Estimate if terms change
Closing DisclosureWhen loan reaches “Clear to Close”Final closing costs and loan terms (must be delivered 3 days before closing)

Retrieving disclosures

Query disclosures using the disclosuresHistory query and filter by packageType:
query GetDisclosures($loanId: ID!) {
  disclosuresHistory(loanId: $loanId) {
    disclosures {
      packageType
      status
      sentOn
      completedOn
      recipients {
        displayName
        email
        signed
        type
        link {
          url
          accessToken
        }
      }
      documentLinks {
        id
        title
        url
      }
    }
  }
}
Filter the results by packageType to get specific disclosure types:
  • INITIAL_DISCLOSURE - Initial disclosures (Loan Estimate)
  • REDISCLOSURE - Redisclosures (updated Loan Estimate)
  • CLOSING_DISCLOSURE - Closing disclosures (Closing Disclosure)

Disclosure status

StatusDescription
SENTDisclosure has been sent to borrowers
COMPLETEDAll recipients have signed, including borrowers and loan officer (LO)
SENDINGDisclosure is being sent
FAILEDDisclosure sending failed
CANCELLEDDisclosure was cancelled
EXPIREDDisclosure signing link expired
For borrower experiences and ITP checking: The COMPLETED status includes all recipients (borrowers and LO). If you’re building borrower-facing experiences or checking if Intent to Proceed (ITP) was received, use the Checking for Intent to Proceed (ITP) section instead, which checks only borrower signatures.
Each disclosure has recipients[] that contain signing links. Query disclosuresHistory and filter by packageType:
query GetDisclosureSigningLinks($loanId: ID!) {
  disclosuresHistory(loanId: $loanId) {
    disclosures {
      packageType
      recipients {
        displayName
        signed
        link {
          url
          accessToken
        }
      }
    }
  }
}
The link.url contains the signing URL, and link.accessToken is the authentication token needed to access it. When you get a disclosure URL and access token back, you need to submit the access token via an HTML POST request into an iframe to access and sign the disclosure packet. Here’s a React component implementation:
import React from "react";

/*
 * Inputs to this component are:
 * document URL, title, and access token
 */
interface PdfSsoViewerProps {
  url: string;
  title?: string;
  accessToken?: string;
}

/*
 * Styles for the PDF SSO Viewer component.
 * The container is set to scroll and the iframe is styled to fit within it.
 */
const styles = {
  container: {
    display: "flex",
    flexDirection: "column" as const,
    width: "100%",
    height: "100%",
    flex: 1,
    overflow: "auto",
    frameBorder: "0",
  },
  iframe: {
    width: "100%",
    height: "100%",
    flex: 1,
    border: "none",
    scrolling: "auto",
    frameBorder: "0",
  },
};

/**
 * PdfSsoViewer component renders an iframe that loads a PDF document
 * using a single sign-on (SSO) mechanism. It automatically submits a form
 * with the access token to the specified URL when the component mounts.
 *
 * @param {PdfSsoViewerProps} props - The properties for the component.
 * @returns {JSX.Element} The rendered component.
 */
export const PdfSsoViewer = ({
  url,
  title,
  accessToken,
}: PdfSsoViewerProps) => {
  /*
   * Effect to automatically submit the form when the component mounts.
   * This is used to pass the access token to the SSO URL.
   */
  React.useEffect(() => {
    (document.getElementById("redirect-form") as HTMLFormElement)?.submit();
  }, []);

  return (
    <div
      style={{
        ...styles.container,
      }}
    >
      <iframe
        name={"sso-viewer"}
        title={`${title ?? ""}`}
        style={styles.iframe}
      ></iframe>
      <form
        action={`${url}`}
        method={"post"}
        id={"redirect-form"}
        target={"sso-viewer"}
        style={{ display: "none" }}
      >
        <input name={"access_token"} type={"hidden"} value={`${accessToken}`} />
        <input name={"cookiePassthrough"} type={"hidden"} value={"true"} />
      </form>
    </div>
  );
};
How it works:
  1. The component creates a hidden form with method="post" that targets an iframe
  2. The form includes the access_token as a hidden input field with the value from link.accessToken
  3. The form’s action is set to the link.url from the disclosure query
  4. When the component mounts, it automatically submits the form, which POSTs the access token to the disclosure URL
  5. The disclosure signing interface loads in the iframe, authenticated via the access token
Usage example:
// After querying disclosuresHistory and filtering by packageType
const initialDisclosure = disclosuresHistory.disclosures.find(
  d => d.packageType === "INITIAL_DISCLOSURE"
);
const disclosureLink = initialDisclosure?.recipients[0]?.link;

<PdfSsoViewer
  url={disclosureLink.url}
  accessToken={disclosureLink.accessToken}
  title="Initial Disclosure Packet"
/>

Checking signing status

Check if all borrowers have signed by querying the signed field for each recipient:
query CheckDisclosureSigningStatus($loanId: ID!) {
  disclosuresHistory(loanId: $loanId) {
    disclosures {
      packageType
      recipients {
        displayName
        signed
        type
      }
    }
  }
}

Checking for Intent to Proceed (ITP)

Intent to Proceed (ITP) is established when all borrowers (type) have signed the INITIAL_DISCLOSURE. To check for ITP:
  1. Query disclosuresHistory and filter for packageType: "INITIAL_DISCLOSURE"
  2. Check that all recipients with type === "BORROWER" have signed === true
query CheckITP($loanId: ID!) {
  disclosuresHistory(loanId: $loanId) {
    disclosures {
      packageType
      recipients {
        type
        signed
        displayName
      }
    }
  }
}
Filter the results to find the disclosure where packageType === "INITIAL_DISCLOSURE", then verify that all recipients with type === "BORROWER" have signed === true. ITP is required before order-outs can be triggered automatically.

Signing workflow

1

Retrieve disclosure

Query the disclosuresHistory query to get disclosure information and signing links. Filter by packageType to get the specific disclosure type you need.
2

Get signing URL

Extract the recipients[].link.url and link.accessToken for each borrower.
3

Direct borrower to signing

Open the signing URL in a browser or embedded viewer. The URL includes authentication via the access token.
4

Poll for signing status

Poll the disclosuresHistory query to check when recipients[].signed becomes true.
5

Confirm ITP

Once all borrowers have signed initial disclosures, ITP is established and order-outs automatically trigger.

Disclosure previews

Before disclosures are sent, you can preview them using the disclosuresPreviews query:
query PreviewDisclosures($loanId: String!) {
  disclosuresPreviews(loanId: $loanId) {
    initialDisclosure {
      documentLinks {
        id
        title
        url
      }
    }
    closingDisclosure {
      documentLinks {
        id
        title
        url
      }
    }
  }
}
Previews show individual document URLs (vs. a single packet URL), making it easier to display documents in your UI.

TRID timing requirements

TRID timing is critical: Closing disclosures must be delivered to borrowers at least 3 business days before closing. Monitor the loan stage and ensure closing disclosures are requested and delivered in time.
  • Initial disclosures: Must be sent within 3 business days of selecting a loan product (or when rate is locked, whichever comes first)
  • Closing disclosures: Must be delivered at least 3 business days before closing
  • Redisclosures: Required when loan terms change after initial disclosure

Best practices

  1. Poll for new disclosures - Check for new disclosures every 30-60 minutes
  2. Notify borrowers immediately - Alert borrowers when disclosures are available for signing
  3. Track signing status - Poll regularly to confirm all borrowers have signed
  4. Handle expired links - Re-query disclosuresHistory if signing links expire
  5. Explain importance - Help borrowers understand that signing disclosures establishes ITP and triggers order-outs, moving the loan forward