Skip to main content

Locking a Loan Without LOS

This guide covers the full lock lifecycle when you are not using a Loan Origination System (LOS) like Encompass. Instead of pulling loan data from an LOS, you create and manage price quotes directly through the API.

Prerequisites

Before integrating, make sure the following are set up for your company:

  1. Pricing -- pricing must be configured for the company (the Lender Price pricing team can help with this).
  2. User Group -- at least one user group must exist in the Workflow tab.
  3. User -- a user assigned to that user group. This user's username and password are used to obtain the JWT token for all API calls.
  4. API Secret -- generated on the company profile.
  5. Lock Policy -- a lock policy created for the company's needs, and the user's group assigned to it. The lock policy drives which statuses and transitions are available.

Locking Policy

The locking policy is the lock schema that is determined by the lender company of the loan. The locking policy is the flow of locking procedures. It determines allowable locking terms, the procedural flow of lock steps, allowable edits to the lock, and other related factors. It is not determined by Lender Price.

Depending on the lender's locking policy, when a user locks a loan, they might lock the loan automatically, or send a lock request that must be approved by the lender before the lock is complete. The Lender Price API allows companies to create their own locking workflow.

Workflow Overview

Lock With Scenario is the step that creates the Lock and its first event (Priced). Its response provides the lockId (currentLock.id) and lockEventId (currentLock.lockEvents[last].id) used by every later call.

Post-lock operations include: Reprice, Extension, Post-Lock Price Concession, Relock (Worst Case), Cancel Lock, Allow Current Market Pricing, and Auto Reprice.

Lock Status Flow

The names above are illustrative -- actual status names are configured per lender. To identify statuses programmatically, use the logic fields in the next section.

Identifying Lock Statuses

Status names (for example "Lock Requested" or "Request Denied (Pre-Lock)") are configured per lender in the lock policy, so they vary from company to company. Do not match on names. Instead, identify each status returned by Get Next Status by its logic fields:

EventIdentify by
Price (root)status.root == true -- the initial event; can repeat (price many times without locking)
Lock requestlockStatusLogic == "Requested" (typically with requireReprice == true)
LockedlockStatusLogic == "Locked"
Denied / rejectedlockStatusLogic == "Rejected"
CancelledlockStatusLogic == "CanceledOrWithdrawn"
ExpiredlockStatusLogic == "Expired" -- created by Lender Price's daily job
Reprice requestlockStatusLogic == "ModificationRequested" and requireReprice == true
Extension requestlockExtender.enable == true and lockExtender.type == "Request"
Extension grantlockExtender.enable == true and lockExtender.type == "Response" -- always auto-status to Locked
Concession requestlockException.enable == true and lockException.requestType == "Request"
Concession grantlockException.enable == true and lockException.requestType == "Grant" -- always auto-status to Locked
Relock (worst case)worseCase == true and requireReprice == true -- available after Cancelled or Expired
Allow current market pricinglockStatusLogic == "None" -- empty event triggered by the lock desk

A status can also be configured with autoStatus == true and autoStatusLockStatusId pointing to a follow-up status (for example, a lock request that locks automatically).

How Values Flow Between Calls

Most integration problems come from passing a stale or wrong ID between calls. This section shows exactly where every value is born and which calls consume it.

ID Reference

ValueWhere it comes fromChanges?Used by
accessToken/oauth/token responseExpires -- refresh as neededEvery call (Authorization: Bearer)
userIdYour user setup (see Prerequisites and Getting Started)NeveruserIdToUse, userIdToUseWorseCase
searchThe search payload you build for Get PricingWhen criteria changeCreate Price Quote, Set Scenario, Lock With Scenario
lineResultGet Pricing response -- the line the user selectsEach selectionSet Scenario, Lock With Scenario, SellSide
priceQuoteIdCreate Price Quote response idNever for a loanAlmost every call
integrationRef.DUMMYCreate Price Quote responseNeverUpdating the same loan via price-quote/create
lockIdLock With Scenario response currentLock.idNever for a loanGet Next Status, desk-hours check, every addLockEvent
lockEventIdcurrentLock.lockEvents[last].idAfter every eventGet Next Status, every addLockEvent
scenariocurrentLock.lockEvents[last].scenario (or Set Scenario)After reprice / relockLock request, reprice, and relock events only
lockStatusIdGet Next Status response -- select by logic fieldsPer actionEvery addLockEvent, both validation checks
exceptionDataIdYou generate it: priceQuoteId + a random stringPer concessionConcession payload, then Edit/Remove Exception
queueItemIdEvery addLockEvent response (except root pricing events)Per event/rest/queue/{queueItemId}

Common Pitfalls

The three mistakes that cause most integration failures
  1. Stale lockEventId -- it changes after every event. Always re-fetch the price quote and take currentLock.lockEvents[last].id immediately before each addLockEvent.
  2. Hardcoded lockStatusId -- status ids belong to your lender's lock policy and can change. Always call Get Next Status and select by lockStatusLogic / lockExtender / lockException fields, never by id or name.
  3. scenario sent where it must be null -- lock request, reprice, and relock events carry a scenario; approve, deny, extension, and concession events must send "scenario": null.

Guide Pages

This workflow is split across the following pages:

  1. Submit a Lock Request -- Create a price quote, set the scenario, create the lock, run validations, and submit the lock request (with or without SellSide).
  2. Approve or Reject a Lock -- Approve a lock, deny a lock request, and lock with a price concession.
  3. Post-Lock Operations -- Reprice, extension requests, relock (worst case), post-lock price concessions, cancel lock, allow current market pricing, edit/remove exceptions, the lock event queue, and auto reprice.

Key Endpoints

All endpoints use the Authorization: Bearer {{accessToken}} header (see Authentication).

OperationEndpointMethod
Get Pricing/rest/v1/lp-ppe-api/pricing/search?userIdToUse={userId}POST
Pricing With Existing Lock/rest/v1/lp-ppe-api/price-quote/{priceQuoteId}/search?userIdToUse={userId}&lockStatusId={nextLockStatusId}POST
Create / Update Price Quote/rest/v1/lp-ppe-api/price-quote/createPOST
Get Price Quote/rest/v1/lp-ppe-api/los/price-quote/get/{priceQuoteId}POST
Set Scenario From Result (unlocked)/rest/v1/lp-ppe-api/price-quote/setScenarioFromResult/EllieMaeQuoteRequestPOST
Set Scenario From Result (locked)/rest/v1/lp-ppe-api/price-quote/setScenarioFromResult/EllieMaeBuyRequestPOST
Lock With Scenario/rest/v1/lp-ppe-api/price-quote/lockWithScenarioPOST
Get Next Actions/rest/v1/lp-ppe-api/price-quote/getNextLockStatus/{lockId}/{lockEventId}GET
Add Lock Event/rest/v1/lp-ppe-api/price-quote/addLockEventPOST
Check Desk Hours/rest/v1/lp-ppe-api/checkLockStatus/{lockId}/{statusId}GET
Check Rate Period/rest/v1/lp-ppe-api/isRatePeriodStillActive/{priceQuoteId}/{statusId}GET
Auto Reprice/rest/v1/lp-ppe-api/price-quote/auto-repricePOST
Edit / Remove Exception/rest/v1/event/fee-change/{priceQuoteId}POST
Check Queue Item/rest/queue/{queueItemId}GET
Queue Items by Loan/rest/v1/integration/ellie/loanLock/ellieQueueDataNotProcessed?priceQuoteId={priceQuoteId}GET
note

Several endpoint URLs contain EllieMae or ellie for historical reasons. They do not involve EllieMae in the no-LOS flow.

Authentication

Endpoints use the Authorization: Bearer {{accessToken}} header for authentication. See Submit a Lock Request for how to obtain the token.