Documents
Upload customer and loan documents in one multipart request, gate downloads behind a malware scan and checksum verification, and manage links, sensitivity, and archival without ever losing history.
A document is stored evidence—a pay statement, an identity card, a signed agreement—owned by the Lending Core and linked to the customers and loans it supports. Metadata and bytes travel together in one request, and nothing is downloadable until the content has been scanned.
Upload in one request
POST /v1/documents (CREATE_LMS_DOCUMENT) is a single multipart request with two parts: a JSON metadata part and the file part. At least one CUSTOMER or LOAN link is required at upload—an unlinked document cannot exist. The server derives the checksum and content type from the bytes; caller-asserted values cannot disagree with the file.
curl -X POST "$BASE/v1/documents" \
-H "Authorization: Bearer $TOKEN" \
-H "LendEasy-Tenant: demo-lender" \
-H "Idempotency-Key: harbor-pay-statement-april" \
-F 'metadata={"title":"Pay statement — April","documentType":"INCOME_EVIDENCE","sensitive":false,"links":[{"targetType":"LOAN","targetRef":"7204"}]};type=application/json' \
-F 'file=@pay-statement-april.pdf;type=application/pdf'
{ "resourceId": 1204 }
documentType is an UPPER_SNAKE classification code. The optional sensitive flag restricts reads to callers holding the additional sensitive read permission—and setting it requires that same permission, so a caller cannot restrict content they could not themselves read. An optional supersedesDocumentId records that this upload replaces an earlier document, because content is immutable: a corrected file is always a new document.
Scan gate
Read and download
GET /v1/documents/{documentId} (READ_LMS_DOCUMENT) returns metadata, scan status, checksum, and active links; sensitive documents additionally require the sensitive read permission.
{
"documentId": 1204,
"documentRef": "doc_4f2a9c1b8d3e5a7c9b1d",
"documentType": "INCOME_EVIDENCE",
"title": "Pay statement — April",
"origin": "STAFF_UPLOAD",
"originalFileName": "pay-statement-april.pdf",
"contentType": "application/pdf",
"contentLength": 184220,
"checksumSha256": "2d8c1f0e5b7a4c6d8e0f2a4b6c8d0e1f3a5b7c9d1e3f5a7b9c1d3e5f7a9b188a",
"scanStatus": "CLEAN",
"status": "ACTIVE",
"sensitive": false,
"createdAt": "2027-05-01T10:40:00Z",
"links": [{ "linkId": 61, "targetType": "LOAN", "targetRef": "7204", "active": true }]
}
GET /v1/documents/{documentId}/content streams the original bytes as an attachment after re-verifying the stored checksum, so silent corruption is detected at read time rather than delivered. The response is never cached.
GET /v1/customers/{customerId}/documents and GET /v1/loans/{loanId}/documents list documents actively linked to that target, newest first. The loan listing includes system-generated documents: every completed statement is also a loan-linked document, so the statement PDF a borrower received is discoverable alongside uploaded evidence. See Statements.
Metadata, links, and archive
PUT /v1/documents/{documentId}(UPDATE_LMS_DOCUMENT) updatestitle,description, or thesensitiveflag and returns the command envelope with the changed fields. Content, origin, and checksum are immutable.POST /v1/documents/{documentId}/linksadds a link to another customer or loan ({ "targetType": "CUSTOMER", "targetRef": "412" });POST /v1/documents/{documentId}/links/{linkId}/removedeactivates one link with an optionalreasonCode, retaining the link row and its removal.POST /v1/documents/{documentId}/archive(ARCHIVE_LMS_DOCUMENT) takes no body and is idempotent; content and history are retained. A document’sstatusisACTIVE,ARCHIVED, or—once retention policy disposes of it—DISPOSED.GET /v1/documents/{documentId}/historyreturns the document’s change events—creation, metadata updates, link changes, archive—newest first. Document activity also appears in the linked customer’s ledger under theDOCUMENTcategory; see Customer lifecycle.
Not the servicing upload flow
These routes are the Lending Core’s document store. Servicing cases have their own evidence pipeline under /v1/servicing/...—registration, short-lived upload targets, structured review, and retention holds—documented in Documents & secure upload. Case evidence lives there; borrower and loan records live here.
sensitive flag for restricted evidence and keep secrets out of documents entirely.