Skip to content

Documents API

Upload, download, verify, and manage documents. Supports both admin operations and borrower portal uploads.

Base permission: IsViewerOrAbove (read), IsLoanOfficerOrAbove (write)

Endpoints

Method Path Description Permission
GET /documents List documents IsViewerOrAbove
GET /documents/{id} Get document IsViewerOrAbove
POST /documents Upload document (direct) IsLoanOfficerOrAbove
POST /documents/create-upload-link Get presigned upload URL IsLoanOfficerOrAbove
POST /documents/{id}/confirm-upload Confirm upload complete IsLoanOfficerOrAbove
POST /documents/{id}/verify Verify document IsLoanOfficerOrAbove
POST /documents/{id}/reject Reject document IsLoanOfficerOrAbove
DELETE /documents/{id} Archive document IsLoanOfficerOrAbove

Upload Flow

Documents use a three-step upload flow for large files:

POST /api/v1/documents/create-upload-link
{
  "loan_id": "550e8400-e29b-41d4-a716-446655440000",
  "document_type": "income_verification",
  "filename": "w2_2025.pdf",
  "content_type": "application/pdf"
}

Response:

{
  "id": "883b1733-b5ce-74g7-d049-779988773333",
  "upload_url": "https://s3.amazonaws.com/lms-documents/...",
  "expires_at": "2026-01-15T15:30:00Z"
}

Step 2: Upload to Presigned URL

Upload the file directly to the presigned S3 URL (client-side):

curl -X PUT "${upload_url}" \
  -H "Content-Type: application/pdf" \
  --data-binary @w2_2025.pdf

Step 3: Confirm Upload

POST /api/v1/documents/{id}/confirm-upload
{
  "file_size": 245760,
  "sha256_hash": "e3b0c44298fc1c149afbf4c8996fb924..."
}

The server verifies the SHA-256 hash matches the uploaded file.

Direct Upload

For smaller files, use direct upload:

POST /api/v1/documents

Multipart form data with the file and metadata.

Document Verification

Verify Document

Mark a document as verified after review.

POST /api/v1/documents/{id}/verify
{
  "verified_by": "Admin User",
  "notes": "Income verified against tax returns"
}

Reject Document

POST /api/v1/documents/{id}/reject
{
  "reason": "Document is illegible, please re-upload"
}

Document Types

Type Description
income_verification W-2, pay stubs, tax returns
identity_verification Driver's license, passport
bank_statement Bank account statements
title Vehicle or property title
insurance Insurance certificate
appraisal Property appraisal report
closing_document Loan closing documents
tila_disclosure Truth in Lending disclosure
adverse_action_notice Adverse action notice
monthly_statement Monthly loan statement
correspondence General correspondence
other Other document type

Storage Providers

Document storage is backed by the provider pattern:

Provider Use Case
S3 (documents.s3) Production --- presigned URLs, server-side encryption
Local (documents.local) Development --- filesystem storage

Storage keys follow the structure: {tenant_slug}/{loan_id}/{document_type}/{filename}

System-Generated Documents

Some documents are generated automatically:

Document Trigger Template
TILA disclosure Loan approval tila_disclosure.html
Adverse action notice Loan denial adverse_action_notice.html
Monthly statement Monthly schedule monthly_statement.html
1099-C Principal forgiveness >= $600 form_1099c.html
Payoff letter Payoff quote request payoff_letter.html

Generated documents use Jinja2 + WeasyPrint for PDF rendering with locale-aware formatting and language variants.

See Also