Developer Documentation
Embed the Loan Certifier agent portal directly inside your platform. Agents get a full-screen view of their loans and opportunities with a back button to return to your app — no separate pages, just one embed.
Portal Embed
Full-screen iframe with back button — copy & paste
Embed Tokens API
Generate user-tied tokens — cURL, Node, Python
AI Agents & MCP
Persona-based agents & AI client connectivity
postMessage API
Back button events & navigation between apps
Installation Guide
Follow these steps to embed the Loan Certifier portal in your platform. You can copy this entire guide as a prompt for your development team.
# Loan Certifier Portal Embed — Installation Guide
## Overview
Embed the Loan Certifier agent portal inside your platform. Agents see their loans
and opportunities in one full-screen view with a back button that returns to your app.
## Prerequisites
1. You need a Loan Certifier API key (contact support to get one).
2. Your server must be able to make HTTPS POST requests to https://app.loancertifier.com/functions/generateEmbedToken.
3. Your API key must be stored server-side — NEVER expose it in client-side code.
## Step 1: Get Your API Key
Contact Loan Certifier support to receive your platform API key. This key identifies
your integration and is used to generate embed tokens for your users.
## Step 2: Generate an Embed Token (Server-Side)
When one of your users needs to view their loans, call generateEmbedToken with their
email address. The token is tied to that specific user — dual verification.
curl -X POST https://app.loancertifier.com/functions/generateEmbedToken \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{ "agent_email": "user@example.com" }'
Response:
{
"token": "a1b2c3d4...",
"embed_url": "https://app.loancertifier.com/AgentPortalEmbed?token=a1b2c3d4...",
"expires_in": 3600
}
## Step 3: Embed the Portal (Client-Side)
Place an iframe in your app using the embed_url from Step 2. Add return_url so the
back button returns to your app:
<iframe
src="https://app.loancertifier.com/AgentPortalEmbed?token=TOKEN&return_url=https://yourapp.com/dashboard"
width="100%"
height="800"
frameborder="0"
style="border: none;"
></iframe>
## Step 4 (Optional): Deep-Link to a Specific Record
If you know a specific loan ID, open directly to it:
<iframe
src="https://app.loancertifier.com/AgentPortalEmbed?token=TOKEN&view=loan&id=LOAN_ID&return_url=https://yourapp.com/dashboard"
width="100%"
height="800"
frameborder="0"
style="border: none;"
></iframe>
## Step 5 (Optional): Listen for Events
Add a postMessage listener to receive back button and activity events:
window.addEventListener('message', function(event) {
if (event.origin !== 'https://app.loancertifier.com') return;
var data = event.data;
if (!data || data.source !== 'loan-certifier') return;
switch (data.type) {
case 'back_requested': window.history.back(); break;
case 'loan_viewed': console.log('Viewed:', data.payload.loan_id); break;
case 'note_added': console.log('Note on:', data.payload.loan_id); break;
}
});
## Token Refresh
Tokens expire after 1 hour. Regenerate before expiry if the user's session is longer.
For long-term integrations, ask about persistent tokens.
## Security
- API keys are server-side only — never in client code.
- Always verify event.origin before processing postMessage events.
- Configure allowed_origins on your API key to restrict which domains can embed.Note on Authentication: The embed itself does NOT require the agent to sign in — the embed token handles authentication. However, the developer reading these docs does need access. If you're sharing this page with a developer who doesn't have a Loan Certifier account, contact support to get a public link or share the installation guide directly.
Portal Embed
One iframe drops the entire agent portal into your app — full screen, no sidebar, no header chrome. Agents see all their loans and opportunities in one view with a back button that returns to your app.
Basic Embed
<!-- Full Agent Portal Embed — loans + opportunities in one view -->
<iframe
src="https://app.loancertifier.com/AgentPortalEmbed?token=YOUR_EMBED_TOKEN&return_url=https://yourapp.com/dashboard"
width="100%"
height="800"
frameborder="0"
style="border: none; border-radius: 12px;"
id="loan-certifier-embed"
></iframe>Deep-Linked Embed (Optional)
Optionally open directly to a specific loan or opportunity by passing view and id.
<!-- Optional: open directly to a specific loan -->
<iframe
src="https://app.loancertifier.com/AgentPortalEmbed?token=YOUR_EMBED_TOKEN&view=loan&id=LOAN_ID&return_url=https://yourapp.com/dashboard"
width="100%"
height="800"
frameborder="0"
style="border: none;"
></iframe>
<!-- Optional: open to a specific opportunity -->
<iframe
src="https://app.loancertifier.com/AgentPortalEmbed?token=YOUR_EMBED_TOKEN&view=opportunity&id=OPP_ID&return_url=https://yourapp.com/dashboard"
width="100%"
height="800"
frameborder="0"
style="border: none;"
></iframe>return_url — When provided, the embed's "Back" button navigates to this URL (your app). If not provided, it sends a postMessage to the parent frame or goes back in browser history.
Embed URL Parameters
Query parameters for the AgentPortalEmbed URL. Only the token is required — everything else is optional.
| Parameter | Required | Description |
|---|---|---|
token | Yes | Embed token from generateEmbedToken API. Tied to the agent's email for dual verification. |
return_url | No | URL the "Back" button navigates to (e.g. your CRM dashboard). If omitted, sends postMessage to parent frame. |
view | No | Optional deep-link to a specific record. Values: "loan" or "opportunity". Must be used with "id". |
id | No | Record ID to deep-link to (used with "view"). |
Embed Tokens API
Generate secure, time-limited embed tokens for agent authentication. Server-side only — your API key must never be exposed to the browser.
# Generate an embed token via API
# Dual verification: token authenticates the partner app (via API key),
# and the agent_email identifies which specific user is accessing.
curl -X POST https://app.loancertifier.com/functions/generateEmbedToken \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"agent_email": "agent@example.com"
}'
# Response:
# {
# "token": "a1b2c3d4...",
# "embed_url": "https://app.loancertifier.com/AgentPortalEmbed?token=a1b2c3d4...",
# "agent_email": "agent@example.com",
# "expires_in": 3600,
# "expires_at": "2025-01-15T10:00:00Z"
# }
#
# The token is cryptographically tied to the agent_email.
# When the embed loads, verifyEmbedToken validates the token AND
# returns the verified agent_email — dual verification.Verify Token (Server-Side)
// Verify an embed token (server-side)
const response = await fetch('https://app.loancertifier.com/functions/verifyEmbedToken', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ token: 'a1b2c3d4...' })
});
const result = await response.json();
// {
// "valid": true,
// "agent_email": "agent@example.com",
// "agent_name": "Jane Smith",
// "sub_account_id": "...",
// "company_id": "...",
// "scopes": ["loans", "opportunities", "notes", "conditions"],
// "is_persistent": true
// }Token Types: Ephemeral tokens (from generateEmbedToken) expire after 1 hour. Persistent tokens (EmbedToken entity) never expire and can be managed from the admin dashboard. Use ephemeral tokens for session-based embedding and persistent tokens for long-term integrations.
Data Scopes & Permissions
Each embed token is scoped to specific data types. Request only the scopes your integration needs.
| Scope | Description | Access |
|---|---|---|
loans | View loan files, statuses, borrower info, conditions | Loan data within embed |
opportunities | View pipeline opportunities, borrower details, stages | Opportunity data within embed |
notes | Add and view notes on loans/opportunities | Note creation via embed |
documents | View and upload documents to loan files | Document upload via embed |
conditions | View and resolve loan conditions | Condition data within embed |
Sharing Scope (Agent Identity)
Which emails count as an agent. An agent is matched on every identity below — the portal email, a verified extra email, the linked CRM contact email, the CRM contact ID, and a full-name match within the same company for older files.
| Phase | Identities included | Activated by |
|---|---|---|
| individual | Portal email, verified extra email, CRM contact email, CRM contact ID, company-scoped name match | Always on |
| team | All individual identities plus the agent's team / group email | Agent turns on share_with_team |
| office | All individual identities plus the brokerage office email | Agent turns on share_with_office |
| assistant | The assistant's own email, which mirrors the primary agent's full pipeline | Set when the assistant accepts the invitation |
Reading the active phases
// Partner API — every agent payload reports the active scope
const { agent_email, identity_emails, sharing, loans } = await fetch(
'/functions/getAgentLoanData?id=' + agentId,
{ headers: { 'x-api-key': process.env.LC_API_KEY } }
).then(r => r.json());
// sharing = {
// individual: true,
// team: { activated: false, email: null },
// office: { activated: false, email: null },
// assistant_access: false
// }
// identity_emails = every email currently matched to this agent
// Scope your own reporting the same way: filter to identity_emails so a team
// dashboard and a personal dashboard never show two different totals for the
// same transaction.Closed and funded files count. Team and office phases are historical — turning one on pulls in transactions filed under that email going back years. Nobody's files are ever duplicated: a transaction matching several identities is returned once, keyed by its loan record.
AI Agents & MCP Connectivity
Loan Certifier runs persona-based in-app AI agents and exposes its data to external AI clients through a native Model Context Protocol (MCP) server.
Loan Officer Persona
Cielo — our assistant for pipeline follow-ups, document chasing, and call/scenario support.
Assessment Analyst Persona
Underwriting-side agent that analyzes loan documents and data to surface assessment findings.
Support Persona
AI support agent that answers borrower, agent, and partner questions from live app data.
Scenario Co-Pilot Persona
Opportunity scenario agent that drafts and refines loan scenarios with the loan officer.
MCP Endpoint (AI Client Connectivity)
The app exposes a native MCP server so AI clients (Claude, ChatGPT, Cursor, custom agents) can work with loan, opportunity, and contact data directly. The server is OAuth-secured and exposes one tool per entity operation and per in-app agent. When a client connects, the signed-in user approves access on the app's consent page and the assistant always acts as them — never across accounts.
// Resolve the MCP server URL at runtime — one per published domain
const mcpUrl = new URL('/api/mcp', window.location.origin).toString();
// e.g. https://your-app-domain/api/mcpAccess & Isolation: MCP access follows each signed-in user's own app permissions — company/office data isolation and row-level security are enforced by the platform, so an AI client can never read across tenants. Clients refresh their tool list when the app ships changes, which may require re-authorizing the connector.
postMessage API
Communicate between your parent application and the Loan Certifier iframe. Receive events when agents interact with loans, and send commands to navigate within the embed.
<script>
window.addEventListener('message', function(event) {
// Verify origin — replace with your allowed origins
if (event.origin !== 'https://app.loancertifier.com') return;
var data = event.data;
if (!data || data.source !== 'loan-certifier') return;
switch (data.type) {
case 'back_requested':
// User clicked "Back" in the embed — return to your app
window.history.back();
break;
case 'loan_viewed':
console.log('Agent viewed loan:', data.payload.loan_id);
break;
case 'note_added':
console.log('Note added to loan:', data.payload.loan_id);
break;
}
});
// Send commands TO the iframe (e.g. navigate to a specific loan)
function navigateEmbed(view, id) {
var iframe = document.getElementById('loan-certifier-embed');
if (iframe && iframe.contentWindow) {
iframe.contentWindow.postMessage({
source: 'parent-app',
type: 'navigate',
payload: { view: view, id: id }
}, 'https://app.loancertifier.com');
}
}
</script>Security: Always verify event.origin before processing messages. Configure allowed origins on your embed token to restrict which domains can embed the portal.
Getting Started Checklist
Follow these steps to embed the Loan Certifier portal in your platform
Get Your API Key
Contact Loan Certifier support to receive your platform API key. This key authenticates your integration and is used for server-side token generation only — it is not tied to a specific install or user.
Generate Embed Tokens
Call generateEmbedToken with the agent's email. The token is cryptographically tied to that email — when the embed loads, verifyEmbedToken validates both the token AND returns the verified agent identity (dual verification).
Add the Iframe
Drop the iframe snippet into your platform with the token and return_url. The embed renders full-screen with a back button that returns the agent to your app.
Listen for postMessage (Optional)
Add a message listener to receive back_requested, loan_viewed, and note_added events. Use these to sync activity back to your CRM if needed.
Test & Go Live
Test in staging: token refresh logic, the back button behavior, and origin validation. Verify allowed_origins on your token before deploying to production.
Need help integrating? Submit a support ticket or contact your account manager.
All API endpoints use HTTPS. API keys must be kept server-side and never exposed in client-side code.