LendEasy/DocsLMS + Servicing·v1
Start integrating
GuidesServicing PlaneDocuments & secure upload

Documents & secure upload

Register expected evidence, upload bytes through a short-lived controlled target, scan and classify before use, review with structured outcomes, and retain integrity and access history.

Document metadata and document bytes cross different boundaries. The API first registers type, file metadata, expected hash, and case; it then returns a short-lived upload target. Files are unavailable to workers and AI until security processing completes.

Lifecycle

Register metadata

The implemented API accepts metadata and bytes together as controlled multipart intake at POST /v1/servicing/cases/{caseId}/documents. It returns the numeric documentId, scan/review state, and any review task; content is unavailable until the security and review gates permit it.

curl -X POST "$BASE/v1/servicing/cases/1001/documents" \
  -H "Authorization: Bearer $TOKEN" \
  -H "LendEasy-Tenant: demo-lender" \
  -H "Idempotency-Key: bankruptcy-notice-7781" \
  -F 'metadata={
    "title": "Bankruptcy notice filed June 14",
    "documentType": "BANKRUPTCY_NOTICE",
    "origin": "BORROWER_UPLOAD",
    "sensitive": true,
    "loanRefs": ["456"]
  };type=application/json' \
  -F "file=@bankruptcy-notice.pdf;type=application/pdf"

Pre-registration variant (roadmap)

The two-step metadata-registration and short-lived upload-target contract below is retained as product direction:

curl -X POST "$BASE/v1/servicing/cases/case_CEDAR_HARDSHIP_4/documents" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: cedar-pay-statement-april" \
  -d '{
    "type": "income_evidence",
    "fileName": "pay-statement-april.pdf",
    "mediaType": "application/pdf",
    "byteLength": 184220,
    "sha256": "sha256:2d8c…188a"
  }'

The response returns documentId and a short-lived upload method/expiry. It does not expose an internal storage path.

Security processing

Controls validate declared size, actual bytes, digest, media type, file structure, malware, encryption policy, and archive contents. A clean scan means the file passed those controls; it does not mean its claims are true.

Structured review

POST /v1/servicing/documents/{documentId}/review records accepted, rejected, or approved reclassification plus reviewer and note. Accepted evidence can support a case decision; rejected evidence remains in history with restricted access and retention policy.

Discovery beyond the case

A document is registered on a case, but evidence is usually looked for by the customer or loan it concerns. Three reads cover that, and their scopes differ deliberately:

Route Returns
GET /v1/servicing/cases/{caseId}/documents Everything registered on one matter, at any lifecycle state.
GET /v1/servicing/customers/{customerRef}/documents Accepted servicing documents across the customer’s visible cases.
GET /v1/servicing/loans/{loanRef}/documents Accepted documents explicitly linked to that loan.

The two cross-case reads return accepted documents only. A quarantined, rejected, or still-scanning file does not leak into a customer- or loan-level view — it stays visible on its own case, where the reviewer who owns it can see why. All three accept the same filters: documentType, origin, sensitive, and a creation window, with limit/offset paging.

A document reaches a loan only through an explicit link, so a customer-level filing does not silently attach itself to every loan on the account. Reviewers correct those links atomically:

PUT /v1/servicing/documents/7001/loan-links

{
  "loanRefs": ["456", "457"],
  "reason": "Reviewer confirmed both loans are covered by the filing."
}

The supplied list becomes the complete set of loan links; the required case and customer links and the historical retention scope are untouched. PUT /v1/servicing/documents/{documentId} separately corrects approved metadata such as an intake title, and explicitly cannot change content, origin, checksum, review evidence, or links. Both commands require a reason, and neither replaces the bytes or re-runs the security gate — the file that was scanned is the file that stays.

POST /v1/servicing/documents/{documentId}/archive retires a document under retention and hold rules while preserving its audit identity, links, and scan history.

Provenance classes

Source Key evidence
Customer upload Authenticated/verified upload session, request, time, and hash.
Worker upload Actor, case, reason, source, and hash.
Provider document Provider reference, signature/transport verification, and normalized type.
System-generated Template version, fact snapshot, render hash, and generator time.

Access and download

The implemented GET /v1/servicing/documents/{documentId}/content evaluates current permission and returns a no-store, short-lived content envelope plus checksum; every sensitive access is audited:

{
  "downloadUrl": "https://content.example/opaque-signed-token",
  "expiresAt": "2027-05-05T18:35:00Z",
  "fileName": "bankruptcy-notice.pdf",
  "contentType": "application/pdf",
  "checksumSha256": "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"
}

The envelope is issued only for scan-clean, authorized content. downloadUrl is opaque and short-lived — do not persist it as a document reference or hand it to another actor; re-request it and take the audit entry. Verify checksumSha256 against the bytes you receive. The /download variant remains in the API reference as a roadmap contract. AI packets receive only explicitly permitted document content or extraction, never an ambient case-folder mount.

Retention

Retention policy considers document class, legal entity, case state, disputes, investigations, and legal hold. Disposal is an auditable lifecycle event. A hold blocks scheduled disposal; closing the case does not automatically delete evidence.

Do not make ordinary email attachments your trusted intake path. Preserve the inbound signal, then move required evidence through a case-scoped controlled upload and review journey.
Unified search across guides, recipes & the API referenceEsc