Integrations & monitoring
One registry holds every external connection the platform makes, and one discipline governs what comes back through it — evidence recorded before it is interpreted, matches compared field by field, and protection applied at intake where the law attaches at filing rather than at discovery.
Every external system the platform talks to is registered in one place, whatever it is for. A disaster data source, a bankruptcy monitor, a sanctions and watch-list source, a credit bureau, an accounting system: one registry, one status vocabulary, one credential discipline, one place an operations lead looks to answer is this working.
That uniformity is worth more than it first appears. Integrations fail in the same handful of ways regardless of what they connect to — a credential expires, a source goes stale, an endpoint moves, a subscription lapses — and integrations fail in the same handful of ways whatever they connect to — a credential expires, a source goes stale, an endpoint moves, a subscription lapses — so one status vocabulary answers all five the same way.
The five sources
A borrower does not ring up to say their county has been declared a disaster area. A bankruptcy petition is filed at a court, not with the servicer. A death is recorded in a federal file. Someone deploys.
A connection is described by four independent facts
| Fact | Values | Answers |
|---|---|---|
| Purpose | Event monitoring · Credit furnishing · Accounting export | What this connection is for |
| Status | DRAFT · ACTIVE · PAUSED · RETIRED |
Whether it should be running |
| Credential state | NOT_REQUIRED · MISSING · CONFIGURED · REAUTH_REQUIRED |
Whether it can run |
| Authorization kind | Credential fields · OAuth authorization | How access was granted |
Keeping status and credential state independent is what makes the pair honest. “Active” and “has no credential” is a contradiction, and the database refuses it: a connection cannot be activated while its credential is missing. A connector that is switched on but cannot authenticate is the single most common way an integration dashboard shows green while nothing is happening.
REAUTH_REQUIRED exists for the same reason. An OAuth grant that has been revoked, expired, or disconnected on the vendor’s side is not the same condition as one that was never configured — one needs a person to reconnect, the other needs a person to set it up, and telling an operator the wrong one wastes an afternoon.
Credentials are written, never read back
Credential handling follows three rules, each closing a specific failure:
A credential is never returned to a caller. The administration surface accepts a value and shows, afterwards, a keyed fingerprint and the time it was last rotated — never the value. There is no reveal control. A form for an existing connection reads leave blank to keep, so rotating one credential does not require re-entering the others.
The stored value is bound to its row. Credentials are encrypted with authenticated encryption whose associated data includes the tenant, the connection, the credential kind, and the key reference. Moving a stored blob to a different row does not decrypt into a working credential for that row — it fails to decrypt at all. The threat this addresses is database write access, which is a much lower bar than key access.
A missing key is a refusal, not a downgrade. If no field-encryption key is configured, a credential write fails and stores nothing. There is no fallback to plaintext, no silent success, and no partially-protected row. The fingerprint shown on screen is itself keyed rather than a plain digest, because a plain digest of a short credential — a six-character password, a numeric subscriber code — falls to an offline dictionary from a database read alone.
Credentials also never travel through the command pipeline. Command bodies are persisted as part of the audit record, so a secret passed through one would outlive the request that carried it; the administration surface writes to the credential store directly.
The destination is fixed by LendEasy, not by a tenant. An operator can pace, pause, or reconnect an integration. An operator cannot repoint it at a different endpoint — a tenant administrator cannot repoint a feed of borrower data somewhere new, so a tenant administrator cannot redirect a feed of borrower data somewhere new.
Connection tests prove reachability without committing to anything
Testing a connection makes at most one call and lets the result stand. It does not retry — retries belong to the job that owns the work, never underneath a person pressing a button and watching a spinner — and it does not activate, enroll, or subscribe.
Each provider defines what its own reachability check means, and the checks are chosen so that testing is cheap and side-effect-free: reading a capability rather than submitting a billable search, reading list health rather than performing a screen, reading one row rather than walking a catalog. A test that authenticates successfully but finds a required data source missing fails, naming what is missing, because a connection that cannot do its job is not a working connection.
An authentication failure during a test moves the connection to REAUTH_REQUIRED rather than leaving it looking configured.
The operational surface
GET /v1/servicing/admin/external-integrations
GET /v1/servicing/admin/external-integrations/{providerCode}
POST /v1/servicing/admin/external-integrations/{providerCode}/commands
POST /v1/servicing/admin/external-integrations/{providerCode}/connection-tests
POST /v1/servicing/admin/sweeps/{sweepKey}/runs
Reads require an integration read permission; changes and tests require an integration administration permission; credential writes require their own separate permission again, so the ability to configure a connection and the ability to hold its credential are grantable independently.
Monitoring and its results have their own reads:
GET /v1/servicing/monitoring/runs
GET /v1/servicing/monitoring/coverage
GET /v1/servicing/protection-findings
GET /v1/servicing/protection-findings/{findingId}
POST /v1/servicing/protection-findings/{findingId}/adjudications
Adjudication is its own permission, distinct from reading findings. Deciding that a sanctions hit is a false positive is a different act from being able to see that one exists, and the platform grants them separately.
Running a sweep on demand
A sweep can be run immediately rather than waiting for its next scheduled beat. This matters during an incident — a provider outage has been resolved, a credential has been rotated, a declaration has just been published — and it is safe because a run is identified by the period it covers rather than the moment it starts, so pressing it collides with that period’s scheduled run instead of buying a second one.
Pressing run now four times runs the work once. That is an operations control that cannot be misused into a second bill.
Finding something is not the same as knowing it
The mistake this is built to avoid is a single confident yes or no — sanctioned, deceased — that nobody can argue with afterwards. So three different things are recorded separately, and none of them decides the next:
- What the source said. A name came back off a list, or a court record matched. That is a lead, not a fact.
- What a trained person concluded after looking at the evidence, in writing, under their own name.
- What may then be done to the account — which is a separate action with its own permission and its own approval rules.
Picking up the review does not mean agreeing with it. Deciding the match is real does not by itself place a hold on the account. Each step leaves its own record, so if something goes wrong later it is possible to ask which of the three went wrong.
Why a near-miss is not a match
When a record comes back, the platform compares it to the borrower one field at a time and keeps each answer separately: the name agreed, the date of birth contradicted, the address was not supplied.
A single similarity score throws away the thing a reviewer needs — which parts matched. A shared surname with a contradicting birth date is a different situation from a full match, and it should not arrive on somebody’s screen as “87%” — which parts matched. A shared surname and a contradicting birth date is a different situation from a full match, and it should not arrive on someone’s screen as “87%”.
Two rules follow from keeping the detail:
- Missing is not “no”. If one side did not supply a field, that field is unknown, and unknown never quietly becomes a clean result.
- The last four digits of a tax identifier never confirm identity on their own. Plenty of people share them.
Evidence is written down before anyone interprets it
What a source returned is recorded first, exactly as it arrived, before the platform tries to make anything of it. If the interpretation later turns out to be wrong, the original is still there to re-read.
Records are never edited or deleted. A source that later withdraws a record has that withdrawal added, not applied by erasure. And if the evidence behind a decision changes afterwards, the decision reopens — because a conclusion drawn from evidence that has since moved should not be allowed to stand quietly.
A cleared false alarm is remembered, so the same borrower is not reviewed again every night for sharing a name with somebody. But that clearance is tied to the exact evidence that was cleared, and it expires. New evidence dissolves it.
Failure is visible and owned
A failed check records its failure category, a human-readable detail, and the next action a person should take — and the record is constrained so that a failure without both a category and a next action cannot be stored. Failures raise reconciliation work at high priority, deduplicated against the check, so an outage lasting six hours produces one item of work rather than seventy.
Resolving that work requires a successful connection, a successful check, or a documented accepted handoff. Marking it done is not one of the options.
Coverage says what it actually covered
If the platform cannot prove it checked everyone it was supposed to, it says so, rather than reporting a partial pass as a clean sweep. Two facts are reported apart rather than averaged into one number: whether every customer was enumerated, and whether the people connected to a corporate customer were. A company is screened as an entity; its officers, directors and owners are not — the platform holds no register of company relationships, and says that plainly instead of letting a company-name check pass for full coverage.
“We screened the portfolio” is a claim somebody may one day have to defend. This report instead says which people were checked and which could not be confirmed. “We screened the portfolio” is a claim somebody may one day have to defend. “We checked these people, and here is who we could not confirm” is a claim that survives being asked about.
What happens when something is found
A confirmed finding opens a case of the right kind and routes it to the team that handles that work — bankruptcy filings to the bankruptcy specialists, death notices to estate handling, sanctions to compliance review, disaster impact to hardship.
What protection is applied before anyone reviews it differs by category, and the differences are deliberate:
| Category | What happens immediately |
|---|---|
| Bankruptcy, death, military service | Collections outreach pauses straight away |
| Disaster | Collections contact pauses; a payment the borrower wants to make is still honoured |
| Sanctions | Nothing. The finding is information until a person decides it |
Sanctions is the odd one out on purpose, and the reasoning is worth reading — it is the clearest example of the platform declining to do something that would look responsible and would actually harm borrowers.