Overview
The Loan Setup integration moves documents through a five-stage asynchronous pipeline: upload, classify, extract, validate, and export. Each stage runs automatically after the previous one completes. Your integration uploads one or more PDFs and polls for status. No webhooks are required, though the MOS webhook subscription feature can serve as a near-real-time alternative once enabled for your tenant.
The pipeline stages in order:
- Upload. Source PDFs land in MOS and are queued for the splitter service. Large multi-document bundles are split into individual document segments automatically.
- Classify. Each document segment is run through the AI classifier, which assigns a document type (W-2, pay stub, 1003, closing disclosure, and so on) with a per-document confidence score.
- Extract. Field-level extraction runs on every classified document, producing per-field values and confidence scores.
- Validate. Extracted data is checked against LOS data and cross-document rules. Documents that fall below confidence thresholds are routed to a human review queue.
- Export. Validated documents and extracted data are pushed to the configured Encompass eFolders.
The average time from upload to extracted data is under five minutes. Classification confidence averages 89.3% across all document types; W-2s reach 94.2% average confidence.
Step 1: Upload source files
Use POST /loans/{loanId}/source-files to upload one or more PDFs. The request must be sent as multipart/form-data. Each file becomes a separate sourceFileId in the response, and asynchronous processing begins immediately upon receipt.
curl -X POST https://api.mos.true.ai/v1/loans/{loanId}/source-files \
-H "x-api-key: YOUR_API_KEY" \
-H "x-tyk-mos-client-secret: YOUR_CLIENT_SECRET" \
-H "tenant-id: YOUR_TENANT_ID" \
-F "files=@/path/to/loan-package.pdf"
The response returns immediately with a sourceFileId for each uploaded file. The file is queued for the splitter service the moment the upload completes. You do not need to wait for processing to finish before making the next call. Subsequent uploads to the same loan are processed in parallel.
The API accepts PDFs only. Single-page documents and large multi-page bundles (100+ pages) are both supported. The splitter service handles bundle decomposition automatically.
Step 2: Poll for completion
To track processing progress, poll GET /loans/{loanId}/documents. This endpoint lists all document records produced from your uploaded source files, each with a processingStatus field.
The processingStatus progression is UPLOADING → PROCESSING → CLASSIFIED → EXTRACTED → EXPORTED. A FAILED status indicates a pipeline error; retrieve the individual document record via GET /documents/{documentId} to inspect the error detail before retrying.
curl -X GET https://api.mos.true.ai/v1/loans/{loanId}/documents \
-H "x-api-key: YOUR_API_KEY" \
-H "x-tyk-mos-client-secret: YOUR_CLIENT_SECRET" \
-H "tenant-id: YOUR_TENANT_ID"
Poll at a reasonable interval — ten to fifteen seconds works for most integrations. Continue until all documents have reached EXTRACTED or EXPORTED status, or until your timeout threshold is exceeded.
The endpoint supports cursor-based pagination using cursor and limit query parameters. The response includes a nextCursor field when additional pages are available.
Webhook alternative to polling
MOS is rolling out outbound webhook subscriptions as an event-driven alternative to polling. Once enabled for your tenant, you can register a URL to receive a signed HTTP POST delivery the moment classification or extraction completes for each document.
Two event types are supported for Loan Setup: classification.completed fires when the CLASSIFIER stage finishes; extraction.completed fires when the EXTRACTOR stage finishes. Each delivery is signed with x-mos-webhook-* headers for payload verification. Contact your MOS integration team to enable webhook subscriptions for your tenant.
Once a document reaches EXTRACTED status, call GET /extractedData/documents/{documentId} to retrieve the full set of extracted field values:
curl -X GET https://api.mos.true.ai/v1/extractedData/documents/{documentId} \
-H "x-api-key: YOUR_API_KEY" \
-H "x-tyk-mos-client-secret: YOUR_CLIENT_SECRET" \
-H "tenant-id: YOUR_TENANT_ID"
The response returns an array of field records:
{
"fieldTypeId": "borrower_first_name",
"fieldValue": "Jane",
"fieldConfidence": 0.97,
"manuallyCorrected": false
}
fieldTypeId is the field identifier, consistent across all documents of the same type. fieldConfidence is a float from 0 to 1; values at or above 0.80 are considered high confidence. manuallyCorrected is true if a human reviewer has overridden the extracted value.
Overall extraction confidence averages 85.2% across all field types. Fields below your configured confidence threshold are routed to a review queue automatically.
Step 4: Handle corrections
When a reviewer corrects an extracted value in the MOS portal, the change is written back to the record. To apply corrections programmatically, use PUT /extractedData/documents/{documentId}:
curl -X PUT https://api.mos.true.ai/v1/extractedData/documents/{documentId} \
-H "x-api-key: YOUR_API_KEY" \
-H "x-tyk-mos-client-secret: YOUR_CLIENT_SECRET" \
-H "tenant-id: YOUR_TENANT_ID" \
-H "Content-Type: application/json" \
-d '{
"fields": [
{
"fieldTypeId": "borrower_first_name",
"fieldValue": "Janet",
"manuallyCorrected": true
}
]
}'
Set manuallyCorrected to true on any field you are overriding. This flag distinguishes AI-extracted values from human-corrected ones in the audit trail — a distinction that matters for investor and compliance reporting.
Working with loans and documents
Retrieve a loan record
To fetch the current state of a loan — including status, timestamps, and the external loan ID you provided at creation:
curl -X GET https://api.mos.true.ai/v1/loans/{loanId} \
-H "x-api-key: YOUR_API_KEY" \
-H "x-tyk-mos-client-secret: YOUR_CLIENT_SECRET" \
-H "tenant-id: YOUR_TENANT_ID"
The response includes loanId, externalLoanId, status, createdAt, updatedAt, and summary counters including fieldsCount and fieldsToReview. Use externalLoanId to cross-reference your LOS loan number.
GET /loans/{loanId}/documents returns all document records for a loan, each with processingStatus, documentTypeId, and documentTypeConfidence. The default page size is 10. A loan with many documents will require multiple requests to retrieve all records.
# First page
curl -X GET "https://api.mos.true.ai/v1/loans/{loanId}/documents?limit=100&include=documentType" \
-H "x-api-key: YOUR_API_KEY" \
-H "x-tyk-mos-client-secret: YOUR_CLIENT_SECRET" \
-H "tenant-id: YOUR_TENANT_ID"
# Subsequent pages — use the nextCursor from the previous response
curl -X GET "https://api.mos.true.ai/v1/loans/{loanId}/documents?limit=100&include=documentType&cursor=NEXT_CURSOR_VALUE" \
-H "x-api-key: YOUR_API_KEY" \
-H "x-tyk-mos-client-secret: YOUR_CLIENT_SECRET" \
-H "tenant-id: YOUR_TENANT_ID"
Continue paging until nextCursor is null. A response with only 10 records and a non-null nextCursor means more documents exist — this is pagination behavior, not a data limitation. Set limit=100 and follow nextCursor until exhausted to retrieve the full document set.
The include=documentType parameter embeds the document type name directly on each record, which is useful for filtering and display without a separate lookup.
Retrieve a single document
When you need detail on a specific document — for example, to inspect an error after a FAILED status:
curl -X GET https://api.mos.true.ai/v1/documents/{documentId} \
-H "x-api-key: YOUR_API_KEY" \
-H "x-tyk-mos-client-secret: YOUR_CLIENT_SECRET" \
-H "tenant-id: YOUR_TENANT_ID"
The extracted data endpoint also paginates at 10 records by default. Use limit=100 and follow nextCursor to retrieve all fields:
# First page
curl -X GET "https://api.mos.true.ai/v1/extractedData/documents/{documentId}?limit=100" \
-H "x-api-key: YOUR_API_KEY" \
-H "x-tyk-mos-client-secret: YOUR_CLIENT_SECRET" \
-H "tenant-id: YOUR_TENANT_ID"
# Subsequent pages
curl -X GET "https://api.mos.true.ai/v1/extractedData/documents/{documentId}?limit=100&cursor=NEXT_CURSOR_VALUE" \
-H "x-api-key: YOUR_API_KEY" \
-H "x-tyk-mos-client-secret: YOUR_CLIENT_SECRET" \
-H "tenant-id: YOUR_TENANT_ID"
A document with 400+ extracted fields will require multiple pages at limit=100. Page until nextCursor is null.
Get the flattened loan data view
For loan-level consumption — rather than fetching each document and its fields separately — MOS provides a flattened endpoint that returns all extracted data for a loan in a single dataset:
curl -X GET https://api.mos.true.ai/v1/loans/{loanId}/data \
-H "x-api-key: YOUR_API_KEY" \
-H "x-tyk-mos-client-secret: YOUR_CLIENT_SECRET" \
-H "tenant-id: YOUR_TENANT_ID"
Important distinction: /loans/{loanId}/data is not a raw dump of every extracted row. It returns only fields where FieldTypes.inUse = true, and applies additional filtering for certain scoped external-field rows. The row count will be lower than fieldsCount on the loan record — this is expected. Use this endpoint when you want a curated, ready-to-consume dataset for LOS population or downstream analysis.
Each row in the response includes docTypeName, which you can use to narrow the dataset to the document types your integration cares about:
# Filter to specific document types using jq
curl -sS \
-H "x-api-key: YOUR_API_KEY" \
-H "x-tyk-mos-client-secret: YOUR_CLIENT_SECRET" \
-H "tenant-id: YOUR_TENANT_ID" \
"https://api.mos.true.ai/v1/loans/{loanId}/data" \
| jq '
.data
| map(
select(
.docTypeName == "W-2" or
.docTypeName == "Paystub" or
.docTypeName == "Bank Statement" or
.docTypeName == "Closing Disclosure" or
.docTypeName == "Note" or
.docTypeName == "Security Instrument"
)
)
'
Customizing field names
MOS provides two mechanisms to control how field names appear in API responses.
Display name (simple label change). Update the displayName on a field type to change how it surfaces in flattened responses:
curl -X PUT https://api.mos.true.ai/v1/field-types/{fieldTypeId} \
-H "x-api-key: YOUR_API_KEY" \
-H "x-tyk-mos-client-secret: YOUR_CLIENT_SECRET" \
-H "tenant-id: YOUR_TENANT_ID" \
-H "Content-Type: application/json" \
-d '{"displayName": "YourCustomFieldName"}'
External field mappings (formal mapping layer). For a structured mapping from MOS fields to your system's field identifiers, use external-fields and external-field-mappings. First create the external field:
curl -X POST https://api.mos.true.ai/v1/external-fields \
-H "x-api-key: YOUR_API_KEY" \
-H "x-tyk-mos-client-secret: YOUR_CLIENT_SECRET" \
-H "tenant-id: YOUR_TENANT_ID" \
-H "Content-Type: application/json" \
-d '{
"name": "YourCustomFieldName",
"tableIndex": "CX.CUSTOM.FIELD.ID",
"source": "Encompass"
}'
Then map the MOS field type to it:
curl -X POST https://api.mos.true.ai/v1/external-field-mappings \
-H "x-api-key: YOUR_API_KEY" \
-H "x-tyk-mos-client-secret: YOUR_CLIENT_SECRET" \
-H "tenant-id: YOUR_TENANT_ID" \
-H "Content-Type: application/json" \
-d '{
"fieldId": "<field-type-id>",
"externalFieldId": "<external-field-id>"
}'
Use displayName when you want the JSON label to appear differently in responses. Use external-field-mappings when you need a durable, formal mapping between MOS field identifiers and identifiers in an external system like Encompass.
Monitoring with analytics
For per-loan processing visibility, call GET /tenant/{tenantId}/analytics/loans/{loanId}/timeline. This returns a chronological event log covering every pipeline stage — splitter, converter, recognizer, classifier, extractor, and export — with timestamps for each. Use it to measure exactly how long each stage took for any given loan.
For aggregate metrics across your entire loan volume, use GET /tenant/{tenantId}/analytics/metrics/processing. This returns totals, averages, and completion rates across all processing tasks for your tenant.
Key numbers
| Metric |
Value |
| Upload to extracted data |
Under 5 minutes under normal load |
| Classification confidence |
89.3% average across all document types |
| W-2 classification confidence |
94.2% average |
| Extraction confidence |
85.2% average overall |
| Annual loan volume |
1 million+ loans processed on the TRUE platform |
If a loan's processing time exceeds your expected window, check the timeline endpoint first. The stage-level timestamps will identify exactly where the delay occurred, which determines whether the right response is a retry, a support request, or a manual intervention via the review queue.