Sync customer and loans from LMS
curl --request POST \
--url https://api.finosu.com/webhooks/lms/sync/customer-full \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"customerId": "12345"
}
'import requests
url = "https://api.finosu.com/webhooks/lms/sync/customer-full"
payload = { "customerId": "12345" }
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({customerId: '12345'})
};
fetch('https://api.finosu.com/webhooks/lms/sync/customer-full', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.finosu.com/webhooks/lms/sync/customer-full",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'customerId' => '12345'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.finosu.com/webhooks/lms/sync/customer-full"
payload := strings.NewReader("{\n \"customerId\": \"12345\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.finosu.com/webhooks/lms/sync/customer-full")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"customerId\": \"12345\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.finosu.com/webhooks/lms/sync/customer-full")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"customerId\": \"12345\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"lmsType": "example-lms",
"customerId": "12345",
"finosuCustomerId": "550e8400-e29b-41d4-a716-446655440000",
"loansSynced": 2,
"loans": [
{
"loanId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"nortridgeAcctrefno": 100001,
"loanExternalReference": "LOAN-001",
"transactionsRows": 15,
"paymentsDueRows": 12,
"paymentMethodsCreated": 1,
"paymentMethodsUpdated": 0,
"documentRows": 3,
"transactionsError": "<string>",
"paymentsDueError": "<string>",
"paymentMethodsError": "<string>",
"documentsError": "<string>",
"setupError": "<string>"
}
],
"error": "<string>"
}{
"detail": "<string>"
}{
"detail": "<string>"
}{
"detail": "<string>"
}{
"detail": "<string>"
}{
"detail": "<string>"
}{
"detail": "<string>"
}LMS Sync
LMS Customer Full Sync
Perform a full sync of a customer and all their loans from the company’s configured LMS.
POST
/
webhooks
/
lms
/
sync
/
customer-full
Sync customer and loans from LMS
curl --request POST \
--url https://api.finosu.com/webhooks/lms/sync/customer-full \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"customerId": "12345"
}
'import requests
url = "https://api.finosu.com/webhooks/lms/sync/customer-full"
payload = { "customerId": "12345" }
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({customerId: '12345'})
};
fetch('https://api.finosu.com/webhooks/lms/sync/customer-full', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.finosu.com/webhooks/lms/sync/customer-full",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'customerId' => '12345'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.finosu.com/webhooks/lms/sync/customer-full"
payload := strings.NewReader("{\n \"customerId\": \"12345\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.finosu.com/webhooks/lms/sync/customer-full")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"customerId\": \"12345\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.finosu.com/webhooks/lms/sync/customer-full")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"customerId\": \"12345\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"lmsType": "example-lms",
"customerId": "12345",
"finosuCustomerId": "550e8400-e29b-41d4-a716-446655440000",
"loansSynced": 2,
"loans": [
{
"loanId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"nortridgeAcctrefno": 100001,
"loanExternalReference": "LOAN-001",
"transactionsRows": 15,
"paymentsDueRows": 12,
"paymentMethodsCreated": 1,
"paymentMethodsUpdated": 0,
"documentRows": 3,
"transactionsError": "<string>",
"paymentsDueError": "<string>",
"paymentMethodsError": "<string>",
"documentsError": "<string>",
"setupError": "<string>"
}
],
"error": "<string>"
}{
"detail": "<string>"
}{
"detail": "<string>"
}{
"detail": "<string>"
}{
"detail": "<string>"
}{
"detail": "<string>"
}{
"detail": "<string>"
}Overview
Perform a full sync of a single customer and all their loans from your company’s configured LMS. This endpoint can be used:- Manually by client engineers for testing
- As a webhook target for automated syncs when your LMS detects updates (e.g., new loan application)
- Customer/contact information (name, phone, email, SSN, address, etc.)
- All loans for the customer
- For each loan: status, amounts, and schedule creation as appropriate
Request Body Format
{
"customerId": "12345"
}
Fields
- customerId — Customer identifier in your LMS (required). Must be a non-empty string.
What Happens During Sync
- Finosu calls your company’s LMS to fetch the customer’s data
- Creates or updates the customer record in Finosu (name, phone, email, birthday, SSN, address, timezone)
- Fetches all loans for that customer from the LMS
- For each loan:
- Creates or updates the loan record in Finosu
- For pending/origination loans: creates the call schedule automatically
- For active loans: creates the loan record for servicing
- Terminal loans (closed, paid, etc.) are skipped
Response Format
{
"success": true,
"lmsType": "example-lms",
"customerId": "12345",
"finosuCustomerId": "550e8400-e29b-41d4-a716-446655440000",
"loansSynced": 1,
"loans": [
{
"loanId": "660e8400-e29b-41d4-a716-446655440001",
"loanExternalReference": "98765"
}
],
"error": null
}
Response Fields
| Field | Type | Description |
|---|---|---|
| success | boolean | Whether the sync completed successfully |
| lmsType | string | The LMS type used for this company |
| customerId | string | The external customer ID you provided |
| finosuCustomerId | UUID | The Finosu internal customer ID |
| loansSynced | integer | Number of loans synced |
| loans | array | Per-loan sync details |
| error | string or null | Error description if the sync failed |
Error Handling
| Status | Meaning |
|---|---|
| 200 | Sync result returned; inspect success and per-loan errors |
| 400 | LMS type does not support customer-level sync |
| 401 | Missing or invalid API key |
| 403 | Company not authorized for LMS integration |
| 404 | Customer confirmed missing from the LMS |
| 422 | Request-body validation failed or customer identifier is invalid for the configured LMS |
| 500 | Unexpected provider or internal error during sync |
Authentication
Requires X-API-Key header with a valid webhook API key. The key determines which company and LMS integration to use.Syncing Multiple Customers
To sync multiple customers at once, use the LMS Customer Batch Sync endpoint instead. It accepts an array of customer IDs and processes them asynchronously.Request naming
Use camelCase request fields. Existing snake_case aliases are also accepted by the API.Retries and results
Idempotency-Key is logged for correlation only; it does not deduplicate requests or replay earlier results. A repeated request can run the sync again.
HTTP 200 means a sync result was returned. Inspect success, error, and each entry in loans before treating the operation as successful. Missing or invalid authentication returns 401; request-body validation failures and invalid LMS identifiers return 422.
Validation-status migration
Invalid LMS identifiers and batch-job UUIDs return422. Confirmed missing records return 404; malformed provider data and unexpected internal failures return 500. Unsupported LMS operations retain 400. Update status-based integrations and monitoring: some cases previously reported as 400, 404, or 422 now have a different classification. This does not make retrying a sync safe or enable request deduplication.Headers
Body
application/json
Customer identifier to sync
Response
Sync result returned. Inspect success, error, and per-loan results.