LendEasy/DocsLMS + Servicing·v1
Start integrating
Guides›Servicing Workspace›Servicing reports

Servicing reports

Each report answers one operating question, echoes the query it actually applied, and links back to the work behind every number it shows.

Seven reports, each answering one question a supervisor actually has this morning — where work is piling up, who has capacity, which delinquent borrowers can be contacted today, and whether the promises the team took are being kept.

One report, one operating question

Seven reports, and each one names its question:

Report Route Answers
Workforce GET /v1/servicing/reports/workforce Where is work piling up, and who has capacity?
Collections GET /v1/servicing/reports/collections Which delinquent matters are contactable, and when?
Interaction exceptions GET /v1/servicing/reports/interactions/exceptions Which channel work was missed, unmatched, or failed?
Compliance GET /v1/servicing/reports/compliance What did policy decide, under which rules and regimes?
AI quality GET /v1/servicing/reports/ai-quality How grounded and how reviewed is AI output?
Reconciliation GET /v1/servicing/reports/reconciliation Where has servicing state drifted from the Lending Core?
Promise & allocation GET /v1/servicing/reports/promise-allocation Are promises being kept, and is work reaching the people who can keep them?

All seven take READ_SERVICING_REPORTS, accept exact structured filters plus limit/offset and sort/order, and return the same outer shape:

{
  "asOf": "2027-05-05T18:30:00Z",
  "effectiveQuery": { "limit": 50, "offset": 0 },
  "rows": [],
  "returnedCount": 0,
  "hasMore": false
}

Read effectiveQuery before trusting a total: a report page is a bounded slice.

Drill-through, not a dead end

The workforce report aggregates by QUEUE or WORKER and gives each row a link straight back into the base collection:

{
  "dimension": "QUEUE",
  "summary": {
    "openTaskCount": 18,
    "activeTaskCount": 7,
    "staleAcceptedTaskCount": 1,
    "overdueTaskCount": 2,
    "slaBreachedTaskCount": 1,
    "openCaseCount": 42,
    "availableWorkerCapacity": 21
  },
  "rows": [
    {
      "queueCode": "COLLECTIONS",
      "openTaskCount": 18,
      "overdueTaskCount": 2,
      "oldestTaskAgeMinutes": 91,
      "eligibleWorkerCapacity": 28,
      "availableWorkerCount": 4,
      "drillThrough": "/v1/servicing/tasks?queueCode=COLLECTIONS"
    }
  ]
}

staleAccepted=true isolates accepted work that has stopped moving — the case a throughput average hides.

A planning aid is not an authorization

The collections report joins current Lending Core financial facts to servicing work state, so a row carries both the money and the permission to act on it:

{
  "caseId": 1001,
  "customerRef": "412",
  "loanRef": "7204",
  "priority": "HIGH",
  "promiseState": "ACTIVE",
  "financialFactsSource": "LMS",
  "daysOverdue": 22,
  "delinquencyBucket": "DPD_1_29",
  "overdueAmount": 517.14,
  "currency": "USD",
  "contactIntensity": 2,
  "remainingContactCapacity": 5,
  "lastContactAttemptAt": "2027-05-04T21:04:00Z",
  "nextPermittedContactAt": "2027-05-06T15:00:00Z",
  "protectiveStateActive": false,
  "contactBlocked": false
}

financialFactsSource names where the balance came from; the servicing workspace does not recompute delinquency. nextPermittedContactAt and remainingContactCapacity are planning aids from the contact budget, not authorizations — the owning operation still runs its own execution-time check immediately before contact, and can block work this report showed as permitted.

Compliance and AI-quality reports

The compliance report exposes decision outcomes with their rule and regime detail, filterable by outcome, hardStop, regime, ruleCode, channel, and proposedAction:

{
  "decisionId": 6117,
  "proposedAction": "OUTBOUND_CONTACT",
  "channel": "PHONE",
  "outcome": "ALLOWED",
  "hardStop": false,
  "rules": [{ "ruleCode": "CONTACT_WINDOW_CA", "regime": "REG_F", "outcome": "ALLOWED" }]
}

The AI-quality report projects retained output, grounding, runtime, and review state together — session, worker and adapter codes, autonomyLevel, runtimeVersion, policyVersion, workPacketVersion, confidence, groundingStatus, and the reviewer and review time. Because runtime and policy versions are rows rather than metadata, a quality regression can be attributed to the version that caused it instead of being averaged away.

The reconciliation report returns current servicing-to-core drift with its classification, priority, and the review task opened for it — the same row shape Reconciliation & drift works through in full.

This is the servicing-plane view. Money-movement exceptions between provider events, intents, and the ledger stay in the Lending Core catalog.

The investor report pack

Two routes serve a curated 18-report pack: GET /v1/servicing/reports/investor lists the catalog, and GET /v1/servicing/reports/investor/{reportKey} returns one report. Both accept READ_REPORT or READ_SERVICING_REPORTS.

Every response says where its numbers came from:

{
  "provenance": {
    "label": "Reporting snapshot",
    "loadKey": "INVESTOR_V1:2027-05-05",
    "sourceWatermark": "portfolio-v1:2027-05-05",
    "generationMode": "SNAPSHOT_LOAD",
    "nonAuthoritative": true
  }
}

The pack is a snapshot load. It never reads live servicing or ledger tables, and the response says so in nonAuthoritative: true rather than in a footnote somebody might strip — reconcile against the authoritative source before publishing a figure externally.

A report renders as headline metrics, insights, a trend, a breakdown, a supporting table, and a methodology note. Metrics declare their own format (number, percent, currency) and tone, and delta/deltaLabel keys are omitted when no comparison period was supplied rather than returned as zero — a zero delta on a slide reads as no change, which is a claim about the business rather than about the absent comparison. The reportKey must come from the catalog, so an arbitrary key is rejected instead of returning an empty report that a reader would take for an empty quarter.

Read methodology before comparing two figures. In the collections pack, for example, promise kept-rate is count-based while dollar kept-rate is value-based, and promise dollars are never counted as collected until the cash is realized.
These are focused reads for operating and oversight. They are not an export path for bulk personal data, and no report returns sensitive content that the caller could not read through the owning resource.
Unified search across guides, recipes & the API referenceEsc