Overview
This procedure shows how to upload source files, monitor processing, and get extracted data for an existing MOS loan. Make corrections or read loan-level data as necessary.
MOS returns the upload response before it completes source processing. One source file can produce multiple documents. Source-file completion covers processing through extraction. Human review and export to your loan origination system (LOS) have separate results.
Before you start
These items are necessary:
- An existing MOS loan ID and tenant ID.
- Your approved portal application’s API key and MOS service-account client secret.
- The API base URL for your environment, from the developer portal.
- Permission to read the loan and, for corrections, update its extracted data.
- An active, tested webhook subscription for source-file outcomes.
-
Configure your subscription with Monitor loan processing with webhook subscriptions.
-
Set these variables for the requests in this article:
export MOS_BASE_URL='YOUR_API_BASE_URL'
export MOS_API_KEY='YOUR_API_KEY'
export MOS_CLIENT_SECRET='YOUR_CLIENT_SECRET'
export MOS_TENANT_ID='ujftdnvq6r8057p3i5g59tr3'
export MOS_LOAN_ID='tj0p8bzq0xqxwfbxxxx90je7'
MOS_BASE_URL is the full API base URL without a slash at the end. Keep its gateway prefix, such as /pm2m/api/v1.
All record IDs in this article are examples in the MOS ID format. Use IDs from your environment in your requests. Keep credentials in secure storage.
Step 1: Upload source files
-
Use your file path in place of /path/to/loan-package.pdf.
-
Upload the source file with the multipart field files:
curl --fail-with-body --request POST \
"$MOS_BASE_URL/loans/$MOS_LOAN_ID/source-files" \
--header "x-api-key: $MOS_API_KEY" \
--header "x-tyk-mos-client-secret: $MOS_CLIENT_SECRET" \
--header "tenant-id: $MOS_TENANT_ID" \
--form 'files=@/path/to/loan-package.pdf'
For each additional file, add another --form 'files=@/path/to/another-file.pdf' to the request.
MOS accepts PDF, JPEG, and PNG source files. MOS converts supported images to PDF before processing.
MOS returns HTTP 201 with a source-file ID for each uploaded file:
{
"message": "Source files uploaded successfully",
"results": [
{
"sourceFileId": "tdmrh68nhy50pn5p6e1jhpoc",
"fileName": "loan-package.pdf",
"message": "Uploaded successfully"
}
]
}
- Record each
results[].sourceFileId with the loan ID for this upload batch.
The upload response shows that MOS accepted the files. Processing continues after this response.
Step 2: Monitor processing with webhooks
Your subscription receives these source-file outcomes:
| Event type |
Meaning |
source_file.processing.completed |
Processing through extraction succeeded for the source revision. |
source_file.processing.failed |
Processing failed. |
source_file.processing.skipped |
Extraction was not necessary. completion.reason gives the cause. |
- Use the webhook monitoring procedure to process each event.
- Match its
loanId and sourceFileId to your upload records.
- For each document with
state: "SUCCEEDED", use its documentId in Step 3: Get extracted data.
The monitoring guide explains duplicate events, revisions, document manifests, missing events, and delivery failures. Its diagrams show the request sequence and outcome decisions.
Document lists and legacy processingStatus values do not prove source-file completion. Classification and extraction events describe individual documents. They do not identify completion of an upload batch or loan.
-
Set the document ID from a successful source-file outcome:
export MOS_DOCUMENT_ID='uqg9nr6ahoe9hfz61s2v8sov'
-
Get its extracted fields:
curl --fail-with-body \
"$MOS_BASE_URL/extractedData/documents/$MOS_DOCUMENT_ID?limit=100" \
--header "x-api-key: $MOS_API_KEY" \
--header "x-tyk-mos-client-secret: $MOS_CLIENT_SECRET" \
--header "tenant-id: $MOS_TENANT_ID"
The response contains an extractedData array and nextCursor. This excerpt shows selected properties of one field record:
{
"id": "kjg304q7baxcoctei30k4ck3",
"fieldTypeId": "vd346r0rh18538ppdogp3k5s",
"fieldValue": "Jane",
"fieldConfidence": 97,
"manuallyCorrected": false
}
id identifies this extracted field record. fieldTypeId identifies its field definition. Use these IDs from the response for corrections.
fieldConfidence is the extraction confidence value. MOS uses your field and document settings for review thresholds. Confidence alone does not show review approval.
- Get all pages with the extracted-field pagination procedure.
The endpoint returns current data. Subsequent corrections or reprocessing can change the values after a webhook event.
Step 4: Make corrections
-
Get the field records with Step 3: Get extracted data.
-
Send a JSON array of corrections to PUT /extractedData/documents/{documentId}:
curl --fail-with-body --request PUT \
"$MOS_BASE_URL/extractedData/documents/$MOS_DOCUMENT_ID" \
--header "x-api-key: $MOS_API_KEY" \
--header "x-tyk-mos-client-secret: $MOS_CLIENT_SECRET" \
--header "tenant-id: $MOS_TENANT_ID" \
--header 'Content-Type: application/json' \
--data '[
{
"id": "kjg304q7baxcoctei30k4ck3",
"fieldTypeId": "vd346r0rh18538ppdogp3k5s",
"fieldValue": "Janet",
"manuallyCorrected": true
}
]'
manuallyCorrected: true identifies a manual correction. It is separate from the review approval flag, userApproved.
success is a boolean. extractedData.updated and extractedData.failed are arrays.
- Examine
extractedData.failed for fields that MOS could not update.
- Get the document’s extracted data again. Make sure that MOS saved the correct values.
Work with loans and documents
Get a loan record
Use this request to get the loan record and review counters:
curl --fail-with-body \
"$MOS_BASE_URL/loans/$MOS_LOAN_ID" \
--header "x-api-key: $MOS_API_KEY" \
--header "x-tyk-mos-client-secret: $MOS_CLIENT_SECRET" \
--header "tenant-id: $MOS_TENANT_ID"
The response contains loan. Its properties include id, status, createdAt, updatedAt, docsToReview, and fieldsToReview.
For a linked loan, externalLoanId identifies the record in the external system. loanNumber is a separate property. Loan status and review counters do not prove source-file completion.
List all documents on a loan
The default page size is 10. limit=100 requests up to 100 records. include=documentType adds the document type association to each record.
-
Get the first page:
curl --fail-with-body \
"$MOS_BASE_URL/loans/$MOS_LOAN_ID/documents?limit=100&include=documentType" \
--header "x-api-key: $MOS_API_KEY" \
--header "x-tyk-mos-client-secret: $MOS_CLIENT_SECRET" \
--header "tenant-id: $MOS_TENANT_ID"
-
If nextCursor is not null, copy its value to MOS_CURSOR:
export MOS_CURSOR='NEXT_CURSOR_FROM_RESPONSE'
-
Get the next page with a URL-encoded cursor:
curl --fail-with-body --get \
"$MOS_BASE_URL/loans/$MOS_LOAN_ID/documents" \
--header "x-api-key: $MOS_API_KEY" \
--header "x-tyk-mos-client-secret: $MOS_CLIENT_SECRET" \
--header "tenant-id: $MOS_TENANT_ID" \
--data-urlencode 'limit=100' \
--data-urlencode 'include=documentType' \
--data-urlencode "cursor=$MOS_CURSOR"
-
Do steps 2 and 3 again until nextCursor is null.
The response contains documents and nextCursor. The final page has nextCursor: null.
Get one document
Use this request to inspect a document record:
curl --fail-with-body \
"$MOS_BASE_URL/documents/$MOS_DOCUMENT_ID?include=documentType" \
--header "x-api-key: $MOS_API_KEY" \
--header "x-tyk-mos-client-secret: $MOS_CLIENT_SECRET" \
--header "tenant-id: $MOS_TENANT_ID"
The response contains document. Use the monitoring guide for source-file failures or missing completion events.
The default page size is 10. The request in Step 3: Get extracted data uses limit=100.
-
If nextCursor is not null, copy its value to MOS_CURSOR.
-
Get the next page:
curl --fail-with-body --get \
"$MOS_BASE_URL/extractedData/documents/$MOS_DOCUMENT_ID" \
--header "x-api-key: $MOS_API_KEY" \
--header "x-tyk-mos-client-secret: $MOS_CLIENT_SECRET" \
--header "tenant-id: $MOS_TENANT_ID" \
--data-urlencode 'limit=100' \
--data-urlencode "cursor=$MOS_CURSOR"
-
Do steps 1 and 2 again until nextCursor is null.
An extracted-field page can contain fewer than 100 records and still return a cursor. The next request can return an empty page.
Get the flattened loan data view
Use this request for loan-level data across documents:
curl --fail-with-body \
"$MOS_BASE_URL/loans/$MOS_LOAN_ID/data" \
--header "x-api-key: $MOS_API_KEY" \
--header "x-tyk-mos-client-secret: $MOS_CLIENT_SECRET" \
--header "tenant-id: $MOS_TENANT_ID"
The response contains data. This view applies field configuration, document configuration, and borrower scope. It can include documents without extracted fields. It does not provide every extracted row.
For extracted rows, the field type and document type must have inUse: true. The view excludes deleted extracted rows and deleted, duplicate, or trashed documents. It also selects among multiple external-field mappings.
Use GET /extractedData/documents/{documentId} to get the document’s extracted field records.
Each data row contains docTypeName. With jq installed, use this example to select document types:
curl --fail-with-body --silent --show-error \
"$MOS_BASE_URL/loans/$MOS_LOAN_ID/data" \
--header "x-api-key: $MOS_API_KEY" \
--header "x-tyk-mos-client-secret: $MOS_CLIENT_SECRET" \
--header "tenant-id: $MOS_TENANT_ID" \
| jq '.data | map(select(.docTypeName == "W-2" or .docTypeName == "Paystub"))'
Use the document type names from your response in the filter.
Change field labels
The document_types.manage permission is necessary to update a field type. This change applies to the tenant’s field definition.
-
Use the fieldTypeId from the extracted data response:
export MOS_FIELD_TYPE_ID='vd346r0rh18538ppdogp3k5s'
-
Update its display name:
curl --fail-with-body --request PUT \
"$MOS_BASE_URL/field-types/$MOS_FIELD_TYPE_ID" \
--header "x-api-key: $MOS_API_KEY" \
--header "x-tyk-mos-client-secret: $MOS_CLIENT_SECRET" \
--header "tenant-id: $MOS_TENANT_ID" \
--header 'Content-Type: application/json' \
--data '{"displayName": "Borrower first name"}'
In the flattened view, mosFieldName uses the document layout label first, then the field display name, then the field name. A layout label can override this change.
Map fields to an external system
External-field mappings connect MOS field definitions to external field definitions, such as Encompass fields. A mapping does not rename a field or prove export completion.
The Partner M2M API profile excludes /external-fields and /external-field-mappings. For this profile, ask your MOS integration contact to configure mappings.
If your approved API profile includes these routes, use this sequence:
-
Create an external field with POST /external-fields and this JSON body:
{
"name": "Borrower first name",
"tableIndex": "CX.SAMPLE.BORROWER.FIRST.NAME",
"source": "Encompass"
}
-
Record externalFieldId from the response.
-
Create a mapping with POST /external-field-mappings and this JSON body:
{
"fieldId": "vd346r0rh18538ppdogp3k5s",
"externalFieldId": "x1klg4396zdo1y3xqynq733u"
}
Use your configured external field name, tableIndex, and returned IDs. The Encompass custom field is an example.
Use analytics to investigate delays
If your API profile includes analytics, use the loan timeline to examine recorded processing events and document timings:
curl --fail-with-body \
"$MOS_BASE_URL/tenant/$MOS_TENANT_ID/analytics/loans/$MOS_LOAN_ID/timeline" \
--header "x-api-key: $MOS_API_KEY" \
--header "x-tyk-mos-client-secret: $MOS_CLIENT_SECRET" \
--header "tenant-id: $MOS_TENANT_ID"
The response contains data.events, data.documentTimings, and data.summary. Missing events or timestamps can limit the available timing data.
Use this request for task totals and average processing time across the tenant:
curl --fail-with-body \
"$MOS_BASE_URL/tenant/$MOS_TENANT_ID/analytics/metrics/processing" \
--header "x-api-key: $MOS_API_KEY" \
--header "x-tyk-mos-client-secret: $MOS_CLIENT_SECRET" \
--header "tenant-id: $MOS_TENANT_ID"
The response contains data.totalTasks, data.completedTasks, data.failedTasks, data.avgProcessingTimeMs, and data.tasksByService.
If the delay continues, give your MOS integration contact the loan ID, source-file ID, and related timestamps. The monitoring guide gives the recovery procedure.
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.