Post-Lock Operations
After a loan has been locked, several operations are available through the addLockEvent endpoint. The specific operations depend on the lender company's locking policy — use Get Next Lock Status to see which actions are available at any point.
Endpoint for all operations: POST /rest/v1/lp-ppe-api/price-quote/addLockEvent
Headers for all operations:
| Header | Value |
|---|---|
| Authorization | Bearer {{accessToken}} |
Before any post-lock operation, retrieve the current price quote using GET /rest/v1/lp-ppe-api/los/price-quote/get/{{priceQuoteId}}. The response has the same structure as the Lock With Scenario response. Always use the last element in currentLock.lockEvents to get the current lockEventId.
Request Lock
Submit a lock request. This is typically the first post-lock action after the initial lock with scenario.
How to find the lockStatusId: From Get Next Lock Status, pick the status where lockStatusLogic == "Requested".
Body:
{
"priceQuoteId": "{{priceQuoteId}}",
"lockId": "{{lockId}}",
"lockStatusId": "{{lockRequestStatusId}}",
"lockEventExceptionInfo": null,
"lockEventExtensionInfo": null,
"lockEventRequestInfo": {
"requestOverrideDifferences": {}
},
"scenario": {},
"hasSellSide": false,
"sellSideLine": null,
"lockDateUpdate": null,
"lockEventId": "{{lockEventId}}",
"lockEventComment": "Your comment here",
"timezone": "America/Los_Angeles"
}
| Field | Description |
|---|---|
| priceQuoteId | The price quote id |
| lockId | currentLock.id from Lock With Scenario |
| lockStatusId | The status with lockStatusLogic == "Requested" from Get Next Lock Status |
| lockEventId | currentLock.lockEvents[last].id |
| scenario | currentLock.lockEvents[last].scenario from Lock With Scenario |
| lockEventRequestInfo | Override differences object (empty {} for standard requests) |
| sellSideLine | Sell-side line data (null if not applicable) |
| timezone | IANA timezone string |
| lockEventComment | Optional comment string |
Response:
{
"isAutoLock": false,
"queueItemId": "68d9dfb88118910001154fe9"
}
Approve Lock
Approve a pending lock request.
How to find the lockStatusId: From Get Next Lock Status, pick the status where lockStatusLogic == "Locked".
Body:
{
"priceQuoteId": "{{priceQuoteId}}",
"lockId": "{{lockId}}",
"lockStatusId": "{{lockedStatusId}}",
"userIdToUseWorseCase": null,
"lockEventExceptionInfo": null,
"lockEventExtensionInfo": null,
"lockEventRequestInfo": null,
"scenario": null,
"lockDateUpdate": null,
"hasSellSide": false,
"exportAndLock": false,
"lockEventId": "{{lockEventId}}",
"lockEventComment": "Approved",
"overrideSetting": null,
"userIdForSearch": null,
"worstCaseData": null,
"timezone": "America/Los_Angeles",
"date": null
}
The scenario is null for approval — the scenario from the original lock request is used.
Response:
{
"isAutoLock": false,
"queueItemId": "68d9e0e08118910001156e74"
}
Deny Lock Request
Deny a pending lock request.
How to find the lockStatusId: From Get Next Lock Status, pick the status where lockStatusLogic == "Rejected".
Body:
{
"priceQuoteId": "{{priceQuoteId}}",
"lockId": "{{lockId}}",
"lockStatusId": "{{rejectedStatusId}}",
"userIdToUseWorseCase": null,
"lockEventExceptionInfo": null,
"lockEventExtensionInfo": null,
"lockEventRequestInfo": null,
"scenario": null,
"lockDateUpdate": null,
"hasSellSide": false,
"exportAndLock": false,
"lockEventId": "{{lockEventId}}",
"lockEventComment": "Reason for denial",
"overrideSetting": null,
"userIdForSearch": null,
"worstCaseData": null,
"timezone": "America/Los_Angeles",
"date": null
}
Response:
{
"isAutoLock": false,
"queueItemId": "68d9e38e8118910001162ebc"
}
Extension Request
Request a lock extension before the lock expires.
How to find the lockStatusId: From Get Next Lock Status, pick the status where lockExtender.enable == true and lockExtender.type == "Request".
Body:
{
"priceQuoteId": "{{priceQuoteId}}",
"lockId": "{{lockId}}",
"lockStatusId": "{{extensionStatusId}}",
"lockEventExceptionInfo": null,
"lockEventExtensionInfo": {
"lockExtension": true,
"dayExtension": 15,
"dayExtensionRequested": 15,
"pointExtensionRequested": 0.15,
"pointExtension": 0.15,
"extensionOverrideDifferences": {}
},
"lockEventRequestInfo": null,
"scenario": null,
"hasSellSide": false,
"sellSideLine": null,
"lockDateUpdate": null,
"lockEventId": "{{lockEventId}}",
"lockEventComment": "Requesting 15-day extension",
"timezone": "America/Los_Angeles"
}
| Field | Description |
|---|---|
| dayExtension | Number of days to extend |
| dayExtensionRequested | Must match dayExtension |
| pointExtension | Point cost of the extension |
| pointExtensionRequested | Must match pointExtension |
The scenario is null for extension requests.
Response:
{
"isAutoLock": false,
"queueItemId": "68d9e15dd01acf000185148a"
}
Approve Extension
Approve a pending extension request.
How to find the lockStatusId: From Get Next Lock Status, pick the status where lockExtender.enable == true and lockExtender.type == "Response".
Body:
{
"priceQuoteId": "{{priceQuoteId}}",
"lockId": "{{lockId}}",
"lockStatusId": "{{extensionApproveStatusId}}",
"lockEventExceptionInfo": null,
"lockEventExtensionInfo": {},
"lockEventRequestInfo": null,
"scenario": null,
"hasSellSide": false,
"sellSideLine": null,
"lockDateUpdate": null,
"lockEventId": "{{lockEventId}}",
"lockEventComment": "Extension approved",
"timezone": "America/Los_Angeles"
}
For lockEventExtensionInfo, use the value from the price quote: currentLock.lockEvents[last].lockEventExtensionInfo.
Response:
{
"isAutoLock": true,
"queueItemId": "68d9e1c0d01acf0001852ee9"
}
Request Post-Lock Price Concession
Request a price concession after the loan has been locked.
How to find the lockStatusId: From Get Next Lock Status, pick the status where lockException.enable == true and lockException.requestType == "Request".
Body:
{
"priceQuoteId": "{{priceQuoteId}}",
"lockId": "{{lockId}}",
"lockStatusId": "{{exceptionStatusId}}",
"lockEventExceptionInfo": {
"exceptionValueType": "Points",
"requestType": "Request",
"reason": "Rate Table Lead Source",
"values": {
"FEE": -0.7
},
"exceptionOverrideDifferences": null
},
"lockEventExtensionInfo": null,
"scenario": null,
"hasSellSide": false,
"sellSideLine": null,
"lockDateUpdate": null,
"lockEventId": "{{lockEventId}}",
"lockEventComment": "Price concession request",
"timezone": "America/Los_Angeles"
}
| Field | Description |
|---|---|
| exceptionValueType | "Points" or "Amount" |
| requestType | "Request" for submitting a concession |
| reason | A reason string for the concession |
| values.FEE | The concession value (can be negative or positive) |
The scenario is null for price concession requests.
Response:
{
"isAutoLock": false,
"queueItemId": "68d9dfb88118910001154fe9"
}
Approve Price Concession
Approve a pending price concession request.
How to find the lockStatusId: From Get Next Lock Status, pick the status where lockException.enable == true and lockException.requestType == "Grant".
Body:
{
"priceQuoteId": "{{priceQuoteId}}",
"lockId": "{{lockId}}",
"lockStatusId": "{{exceptionApproveStatusId}}",
"lockEventExceptionInfo": {},
"lockEventExtensionInfo": null,
"scenario": null,
"hasSellSide": false,
"sellSideLine": null,
"lockDateUpdate": null,
"lockEventId": "{{lockEventId}}",
"lockEventComment": "Concession approved",
"timezone": "America/Los_Angeles"
}
For lockEventExceptionInfo, use the value from the price quote: currentLock.lockEvents[last].lockEventExceptionInfo.
Response:
{
"isAutoLock": false,
"queueItemId": "68d9e0e08118910001156e74"
}
Cancel Lock
Cancel an existing lock.
How to find the lockStatusId: From Get Next Lock Status, pick the status where lockStatusLogic == "CanceledOrWithdrawn".
Body:
{
"priceQuoteId": "{{priceQuoteId}}",
"lockId": "{{lockId}}",
"lockStatusId": "{{cancelStatusId}}",
"userIdToUseWorseCase": null,
"lockEventExceptionInfo": null,
"lockEventExtensionInfo": null,
"lockEventRequestInfo": null,
"scenario": null,
"lockDateUpdate": null,
"hasSellSide": false,
"exportAndLock": false,
"lockEventId": "{{lockEventId}}",
"lockEventComment": "Lock cancelled",
"overrideSetting": null,
"userIdForSearch": null,
"worstCaseData": null,
"timezone": "America/Los_Angeles",
"date": null
}
Response:
{
"isAutoLock": false,
"queueItemId": "68d9e246811891000115be67"
}
Quick Reference: Finding lockEventId
For every post-lock operation, you need the current lockEventId. To get it:
- Call
GET /rest/v1/lp-ppe-api/los/price-quote/get/{{priceQuoteId}} - The response contains
currentLock.lockEvents— an array of all lock events - Always use the last element:
currentLock.lockEvents[currentLock.lockEvents.length - 1].id
The priceQuoteId and lockId remain the same throughout the lifecycle of a single loan lock.