<iframe>
API messages
All messages sent to and from the LoanPASS app are plain JavaScript objects, with a message
field indicating the type of message. Note that we may add more messages in the future, so to future-proof your integration, ensure unknown message types are ignored!
Sendable messages
connect
Connect to the LoanPASS <iframe>
API. This message must be sent to the LoanPASS app before any other messages, and this message must be sent before any messages will be sent from LoanPASS back to your app.
After sending connect
, the <iframe>
will respond with the listening
message once it's ready to receive more messages.
It's recommended that this message is sent in an event listener that listens for the <iframe>
's load
event.
Fields
None
Example
iframe.addEventListener("load", function() {
iframe.contentWindow.postMessage({
message: "connect",
}, loanpassOrigin);
});
log-in
Automatically log the user in to LoanPASS with the given credentials.
NOTE: If the user is already signed in to the LoanPASS UI, then this message may cause them to log out and be logged in with the specified credentials. When this happens, the <iframe>
may be reloaded. To account for this properly, you should wait for the listening
message again before sending any more messages.
SECURITY NOTE: Like all messages, the log-in
message is handled entirely client-side, so the given email and password will be sent to the server in exactly the same way as if the user had entered the email and password themselves. However, for security purposes, that leads to 2 details to consider:
- The end user can get the credentials. A tech-savvy user could trivially use the Web Inspector in their browser to find the email and password that were sent to the
<iframe>
(say, by viewing the "Network" tab and looking for the "log in" API call). - The credentials should be stored and sent securely. The password for the user should be considered a secret, so it should be treated as such and standard best practices should be used.
Fields
clientAccessId
: The client access ID to log in as. This should be the same as the client access ID used to embed the<iframe>
.emailAddress
: The email address of the account to sign in as.password
: The password of the account to sign in as.
Example
Signing in a user
iframe.contentWindow.postMessage({
message: "log-in",
clientAccessId: "example-client",
emailAddress: "user@example.com",
password: "password1234",
}, loanpassOrigin);
Signing in a user on page load
// Track the current state of the user:
// 1. "pending": iframe just added to page, user may be logged out or logged in
// 2. "logged-in": `log-in` message sent, user is now logged in
let userState = "pending"; // "pending" | "logged-in"
const loanpassOrigin = "https://app.loanpass.io";
const clientAccessId = "example-client";
const emailAddress = "user@example.com";
const password = "password1234";
window.addEventListener("load", function () {
console.log("page loaded");
const iframe = document.createElement("iframe");
const handleListening = () => {
switch(userState) {
case "pending":
console.log("sending log in message...");
iframe.contentWindow.postMessage({
message: "log-in",
clientAccessId,
emailAddress,
password,
}, loanpassOrigin);
userState = "logged-in";
break;
case "logged-in":
console.log("log in completed");
break;
}
};
window.addEventListener("message", function (event) {
if (event.origin !== loanpassOrigin) {
console.warn("received message from unexpected origin", event);
return;
}
console.log("received message", event.data);
switch (event.data.message) {
case "listening":
handleListening();
break;
}
});
iframe.src = `${loanpassOrigin}/frame-redirect/${clientAccessId}`;
iframe.addEventListener("load", function () {
console.log("iframe load event fired");
if (iframe.contentWindow == null) {
return;
}
console.log("connecting...");
iframe.contentWindow.postMessage({
message: "connect",
}, loanpassOrigin);
});
document.getElementById("iframe-container").appendChild(iframe);
});
log-out
Log out the current user if they are logged in.
NOTE: Sending this message may trigger the <iframe>
to reload! To continue receiving messages after sending the log-out
message, make sure the connect
message is sent after the load
event triggers on the <iframe>
. See the connect
message for more details.
Fields
clientAccessId
: The client access ID of the login page to show.
Example
iframe.contentWindow.postMessage({
message: "log-out",
clientAccessId: "example-client",
}, loanpassOrigin);
See log-in
for more details about logging the user back in after logging out.
enable-price-locking
Set a flag to show a "Lock Request" button in the UI. When clicked, the LoanPASS app will send a price-lock
message back to your app. That is, sending enable-price-lock
doesn't itself handle price locking, it just enables integrators to grab the pricing data to handle price locking through another system.
After this message is sent and after filling out the fields on the "Price a Loan" page, clicking into a product, then clicking one of the prices in the table, the modal that pops up will have a "Lock Request" button at the bottom:
The label of the button can be changed by setting the lockRequestLabel
field on the message.
Fields
lockRequestLabel
(optional): A string indicating what label to use for the price locking button. Defaults to "Lock Request". The same label will also be used after clicking the button, where the label will change to say "${lockRequestLabel} Sent
".
Example
iframe.contentWindow.postMessage({
message: "enable-price-locking",
lockRequestLabel: "Lock Request", // optional
}, loanpassOrigin);
set-fields
Fill in fields on the "Price a Loan" page with preset values. Calling set-fields
is very similar to loading an existing scenario, except the data is controlled by the integration rather than the LoanPASS backend.
Fields
fields
: An array of specifying fields to set and their values. The format matches the.creditApplicationFields[]
schema from the/execute-product
and/execute-summary
Public API endpoints.fieldId
: The field ID.value
: An object describing the value of the field, with atype
field indicating the type of value.
Example
iframe.contentWindow.postMessage({
message: "set-fields",
fields: [
{
fieldId: "field@occupancy-type",
value: {
type: "enum",
enumTypeId: "occupancy-type",
variantId: "primary-residence"
}
},
{
fieldId: "field@desired-loan-term",
value: {
type: "duration",
unit: "months",
count: "6"
}
},
{
fieldId: "field@number-of-units",
value: {
type: "number",
value: "1"
}
},
]
}, loanpassOrigin);
Receivable messages
listening
Sent after the <iframe>
receives the connect
message and is ready to receive more messages.
price-lock
Sent when a user clicks the "Lock Request" button in the UI after the enable-price-locking
message is sent.
Fields
role
: Contains details about the user's active role.id
: The role ID.name
The display name of the role.
pricingProfile
: Contains details about the user's active pricing profile.id
: The pricing profile ID.name
The display name of the pricing profile.
product
: Contains details about the product that was price locked.id
: The product ID.name
The display name of the product.
investor
: Contains details about the investor of the product that was price locked.id
: The investor's ID.name
: The display name of the investor.
scenario
: The details about the price scenario that was locked. The schema matches the.priceScenarios[]
schema returned from the/execute-product
Public API endpoint.status
: The status of the price scenario, such asapproved
,rejected
, etc.adjustedRate
: The rate with rate adjustments applied.adjustedPrice
The price with price adjustments applied.priceScenarioFields
: An array of price scenario fields and values.fieldId
: The field ID.value
: An object describing the value of the field, ornull
if the field has no value.
calculatedFields
: An array of calculated fields and their values for this price scenario.fieldId
: The calculated field ID.value
: An object describing the value of the field, ornull
if the field has no value.
creditApplicationFields
: An array of fields and their values that were filled in by the user for the price scenario. This corresponds to thecreditApplicationFields
field for the/execute-product
Public API endpoint.fieldId
: The input's field ID.value
: An object describing the value of the field.
Example
{
"message": "price-lock",
"role": {
"id": "11",
"name": "Loan Officer"
},
"pricingProfile": {
"id": "22",
"name": "Standard"
},
"investor": {
"id": "123",
"name": "Test Investor",
"code": "TI",
"isPricingEnabled": true
},
"product": {
"id": "1234",
"code": "EXAMPLE",
"name": "Example Product",
"description": "Example product",
"activationTimestamp": "2021-01-01T00:00:00Z",
"deactivationTimestamp": null,
"investorId": "123"
},
"scenario": {
"id": "00000000-0000-0000-0000-000000000000",
"priceScenarioFields": [
{
"fieldId": "base-interest-rate",
"value": {
"type": "number",
"value": "1.0"
}
},
{
"fieldId": "rate-lock-period",
"value": {
"type": "duration",
"count": "15",
"unit": "days"
}
},
{
"fieldId": "base-price",
"value": {
"type": "number",
"value": "101.000"
}
}
],
"calculatedFields": [
{
"fieldId": "calc@fsb-lpmi-refinance",
"value": {
"type": "number",
"value": "0.000"
}
},
{
"fieldId": "calc@fsb-jumbo-max-price",
"value": null
},
{
"fieldId": "calc-field@ah-va-purch-tier",
"value": {
"type": "number",
"value": "4"
}
}
],
"adjustedRate": "1.75",
"adjustedRateLockPeriod": {
"count": "15",
"unit": "days"
},
"adjustedPrice": "101.000",
"status": "approved",
"priceAdjustments": [
{
"ruleId": "1234",
"amount": "0.25",
"description": "Price adjustment 1"
},
{
"ruleId": "5678",
"amount": "0.25",
"description": "Price adjustment 2"
}
],
"marginAdjustments": [
{
"ruleId": "12345",
"amount": "-0.300",
"description": "Margin adjustment"
}
],
"rateAdjustments": [],
"stipulations": []
},
"creditApplicationFields": [
{
"fieldId": "field@occupancy-type",
"value": {
"type": "enum",
"enumTypeId": "occupancy-type",
"variantId": "primary-residence"
}
},
{
"fieldId": "field@loan-purpose",
"value": {
"type": "enum",
"enumTypeId": "loan-purpose",
"variantId": "purchase"
}
},
{
"fieldId": "field@decision-credit-score",
"value": {
"type": "number",
"value": "750"
}
},
{
"fieldId": "field@state",
"value": {
"type": "string",
"format": "us-state-code",
"value": "TX"
}
},
{
"fieldId": "field@property-type",
"value": {
"type": "enum",
"enumTypeId": "property-type",
"variantId": "single-family"
}
},
{
"fieldId": "field@base-loan-amount",
"value": {
"type": "number",
"value": "400000.00"
}
}
]
}