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.

Installation Guide

Start Here

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.

markdown
# 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

Copy & Paste

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

html
<!-- 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.

html
<!-- 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.

ParameterRequiredDescription
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

REST API

Generate secure, time-limited embed tokens for agent authentication. Server-side only — your API key must never be exposed to the browser.

bash
# 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)

javascript
// 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.

ScopeDescriptionAccess
loansView loan files, statuses, borrower info, conditionsLoan data within embed
opportunitiesView pipeline opportunities, borrower details, stagesOpportunity data within embed
notesAdd and view notes on loans/opportunitiesNote creation via embed
documentsView and upload documents to loan filesDocument upload via embed
conditionsView and resolve loan conditionsCondition 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.

PhaseIdentities includedActivated by
individualPortal email, verified extra email, CRM contact email, CRM contact ID, company-scoped name matchAlways on
teamAll individual identities plus the agent's team / group emailAgent turns on share_with_team
officeAll individual identities plus the brokerage office emailAgent turns on share_with_office
assistantThe assistant's own email, which mirrors the primary agent's full pipelineSet when the assistant accepts the invitation

Reading the active phases

javascript
// 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

New

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.

javascript
// 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/mcp

Access & 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

Two-Way

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.

html
<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

1

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.

2

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).

3

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.

4

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.

5

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.