White-label borrower apps
The borrower-facing web and mobile apps: what a borrower can do on each screen, and what happens on the servicing side when they do it.
The borrower apps run on the same servicing platform your team works in, rather than alongside it. A message a borrower sends becomes an interaction on their timeline and a task in a queue. A document a case asks for is requested in the app and attached to that case when it arrives. This page covers what a borrower can do and what each action produces on the operator side.
What a borrower can do
| Area | Available actions |
|---|---|
| Dashboard | See what needs attention first — a payment due, a document request, an unread reply. |
| Loans | Schedule, activity, statements and autopay state, each on its own addressable tab. |
| Payments | Pay the amount due or a different amount, from a saved bank account or card. |
| Autopay | Enrol, pause, resume or cancel. |
| Payment methods | Add or remove a bank account or card. |
| Agreements | Read, sign, decline, or request a change to an agreement. |
| Documents | Download statements and letters; upload a document a case has requested. |
| Messages | Write to the servicing team and read replies. |
| Assistance | Ask for payment help, with the situation and its details captured. |
| Settings | Delivery preferences, profile, and security. |
Messages
A borrower message is written to their conversation thread and produces two records on the servicing side: an interaction on the customer timeline, alongside every call, letter and email they have had with you, and a task the communications agent picks up.
A message does not open a case. Most are a single question with a single answer, and a case for each one makes the case queue unusable. When a message turns out to be a hardship, a dispute or a cease request, the agent opens the appropriate case and links the conversation to it; the link is refused if the interaction already belongs to a different case.
Three behaviours to know when integrating:
- Only the agent holding the task can reply. The server checks that the caller is the task’s assignee and refuses otherwise. Reading and replying are separate permissions.
- A reply on an open thread does not create a second task. It appends to the existing one and updates its last-modified time, so an active conversation does not sink in an activity-sorted queue.
- A reply to a closed conversation reopens it in the same transaction and enqueues a fresh interaction and task.
Borrowers see a display name rather than a username: rosa.iyer renders as Rosa from Servicing.
Document requests
When a case reaches a step that needs evidence from the borrower, it issues an upload invitation. The invitation is created against that case and carries its identifier, so nothing has to be reconciled afterwards.
- A case step requests a documentthe invitation carries the case idautomatic
- The borrower sees the request in the appfetched on read, not pushedwaits
- They upload the filea person
- It is written against the requesting caseautomatic
- Review completes the task and the case re-evaluatesautomatic
Invitation states are ISSUED, DELIVERED, OPENED, UPLOADED, plus EXPIRED, REVOKED and SUPERSEDED. Issuing a new invitation for the same case and evidence type supersedes the live one. Refusals come from a fixed list: unknown link, expired, revoked, already used, rate-limited.
The request the borrower reads is generated per evidence type and carries what the document must show, what not to send, why it is needed, the accepted formats and the size limit. It contains no case or loan detail.
Uploads are checked on their actual bytes rather than the filename or declared content type, capped at 10 MiB, and streamed through the same evidence pipeline as a document an operator uploads — the same scanning, the same single-purpose session, the same refusals.
The borrower receives a reference on upload and sees the file in their documents immediately, carrying PENDING_REVIEW, ACCEPTED or REJECTED. A rejection carries a reason class — unreadable, wrong document, incomplete, or issued too long ago — and never the reviewer’s own note.
Expiry re-evaluates the case in the same way an upload does, so a case does not wait indefinitely at a document step.
Agreements and signing
An agreement is presented as a plain-language summary followed by the legal text, with per-item acknowledgements and a step-up confirmation. Signing runs ten checks in order:
The first failure refuses the signature
- 1The agreement belongs to this customercustomer-bound, not loan-bound, so a co-borrower cannot decline the primary’s relief
- 2It is still openpending or viewed only
- 3The document digest matches what was presented
- 4The live offer is re-read and still matchesmoved terms mark it superseded or expired rather than binding the borrower
- 5All required acknowledgements are present
- 6The name the borrower types matches the signer name on the agreementcase- and whitespace-insensitive; an intent artifact, not authentication
- 7The step-up challenge is consumedbound to this action, this agreement and this digest — three attempts
- 8The evidence record is assembleddocument, acknowledgements, consent version, session, address, time
- 9It is signed with the evidence keyheld separately from the session key, and retained for the life of the evidence
- 10The signature is stored, then the loan system is called
Because the signature is stored before the acceptance call, a transport failure leaves the agreement SIGNED and retrying under the same key; the borrower is not asked to sign again. Acceptance returns one of three outcomes: executed, executing, or invalidated — the last when the loan moved between signing and execution, in which case the prior evidence is retained and a refreshed offer follows.
Statuses are PENDING, VIEWED, CHANGE_REQUESTED, SIGNED, EXECUTED, ACCEPTANCE_INVALIDATED, DECLINED, EXPIRED, SUPERSEDED.
Declining and requesting a change are separate endpoints given equal prominence in the interface. Neither the app nor the borrower authors terms: a change request transmits what was asked for, and the lending system authors what is offered back.
Payments and autopay
A payment takes four fields: the kind of amount, the amount as a decimal string, the instrument, and the effective date. Unknown fields are rejected.
The authorization wording is not part of the request. The server composes it from the amount, date and rail, stores it verbatim beside the payment, and echoes it back so the confirmation shows the stored record rather than the client’s copy. The amount is re-derived at submission rather than read from cache, and its as-of time is stamped into the evidence row.
The rail comes from the instrument and determines the forwarded request, the stored wording (debit from against charge to), the estimated timing the borrower sees, and the audit row — so those four cannot disagree. An unrecognized rail is refused.
Borrower-facing payment states are SUBMITTED, PROCESSING, POSTED, RETURNED, FAILED. Operators see the fuller intent lifecycle and the ledger allocation.
Autopay enrolment is ACH only and carries the instrument, the step-up challenge, how many days before the due date to initiate, the business-day convention, the behaviour on schedule change, and the amount policy. Pausing, resuming and cancelling are gated the same way as enrolling, because pausing stops payments as effectively as cancelling and delinquency follows either way. States are ACTIVE, PAUSED, NONE.
Bank and card details are entered on the provider’s own hosted page and returned as a token. The step-up challenge is reserved when the hosted session opens and consumed when the instrument is added, so abandoning the flow does not spend the borrower’s daily allowance.
Assistance requests
An assistance request carries the loan, a situation from a fixed list — job loss, reduced income, medical, bereavement, disaster, other — the borrower’s own description, and an optional recovery date. It opens an ordinary conversation whose first message reads in the borrower’s voice rather than as a form dump, and inherits the same staffing behaviour as any message.
The portal does not open a hardship case and does not quote terms. A client reference makes a double submission idempotent.
Returned payments
A returned payment opens a collections case against the loan at high priority, with a review task in the collections queue. Where the return matches the configured high-risk conditions, autopay is cancelled by a case effect — one of four permitted effect types, and restricted to this path.
A credit balance opens a payment investigation case instead, routed to the queue that owns money which has already moved: refunds, returns and misapplied payments.
Support sessions
Staff can open a borrower’s app read-only to see what the borrower sees.
Read-only is enforced by capability rather than by HTTP method, because some reads legitimately write: a document download records an audit row, and rendering an agreement would normally mark it viewed. Each handler declares whether it writes nothing, writes only an audit row, mints a short-lived artifact, or mutates. A support session may invoke the first three. A handler with no declaration is treated as mutating, so a new route is safe by omission.
Three behaviours are carved out beyond that gate: messages are not marked read, agreements are not marked viewed, and document downloads stream rather than redirect, so no bearer-free URL outlives the session.
Branding and tenancy
Branding resolves to design tokens at runtime. Per-tenant subdomains and custom domains are supported, and each tenant’s data is held in its own database.
Every screen here runs on the self-service API, which is also what you would build against to replace any of it.