MortgageGuidelines API

Embedded Chat Launches

Provision partner users and create secure, WordPress-authenticated chatbot launches.

Embedded chat launches

Call the embedded-chat APIs only from your trusted backend. Use one server-only key with the user-management scopes needed by your integration and a separate server-only key with only embed:launch for launches. Neither key may appear in a WordPress plugin, browser code, desktop-client configuration, or an embed URL.

MortgageGuidelines assigns a public integration name during onboarding. Use that exact authorized name anywhere the API path or body contains integration; a descriptive placeholder is not accepted. MG may explicitly configure an alias for another LOS entry point into the same canonical partner identity. The examples below store the approved public name in INTEGRATION_ID.

Integration slugs contain 3–64 lowercase ASCII letters/digits, start with a letter, and may use single hyphen or underscore separators. A valid-looking slug does not grant access: MG must configure an active integration matching the key's organization and linked client. Unknown, disabled, and mismatched integrations are rejected; requests never create configuration.

The shared browser flow uses canonical partner configuration for WordPress authentication, sessions, entitlements, chat and history. A public alias does not create another WordPress account, organization, client or conversation namespace. Both an active alias and exact credential authorization are required; valid syntax alone cannot grant access. New launch authorizations and provisioning alias grants are disabled by default. Availability in a deployed environment and actual host compatibility require separate verification; an API response alone proves neither.

Public names, canonical identity and source

Use a separate server-only launch credential for each approved source. Each launch key authorizes its configured public name only; it cannot select another name to change attribution. Existing keys are not silently expanded. A provisioning credential can manage users through additional public aliases only after an explicit MG grant, using its existing user/team/lifecycle scopes. It never needs launch scope or a launch binding.

MG snapshots the authorized public name and LOS/source when issuing a launch. Each subsequent message, usage event and feedback action is attributed from the current authorized session, even if that conversation began through another source. Do not send a source, los_source, losSource, canonical integration, or similar override in launch bodies or metadata. Historical records with no trusted source remain unattributed. Attribution identifies the credential/source used; it does not authenticate the actual embedding application.

Use the same immutable external employee ID and WordPress account across a partner's LOS systems. Assign distinct opaque IDs to different loans, even when their native LOS numbers match. Reuse an opaque ID only for an intentionally mapped, identical authorized loan. There is no automatic history merge or per-LOS history silo; user, team, generation, entitlement, experience and loan boundaries still apply.

Provision the user first

Every opaque external user ID must be linked to an active WordPress identity before launch. Provisioning creates or links the WordPress user and creates the internal chat identity. For partner-created accounts, the normal WordPress password-setup notification is sent only after provisioning has completed successfully.

API_BASE_URL="https://api.mortgageguidelines.com"
INTEGRATION_ID="<assigned-integration-id>"
EXTERNAL_USER_ID="employee-6d55c95f"

curl -X PUT \
  "$API_BASE_URL/v1/integrations/$INTEGRATION_ID/users/$EXTERNAL_USER_ID" \
  -H "Authorization: Bearer mgapi_live_provisioning_key" \
  -H "Content-Type: application/json" \
  -d '{"email":"employee@example.com","name":"Taylor Morgan"}'

Use PATCH /v1/integrations/{integration}/users/{external_user_id} with {"status":"disabled"} to revoke grants and chat access immediately. Bulk provisioning is available through POST /v1/integrations/{integration}/user-imports; imports contain at most 1,000 unique users, require Idempotency-Key, and expose status through GET /v1/integrations/{integration}/user-imports/{job_id}.

See Partner User Lifecycle for profile changes, permanent account deletion, operation polling, and reprovisioning.

Create the launch

After provisioning, call POST /v1/embed-sessions from the trusted partner backend.

curl -X POST "$API_BASE_URL/v1/embed-sessions" \
  -H "Authorization: Bearer mgapi_live_launch_key" \
  -H "Idempotency-Key: launch-$EXTERNAL_USER_ID-001" \
  -H "Content-Type: application/json" \
  --data @- <<JSON
  {
    "integration": "$INTEGRATION_ID",
    "user": {
      "external_user_id": "$EXTERNAL_USER_ID"
    },
    "loan_context": {
      "external_loan_id": "loan-7f4a2d18",
      "program": "fha",
      "purpose": "purchase",
      "property_state": "TX"
    }
  }
JSON

Omit parent_origin and host_policy for every partner. They are unsupported fields, rejected even when empty or null. Launch access comes from an active server-owned per-key integration binding, never from a caller's choice of fields. New bindings are disabled by default. Provisioning keys do not need embed:launch or a launch binding.

Launch behavior

Use the returned URL unchanged; the canonical partner determines its route. A public alias must not be substituted into the URL.

  • The launch URL contains a single-use code in its URL fragment.
  • The code expires after two minutes.
  • Consuming the code creates a ten-minute authentication-only session.
  • When authentication is required, the iframe opens the configured WordPress login in a popup and polls MortgageGuidelines for completion.
  • Successful WordPress authentication creates an absolute 24-hour server-side grant. A same-day relaunch is authorized without another prompt.
  • The loan-scoped chat token expires at the earlier of eight hours or the daily grant expiry and is never refreshed.
  • The existing browser flow can resume its server-bound experience on refresh. If resume is unavailable or rejected, request a fresh launch from the partner backend; never replay a consumed launch fragment.
  • Every conversation is scoped to the authenticated organization, partner user, integration, account generation, and opaque loan ID.
  • Reuse an Idempotency-Key only when retrying the identical launch request, including its public integration name. Changing the name changes the request. Authorized retries keep the original target, code and expiry; they do not renew expiry or undo consumption.
  • Clerk is not used by this partner embed flow.

Allowed context

The strict loan_context schema accepts an opaque loan ID and approved categorical fields for program, purpose, occupancy, property type, state, units, milestone, and application date.

Do not send borrower identity, property address, income, assets, credit data, loan ratios, documents, free-form notes, a lender- or system-issued loan number, or other borrower PII. Unknown properties are rejected.

Email-shaped user/loan identifiers are rejected. An opaque-ID syntax validator cannot prove that a value was not derived from a real loan number; the partner must generate and govern this mapping without transmitting raw LOS identifiers.

Host compatibility and security

V1 has one no-parent-origin launch approach. Existing integrations retain their routes; other configured canonical partners receive the exact /embed/partner/<canonical-integration> target. Multiple approved public names can share the same canonical target. No per-LOS adapter or framing-origin registration is required. MG configures authorization without exposing a host-policy choice to callers.

This approach does not verify the embedding host through a stable parent origin. Server-only API keys, WordPress login, one-time codes and entitlement checks do not provide equivalent framing/clickjacking protection. Popup, storage, cookie and messaging behavior must be tested in each actual host before production; desktop/webview and MeridianLink compatibility is not assumed. Unrelated app, admin, callback, CORS and origin protections remain in place.

The unused origin-bound launch authority is retired, not converted: even an accidentally active historical binding cannot issue or replay launches, and old codes/tokens cannot authorize browser use. The retired origin-bound browser route returns 410 Gone, never a redirect. Removing parent_origin from an old request does not rehabilitate its key. Request separately approved new authorization if needed; do not repurpose a historical key.