Personal Loans Marketplace
Your guide to integrating Engine's Personal Loans Embed in your experience
This page outlines what's needed to integrate Engine's Personal Loans Embed into your website.
In this guide, we will explore what Engine’s Embed syntax looks like and best practices for loading it on your site. This includes topics like proactively addressing layout shift for optimized performance.
This is a high-level guide, and specific implementation details should be discussed with your Engine team.
Standard Embed Implementation
Engine's embed code can be placed in any order within your page, but for optimal user experience we recommend placing the script tag within the same div where the content is being rendered.
Basic Embed Syntax
<script
async
src="https://www.moneylion.com/network/{channel}/{zone}/web-component/lending-search/index.js"
data-embed-type="auto-mount"
></script>This is a representative example of what our embed code looks like, and contains placeholders as defined below. Placeholders and will be replaced with precise values in the embed code provided to you.
Embed Components
Channel: placeholder that will be replaced with precise values in the embed code provided to you.
Zone: placeholder that will be replaced with precise values in the embed code provided to you.
Component Name: corresponds to the specific product or Engine experience type that's being rendered.
Tracking Events Emitted by Embed
When you embed the Personal Loans experience, event callbacks fire automatically.
How It Works
As a consumer navigates through the experience, the embed emits partner messages: JSON objects with a name (the event type) and a payload (event-specific data). The iframe posts them to your host page via window.parent.postMessage(message, '*').
You do not register callbacks with Engine. You listen on your host page; messages arrive whether or not you handle them.
Not every UI action sends a message. Only the events listed below are part of the partner contract.
Messages are one-way. There is no acknowledgement or response channel.
Implementation Path
Partners using Web Embed receive events by listening for browser message events on the host page:
Message envelope
Field
Description
name
The event name (e.g. "onCreate", "onNavigate")
payload
Event-specific data; always includes timestamp (ISO-8601 string)
Events & Data
onCreate: Emitted when a lead-created model is mounted. For non-edit flows, editingPage is null.
onNavigate: Emitted when the flow moves from one step to another.
onUpdate: Emitted when a step is submitted. For normal submissions, editingPage is null. For confirmation edit submissions, editingPage is an array of edited pages.
onSubmit: Emitted when the final loan search is submitted.
onExit: Emitted when the user closes the embed (e.g. via the close button). experience is "search" when closed from the form flow and "compare" when closed from the results page.
onErrorPageView: Emitted when a search error page is viewed.
onErrorPageRetry: Emitted when a user clicks retry from a search error page.
onRateTableRender: Emitted when offers are rendered on the compare/results page.
Both arrays are always present. Typically one is populated and the other is empty, depending on which compare view rendered.
loanOffers[] item
Sent when the loans compare view is shown.
Field
Type
Definition
offerUuid
string
Offer UUID
financialInstitutionName
string
Lender name
financialInstitutionUuid
string
Lender UUID (empty string if unavailable)
productType
string
Product type from the API (e.g. "loan", "Loan")
productSubType
string
Product subtype (e.g. "personal_loan", "secured_loan")
loanAmount
number | string
Maximum loan amount (maxAmount)
apr
number | string
APR — resolved from maxApr, then meanApr, then minApr, else ""
termLength
number | string
Term length in months, or "" if unavailable
monthlyPayment
number | string
Monthly payment — resolved from maxMonthlyPayment, then monthlyPayment, then meanMonthlyPayment, else ""
Example:
specialOffers[] item
Sent when the special / other offers compare view is shown (debt relief, credit builder, cash advance, bill reduction, etc.).
Field
Type
Definition
offerUuid
string
Offer UUID
name
string
Offer headline / name shown in the UI
financialInstitutionName
string
Partner name
financialInstitutionUuid
string
Partner financial-institution UUID (empty string if unavailable)
productSubType
string
Product subtype (e.g. "credit_builder", "debt_relief", "bill_reduction")
Example:
Special-offer render items do not include productType, loanAmount, apr, termLength, or monthlyPayment.
What gets sent in each view
Compare view
loanOffers
specialOffers
Loans (default / paginated list)
Offers displayed on that page
[]
Special / other offers
[]
All special offers from the rate table
No offers
[]
[] (may still fire when empty render is emitted)
onOfferClick: Emitted when the user clicks an offer call-to-action. Suppressed if no leadUuid is available.
Payload fields
Field
Type
Definition
timestamp
string
ISO-8601 time when the click occurred
leadUuid
string
Applicant lead UUID (required on click)
offerUuid
string
Clicked offer UUID
financialInstitutionName
string
Lender / partner name
financialInstitutionUuid
string
Lender / partner UUID
productType
string
"loan" for loan offers; "Special" for special offers
productSubType
string
Product subtype
loanAmount
number | string
Loan amount (loan offers) or "undefined for specialOffers" (special offers)
apr
number | string
APR (loan offers) or "undefined for specialOffers" (special offers)
termLength
number | string
Term length (loan offers) or "undefined for specialOffers" (special offers)
monthlyPayment
number | string
Monthly payment (loan offers) or "undefined for specialOffers" (special offers)
Loan offer click
Same shape as a loanOffers[] item plus leadUuid and timestamp.
Special offer click
Uses the same field names, but productType is "Special" and the four metric fields are the literal string "undefined for specialOffers" (not null, not omitted):
One event is SDK-only and will not be emitted by the Personal Loans web embed:
onBack: Emitted by the SDK header back button
Note: unlike the Credit Cards embed, onExit is emitted by the Personal Loans web embed (see above).
Common productSubType values
Examples seen in loan and special-offer payloads:
personal_loan, secured_loan, line_of_credit, debt_relief, credit_builder, cash_advance, bill_reduction, installment_loans
Treat this as a representative set, not a frozen enum — new subtypes may appear as products are added.
How it works
Add this script tag wherever you want the embed to render. It loads an iframe that automatically fills its container and scales responsively.
Placeholders
channel
Provided in your embed code
zone
Provided in your embed code
component-name
The specific product/experience being rendered (see below)
data-embed-type
Must be "auto-mount" — without it, nothing renders
Component types
lending-search
A full application flow — user answers a few questions, gets matched offers in-session. Use as your primary entry point.
lending-explore
A browse-and-filter experience using data you already have or prefilled. Use inside an existing logged-in dashboard.
Interactive Demo
See the Personal Loans Embed in action:
Prefilling & Attribution
Add client tags to your embed to prefill known, non-PII fields and attribute leads for reporting. Both reduce friction and improve conversion.
Client tags (data-tags attribute, for reporting):
Prefill fields (data-tags attribute, for auto-populating the form):
Example — tags clientId and source for reporting, prefilled zip code:
Supported client tag keys
Keys are case-sensitive — use consistent casing across all requests
agentId · campaignId · clickId · clientId · deviceId · medium · sourceId · subId · subId1 · subId2 · subId3 · target · trafficsource · userId
Need a different key? Ask your Partner Manager — nonstandard keys slow down reporting and aren't recommended.
Supported Prefill fields (Personal Loans)
Requested Loan Amount
app.loanAmount
No dollar signs, e.g. 6000
City*
app.city
Spaces as %20, e.g. New%20York
Zip Code*
app.zipcode
5 digits, or 9 digits as 5+4
Date of Birth
app.dateOfBirth
Format mm/dd/yyyy
Annual Income
app.annualIncome
No dollar signs, e.g. 100000
*Overwritten if the user's location is detected.
Best Practices & Troubleshooting
Best practices
Use the snippet Engine gives you. Don't hardcode channel, zone, or component paths yourself.
Keep
asyncon the script tag. This prevents the embed script from blocking the rest of your page.Give the embed a real container. Set a width on the parent. Set a
min-heightwhen possible. This gives the iframe room to render and avoids large layout shifts.Allow Engine in your CSP. Your Content Security Policy must allow the Engine script in
script-srcandhttps://www.moneylion.com(or your Engine environment host) inframe-src.Follow this page's tags and prefill guidance. Attributes differ by product. Use this page's sample, or your Engine-provided snippet, rather than copying syntax from another embed.
Troubleshooting
The component doesn't show
Check your install mode:
Explicit custom element: Confirm the
moneylion-*element from your snippet is on the page.Auto-mount snippet: Confirm data-embed-type="auto-mount" is on the tag.
Open the browser console. Check for script load failures or CSP blocks.
The page feels slow
Confirm the
asyncattribute is on the<script>tag.Avoid nesting the embed in a hidden container, such as
display: none, at first load. This can delay useful height and layout work.
Events aren't firing
Confirm you listen for
messageevents. Check for{ name, payload }objects. See the tracking section on this page for product-specific events.In production, filter by Engine's origin. This ignores unrelated
postMessagetraffic from other page scripts.
Related
See Tracking Events for the full list of event callbacks this embed emits (onCreate, onNavigate, onOfferClick, and more).
Last updated
Was this helpful?

