LendEasy/DocsLMS + Servicing·v1
Start integrating
Guides›Servicing Workspace›Account Actions

Governed operations & action requests

Every action runs in the system that owns it, an approval is opened only when one is genuinely needed,

Every account change a case needs — take a payment, apply a hold, change a schedule, send a letter — runs on the system that owns it and comes back either done, or as an approval request naming who has to decide. An action request exists only where the change could not simply proceed, so its presence is a signal that something is genuinely blocked. A gateway that manufactured one for every change would make that signal worthless, which is why this one does not. The owning operation resolves current facts and policy first: an ALLOWED operation executes immediately, and a request is opened only for APPROVAL_REQUIRED, deferred, manual, external, or unavailable work.

A requested changeon its own resourceThe owning operationresolves current factsand policy, right nowALLOWEDIt simply happens.No action request is created, because nothing is blocked.anything elseAn action request is openedAPPROVAL_REQUIRED · deferred · manualexternal · unavailableIt carries the change until somebody settles it.Why the fork mattersA gateway that created a request for every change wouldproduce a queue full of records that mean nothing. Here, arequest on the list is always something genuinely stuck.
Only the right-hand branch creates a record, the existence of an action request is itself information: something about this change could not simply happen.

Where each change runs

Work Current path Authority
Servicing-owned change The resource’s own endpoint, such as POST /v1/servicing/cases/{caseId}/promises or /restriction-changes. The endpoint’s named permission plus its execution-time policy result.
Direct servicing outcome /responses, /follow-up-tasks, and /payment-support-reviews. Executes directly after current-fact checks; it does not fabricate an action request.
Lending Core command The customer or loan route under /v1, with LendEasy-Case on a human servicing call. The command’s exact LMS permission. The case supplies causation and scope, never authority.
Workflow automation A registered case effect. The workflow and effect type are closed contracts; callers cannot submit an arbitrary command, URL, or payload.

The governed operations

Eight case-scoped operations cover the borrower-facing and account-changing work the servicing workspace owns. Each is its own resource under its case, each requires its own permission, and each decides for itself whether to execute or open a request:

Operation Route on /v1/servicing/cases/{caseId} Permission
Prepare a customer-authorized payment POST /payment-requests CREATE_SERVICING_PAYMENT_REQUEST
Record an external payment POST /external-payments RECORD_SERVICING_EXTERNAL_PAYMENT
Update contact or consent POST /contact-consent-updates UPDATE_SERVICING_CONTACT_CONSENT
Apply or clear a restriction POST /restriction-changes CHANGE_SERVICING_RESTRICTION
Update a bankruptcy record POST /bankruptcy-updates UPDATE_SERVICING_BANKRUPTCY
Send or log a case response POST /responses SEND_SERVICING_RESPONSE
Create internal follow-up work POST /follow-up-tasks CREATE_SERVICING_FOLLOW_UP_TASK
Create payment-support review work POST /payment-support-reviews REQUEST_SERVICING_PAYMENT_SUPPORT_REVIEW

Every one of them requires a reason. The three that change authoritative state on the strength of evidence — external payments, restriction changes, and bankruptcy updates — also require evidenceIds, so a protective control can never rest on an assertion alone.

curl -X POST "$BASE/v1/servicing/cases/1001/restriction-changes" \
  -H "Authorization: Bearer $TOKEN" \
  -H "LendEasy-Tenant: demo-lender" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: cease-1001-2027-05-05" \
  -d '{
    "customerRef": "412",
    "loanRef": "7204",
    "operation": "APPLY",
    "restrictionType": "CEASE_COMMUNICATIONS",
    "effectiveAt": "2027-05-05T18:30:00Z",
    "reason": "Verified written cease request.",
    "evidenceIds": [8801]
  }'

The response is an outcome, not a request receipt:

{
  "outcome": "COMPLETED",
  "restrictionRef": "restriction-41",
  "resourceId": 41
}

Branch on outcome. COMPLETED means the operation already executed against the system that owns it and the returned reference is real. Where policy instead requires approval, or execution is deferred, manual, external, or unavailable, the same call reports that and returns the action request it opened — which is the only way an action request comes into existence.

Two of these are worth calling out because they look like approvals and are not. /responses, /follow-up-tasks, and /payment-support-reviews create the owning interaction or task directly after current-fact checks. A payment-support review is specialist work, not a request for someone to authorize something.

Applying a protective restriction and relaxing one follow separate action-specific policy. operation: APPLY on a cease request is not the mirror image of clearing it, and the two do not share an approval threshold.

Action-request lifecycle

When an owning operation does open a request, the implemented API exposes the case-scoped lifecycle:

Route Purpose Permission
GET /v1/servicing/cases/{caseId}/action-requests List only the requests actually opened on this case. READ_SERVICING_CASE
GET /v1/servicing/action-requests/{actionRequestId} Read the request and its safe lifecycle state. READ_SERVICING_ACTION_REQUEST
POST .../{actionRequestId}/approve Approve with a required decisionNote. APPROVE_SERVICING_ACTION_REQUEST
POST .../{actionRequestId}/reject Reject with a required reason. REJECT_SERVICING_ACTION_REQUEST
POST .../{actionRequestId}/submit Execute the approved inputs. Accepts no request body. SUBMIT_SERVICING_ACTION_REQUEST
POST .../{actionRequestId}/manual-complete Record a manual result, only from MANUAL_EXECUTION_REQUIRED. MANUAL_COMPLETE_SERVICING_ACTION_REQUEST

Both reads return allowedActions computed for the calling actor:

{
  "actionRequestId": 6001,
  "externalActionRef": "LE-ACTION-6001",
  "caseId": 1001,
  "actionType": "AR_002",
  "riskClass": "R2",
  "status": "APPROVAL_REQUIRED",
  "preparedByActorType": "HUMAN",
  "preparedByWorkerId": 4101,
  "approvalRequired": true,
  "approvalPermissionCode": "APPROVE_SERVICING_PROMISE",
  "allowedActions": ["APPROVE", "REJECT"],
  "requestPayload": { "loanRef": "7204", "planType": "SINGLE", "promiseDate": "2026-08-01" }
}

A workspace should render buttons from allowedActions rather than inferring them from status. The list already accounts for the caller’s permissions and for maker-not-approver, so the maker who prepared request 6001 sees an empty approval set on their own request.

Approving checks two authorities, not one: the route permission above and the server-derived action-specific permission named in approvalPermissionCode — APPROVE_SERVICING_<ACTION>. The caller cannot choose riskClass, approvalPermissionCode, or a generic approval role; all three are derived from the action type. Submit takes no body precisely so that approved inputs stay immutable between approval and execution.

Manual completion is evidence-backed and reachable only from MANUAL_EXECUTION_REQUIRED. outcomeCode, reason, and evidenceIds are all required, with an optional externalResultRef naming the authoritative record outside the platform:

{
  "outcomeCode": "COMPLETED_EXTERNALLY",
  "reason": "The external system completed the change.",
  "evidenceIds": [8801],
  "externalResultRef": "external-result-71"
}

Named actions, not raw commands

Every request has an actionType from the published catalog and a schema specific to that type. Callers cannot submit arbitrary command names, URLs, or unvalidated payloads.

The catalog includes payments, autopay changes, external-payment records, contact-consent updates, restrictions, re-aging, re-amortization, rescheduling, interest treatment, charges, refunds, recovery payments, write-off, charge-off, fraud flags, SCRA adjustments, contract termination, and closure. See Servicing actions.

Decide, then prepare

There is no preview endpoint on the built-in Lending Core and no preview token. For a schedule-changing or balance-changing action, decide from authoritative reads—GET /v1/loans/{loanId}?associations=repaymentSchedule,transactions and GET /v1/loans/{loanId}/summary—and attach the before/after comparison the decision rests on to the case. Preparation freezes the request and its context:

{
  "actionType": "re_amortize",
  "loanRef": "7204",
  "parameters": {
    "interestHandling": "default"
  },
  "context": {
    "caseId": "case_CEDAR_HARDSHIP_4",
    "reasonCode": "temporary_income_reduction"
  }
}

Approval binds to the hash of that frozen request. If material facts change before submission, the execution-time gate fails the request closed and the decision must be remade from fresh reads.

Every change names the matter it serves

Every state-changing action links to one of:

  • a case it serves;
  • a controlled administrative exception with approver and expiry; or
  • a named system trigger with policy version.

The context is not a free-form note. It carries structured reason, origin, source interaction or task, evidence references, and actor. This makes the chain traversable from ledger transaction back to decision.

Approval from yesterday is not permission today

Immediately before submission, the gateway re-reads critical facts and reruns policy. Approval from yesterday does not override a bankruptcy restriction received today. Possible outcomes are:

Decision Meaning
ALLOWED Execute under the resolved policy.
ALLOWED_WITH_WARNING Execute and preserve named warnings.
APPROVAL_REQUIRED Stop until the required role approves the frozen action.
BLOCKED A known rule prohibits the action.
UNAVAILABLE_DUE_TO_MISSING_FACTS Required facts are absent or stale; fail closed.

The result stores rule IDs, jurisdictions, effective versions, facts and freshness, and any override—not merely a boolean.

Approval and separation of duties

Approval policy can consider action type, amount, balance effect, customer vulnerability, source worker, and tenant thresholds. Maker and checker must be distinct where dual control applies. A checker sees the same before/after comparison, evidence, warnings, and action hash that execution will use.

An AI agent executes the actions its registration grants and its autonomy level allows, and prepares the rest for the person policy reserves them to. It cannot supply that approval, raise its own autonomy level, or alter an action after it is approved.

Idempotent submission and acknowledgement

The gateway derives a stable execution key from tenant, action request, and attempt. The system of record must return the same acknowledgement for a retry.

For the built-in Lending Core, execution is in process rather than a call to a generic actions API: an executor resolves the loan’s facts and capabilities, applies the governed native command—case context attached, maker-checker parking respected—and records the case effects and governance record. A bring-your-own-core binding submits the same action over its documented HTTP contract.

{
  "actionRequestId": "act_CEDAR_RA_81",
  "status": "completed",
  "result": {
    "coreCommand": "reAmortize",
    "resourceId": 7204,
    "governanceId": 903,
    "effectiveDate": "2027-08-20"
  },
  "requestedHash": "sha256:2a7f…12ce",
  "appliedHash": "sha256:2a7f…12ce"
}

Normalized execution results are COMPLETED, PENDING_EXTERNAL, REJECTED, MANUAL_REQUIRED, FAILED, and CAPABILITY_UNAVAILABLE. Provider-native detail remains available in restricted evidence.

It never labels the requested value as applied

If the applied amount, date, treatment, or resulting state differs from the approved request, the gateway records both, marks FAILED_ACTION_REVIEW, and opens reconciliation work. It never labels the requested value as applied.

For a MANUAL_REQUIRED binding, an approved specialist records the authoritative reference and applied facts. Manual completion passes the same reconciliation checks; it is not a free-form “done” button.

Undo is a compensating action

Supported undo operations—dedicated commands such as undowriteoff, undo-charge-off, undoReAge, undoReAmortize, and undoContractTermination on the built-in core—create a new action linked to the original. They verify that the target is still reversible and that no later dependent transaction makes undo unsafe. The original action, approval, and evidence remain immutable.

Unified search across guides, recipes & the API referenceEsc