LendEasy/DocsLMS + Servicing·v1
Start integrating
GuidesServicing WorkspaceQueues, routing & who gets the work

Who gets the work

A queue nobody looks at is a queue nobody works, and the promise a borrower is waiting on is the item least able to survive being overlooked — so work is offered rather than left to be found.

Work reaches a named person or AI agent by being offered to them individually, with the reason they were chosen, rather than being listed for whoever claims it first. How a case moves explains how a case decides it needs work done; this page explains how that work reaches somebody, what they can do with it, and what happens when nobody can take it.

A task is createdby a step, a job, a serviceROUTINGWhich queue owns this?Decided once, at creation.Written onto the task itself.ALLOCATIONWhich worker is offered it?Decided again and again.Written into its own offer log.An AI agentholds itor a personwhere reserved“Task-type default queue.”“Workflow queue hint COLLECTIONS.”“Owns the case and is available.”“Carrying the least work of four.”
Both decisions record their reason as a sentence rather than a score.

Two decisions, not one

People usually describe this as “assigning a task”, as though it were one act. It is two. They are made at different moments by different machinery, and both are written down separately. Keeping them apart is what lets you answer two very different questions later: why is this in the bankruptcy queue? and why was it offered to me?

What a task is

A task is one unit of work the platform has to place — with an AI agent, which is where most of it goes, or with a person where policy reserves that decision for one. Everything else on this page is about getting each task to the right holder.

What it carries Why it matters
Status Enforced by the database, not just by code, so an illegal move is refused rather than trusted.
Queue, and why The queue plus the rule that put it there, the reason in English, and the policy version. Recorded at creation and never re-derived, so the placement can be explained later without re-running the rules against facts that have since changed.
Two possible holders The person who has accepted it, and separately the person it is currently offered to. Different columns, because they are different states.
Where it came from A source type and a source reference. That reference is load-bearing: it decides whether the task can be cancelled, whether something else owns its lifecycle, and whether it is the current step’s own work.
Which visit it answers for Not the step, the visit. A flow can return to the same step, and the second visit’s rule must not be satisfied by the first visit’s work.
When it becomes actionable, and when it is late Two separate times. For a promised callback they are the agreed window’s start and end.
Sensitivity A sensitive task is invisible to anyone without the specific permission — in every view, and at reservation.
Its outcome Written only on completion, from a catalog.
One unresolved borrower promise per case, held by the database itself. A second request opens the existing one instead of stacking a rival promise the borrower never made.

Where tasks come from

Five sources, and the difference matters because it decides who is allowed to finish the task.

  • A workflow step asking for the work its rules describe. This is most of them.
  • A standing timer on a monitoring step, raising its review on a cadence.
  • A service that owns something and needs a person: a failed effect raises exactly one review, a reconciliation drift raises its own, a governed action request needing manual execution raises its own.
  • The channel gateway, when a call is answered. That path creates the task already accepted by the agent who answered, bypassing the offer entirely, and records a system decision so the bypass is auditable.
  • A person, creating follow-up work or a checklist item on a manual case.

Work owned by a parent — an action request, a recovery review — cannot be completed through the ordinary task command. It completes inside the parent’s own transaction, and the platform first transfers the task to the person resolving it, so the record still names one accountable person rather than closing under somebody who did not do it.

Choosing the queue

Eight levels, tried in order, first match wins. This runs once, when the task is created.

TRIED IN ORDER, FIRST MATCH WINS1An explicit escalation targetSomebody said “send this there”. It beats everything below.2A governed compliance destinationOnly when the task type is itself compliance work. Otherwise it is an error, not an instruction.3A sensitivity or specialist restrictionA configured rule about who may see this kind of thing.4Named-owner continuityKeep it with the person already on the case, but only if they are actually eligible.5The workflow layer: a stage rule first, and only then the step’s queue hintThis is where a case-type team rule lives, so every task on a bankruptcy case goes to the bankruptcy teamwhatever the step suggested. The hint is an input at this level, never a bypass.6A case-type or task-type overrideAnother configured rule, less specific than the ones above.7The task type’s own default queueEvery task type has one. This is the ordinary answer.8DEFAULTThe catch-all. Zero matches or several ambiguous ones land here. Routing never guesses.no match, fall through
Levels three to six are configured rules that change without a release. Levels one, two, seven and eight are resolved in code.

Two things follow from that ladder that are easy to miss. A workflow step’s queue hint is weak, not strong — a stage rule is consulted before it, and a case-type team rule matches every task on that case, so the hint often never gets a look-in. And the compliance queue cannot be named, only earned: a step hint or an escalation pointing at it is rejected outright unless a governed process supplied a closed reason and a source. Public and template input cannot select that queue or manufacture its reason.

Queues and the people in them

A queue is pure configuration: a code, a name, a type, an enabled flag. Membership is a join with an active flag, and removing somebody deactivates the row rather than deleting it, so history stays answerable.

Queue What lands there
SUPPORT General borrower support.
COLLECTIONS Delinquency review and outreach.
BANKRUPTCY Specialist evidence and restriction work.
CEASE_COMMUNICATIONS Cease and representation requests.
COMPLIANCE_REVIEW Second-line work. Every task needs a closed reason and source.
ACTION_REVIEW Failed, manual-execution and approval-required action requests.
AI_REVIEW AI quality and low-confidence review.
UNKNOWN_INTAKE Inbound nobody has identified yet.
PAYMENT_OPERATIONS Refunds and payment investigations. Deliberately never falls back to collections.
HARDSHIP Assistance programmes, including disaster relief.
ESCALATION Routes to the selected person or team only, and overrides ordinary routing.
LANGUAGE_SPECIALIST · MILITARY_SPECIALIST Specialist callbacks.
SANCTIONS_REVIEW · ESTATE_HANDLING Sanctions decisions, and deceased-borrower and estate work.
IT_ONCALL Infrastructure failures, which are an IT concern rather than a servicing one.
DEFAULT The catch-all.

Workers

One registry holds three kinds. A human has a real platform login and a capacity. An AI worker has no login at all: it has an adapter and a contract version, and its registration states maxima rather than authority. A system actor is a closed, code-defined set of job identities that never reserve ordinary queue work.

Presence is intent, not workload. A worker on a call stays available and is withheld the second call by voice occupancy, not by a status change, so provider events never quietly mark anyone busy.

Capacity is the smaller of the person’s own configured number and the platform-wide ceiling. A person configured to carry less than the platform allows is respected; nobody carries more. Reserved work counts against capacity, because an unanswered offer is being held for that person and nobody else can have it. A callback scheduled for Thursday does not, because a promise for Thursday is not something anyone is carrying today.

Specialist capability is expressed as a destination, not as a skills model: the language and military specialist queues exist, and their members are the qualified people. Reservation does not check skills, so filtering a queue by them would promise a rule nothing keeps. Specialist routing is a queue and a membership list.

Who is allowed to take it

One contract answers this, and every caller asks it: the views, the pull command, and the dispatcher. That is deliberate. A view that offered work reservation would refuse sends an operator to a locked door, and a dispatcher that pushed work reservation would refuse is the same failure arriving uninvited.

The worker exists, and is activeThe task type admits this kind of worker, human or AIThey are registered for this task typeThey are an active member of the task’s queueThey may accept tasks at allIf the task is sensitive, they may see sensitive workTheir presence says availableThey are not already sitting on an unanswered offerThey are under capacityFor voice work, they are not already on a callThese two apply only when theplatform is offering work to them.Someone may still go and pull work themselves.
A worker who marks themselves away should not have work put in front of them, but may still pull something if they choose to. The difference is between the platform interrupting somebody and somebody deciding to work.

Authority is read from the worker being considered, never from whatever triggered the dispatch, because the dispatcher acts for a worker rather than as them. And voice exclusivity is declared on the task type rather than inferred from a queue or a channel, so a new kind of conversation has to declare itself.

Two routes to a worker

A worker comes to hold a task in exactly two ways, and both ask the same eligibility question.

PUSH · THE DISPATCHERFired after a task is created or activated,when a worker becomes available or freesa slot, when an offer is released, and onthe sweep that catches what was missed.PULL · THE WORKER ASKS“Give me the next thing I can work on.”Available whatever their presence says.The sameeligibility contractasked the same wayOne reservationheld for that person,with a deadlineThe reservation IS the offer.There is no separate “offered” state, so a worker who ignores an offer coststhe work one reservation window rather than a whole shift.
Because both routes produce the same thing, acceptance, expiry, decline and release each keep one meaning whichever route produced them. One lifecycle instead of two.

The offer

When the dispatcher has a choice to make, it makes it in a stated order rather than by scoring — because an operator asking why they were given something deserves a sentence.

WHICH WORK1. Anything critical2. Anything already overdue3. Whatever is due soonest4. Priority, plus a bonus for waiting5. Oldest firstThe waiting bonus rises one band every four hours,so low-priority work cannot wait for ever.WHICH PERSON1. Eligible, and has not declined this one2. The case owner, if available right now3. Whoever is carrying the least4. Whoever has waited longest for an offerCase ownership is a preference, never a wait: a promisedcallback is not held for its owner while somebody elsecould make it on time.
Every offer is logged with the sentence that justified it, the number of candidates considered, and what triggered the attempt.

An offer has a deadline, two minutes by default. Three things can end it.

  • Accepted. The full eligibility contract is re-run at this moment, not assumed, so a worker whose circumstances changed between the offer and the answer is refused here rather than discovered later.
  • Declined, optionally with a reason. That worker is then skipped when the work is offered again. Declining is not the same as saying the work cannot be done; it says nothing about the work at all.
  • Expired. A sweep runs every fifteen seconds, returns the task to the queue, and immediately offers it again. It is faster than the other sweeps because the cost of being slow here is a person waiting.

Marking yourself busy, away or offline returns any unanswered offer and re-offers it, but never touches work already accepted.

Taking the next task

The implemented route derives the worker, queue membership, capacity, and reservation duration from the authenticated workforce record and queue policy:

curl -X POST "$BASE/v1/servicing/tasks/reserve-next" \
  -H "Authorization: Bearer $TOKEN" \
  -H "LendEasy-Tenant: demo-lender" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: reserve-next-ana-4-2027-05-01T1000" \
  -d '{
    "queueCode": "COLLECTIONS",
    "taskTypeCodes": ["COLLECTIONS_OUTREACH"]
  }'
{
  "taskId": 2001,
  "reservationExpiresAt": "2027-05-01T10:02:00-07:00"
}

Selection and reservation happen in one step, so two workers cannot receive the same task.

A task’s whole life

SCHEDULEDa future promisewindow opensAVAILABLEofferedRESERVEDacceptedACCEPTEDIN PROGRESSoptionaldeclined, or the two minutes ran outCOMPLETEDwith an outcome and its proof“I cannot do this”Is this the current step’s own work?If yes it is HELD, unassigned, and a recovery reviewis raised. If no it simply ends as unable.Back to the queue, handed on, or withdrawnwhichever way the reviewer settles itOne more ending.CANCELLED, with a reason, from any active state.
The database refuses an illegal move rather than trusting the code that asked for it. Completed, unable and cancelled are ends: nothing leaves them.

What a worker sees

Six views, and they exist because “the queue” was answering the wrong question. A queue listing shows what is in a queue. An operator needs to know what they can start now, which is a different set.

View Shows
Ready for me Work this person can pick up right now. Every clause mirrors a check the reservation would make, in the same order, because a view that shows work reservation would refuse is worse than no view at all — it sends someone to a locked door.
My work Everything they are holding: offered, accepted, in progress, waiting.
Waiting Their work that is parked on somebody else.
Team backlog Unassigned human-eligible work across their queues, whether or not they personally qualify. A supervisor needs to see the item nobody on shift can take.
AI work Work an AI holds or has run, including finished and failed runs — because a run that failed is the point of the view.
All work The unrestricted inventory.

Two properties matter more than the list. The caller’s identity is resolved on the server for every view, so a client cannot ask for somebody else’s ready for me. And a view narrows and is never widened: asking for ready-for-me plus completed still returns only available work.

Two self-serve reads keep the workspace grounded in the authenticated worker’s real eligibility instead of client-side assumptions. GET /v1/servicing/me returns the worker’s own context in one call — identity, queue memberships, task-type eligibility, presence, the live reservation if one exists, active assignments, and whether the worker is at capacity:

{
  "workerId": 4101,
  "displayName": "Maria Agent",
  "active": true,
  "capacity": 8,
  "taskTypeCodes": ["COLLECTIONS_OUTREACH"],
  "queueCodes": ["COLLECTIONS"],
  "presence": { "state": "AVAILABLE", "channels": ["PHONE", "GENERAL"], "since": "2027-05-05T18:00:00Z", "setBy": "AGENT_TOGGLE" },
  "activeReservation": { "taskId": 2001, "reservationExpiresAt": "2027-05-05T18:40:00Z" },
  "activeAssignments": [
    { "taskId": 2002, "status": "IN_PROGRESS", "taskTypeCode": "COLLECTIONS_OUTREACH", "queueCode": "COLLECTIONS", "priority": "HIGH", "dueAt": "2027-05-06T17:00:00Z" }
  ],
  "activeAssignmentCount": 1,
  "atCapacity": false
}

GET /v1/servicing/task-types returns the presentation-safe task-type catalog for enabled queues — code, display name, default queue, and default priority — without exposing AI-eligibility or worker-type internals.

Work an AI is holding disappears from human pickup views, and not as a special case: a task an AI holds has a holder, and the readiness rule excludes anything with a holder. Holding is holding.

Completing a task

Completing a task is not a status update. It is a recorded decision, and the platform is strict about it in three separate ways.

The outcome comes from a catalog. Each task type declares its legal outcomes, each with its own requirements: a note, a document, named fields, whether a follow-up is required or forbidden. An outcome that is not in the catalog is not a way to finish.

The catalog is narrowed again by the case’s own flow version. An outcome the pinned version cannot route is refused, and the worker is told which ones it can route, or offered the recovery path instead.

And some outcomes require proof.

None of them can be satisfied by the completion request itself, which is the whole point: the person completing the task cannot also supply the proof that they did it.

An outcome can declare that it claims a real operation — a message actually sent, a promise actually recorded, a governed command the Lending Core actually executed, a compliance decision actually taken, an identity actually verified. Completion then reads the state that other part of the platform wrote as a side effect of the work being done. If it is not there, the completion is refused with a sentence a person can act on: the Lending Core has not reported executing a governed command for this case. Do the work, then complete the task.

The catalog is careful about where it does and does not demand proof. Submitting a refund proves nothing, because submitting is not refunding. Telling a borrower their refund is on its way has an outcome for the case where nothing was sent, and that one proves nothing because nothing happened.

Completion writes the stored fields and evidence, spends the collections treatment decision first, and then re-evaluates the workflow inline. That re-evaluation can walk the case all the way to its ending and close it in the same transaction — which is why any follow-up work is created before the completion rather than after. A follow-up created afterwards would be newly active work on a closed case.

The five commands

Reservation is only the offer. Five commands carry a task the rest of the way, and each records the decision that ended it. The two that look alike are the two most worth keeping apart: release says someone else should do this; cancel says this no longer needs doing. Only release returns the task to queue ranking.

Command Body Permission
POST /tasks/{taskId}/accept None — it accepts the caller’s own live reservation. ACCEPT_SERVICING_TASK
POST /tasks/{taskId}/decline Turns down the caller’s own live offer so it requeues immediately. DECLINE_SERVICING_TASK
POST /tasks/{taskId}/complete outcomeCode required; note, fields, followUp optional. COMPLETE_SERVICING_TASK
POST /tasks/{taskId}/release The full unable/requeue decision. ACCEPT_SERVICING_TASK
POST /tasks/{taskId}/cancel reason required. CANCEL_SERVICING_TASK

Completion carries the evidence the task type demands:

curl -X POST "$BASE/v1/servicing/tasks/2001/complete" \
  -H "Authorization: Bearer $TOKEN" \
  -H "LendEasy-Tenant: demo-lender" \
  -H "Content-Type: application/json" \
  -d '{
    "outcomeCode": "CUSTOMER_REACHED",
    "note": "Customer agreed to a promise to pay.",
    "fields": { "identity_verified": true, "contact_channel": "PHONE" },
    "followUp": { "taskTypeCode": "REVIEW_PROMISE_OUTCOME", "dueDate": "2026-08-02" }
  }'

fields must satisfy the task type’s configured completion-field definitions, so “record whether identity was verified” is enforced by the platform rather than by a client-side form — see Servicing configuration. followUp creates the next task only where policy allows it; it is not a way to invent arbitrary work.

Releasing is not a silent undo. Every field is required, because returning work to a queue is an operational decision that has to be attributable:

{
  "unableReason": "SHIFT_ENDED",
  "note": "Returning unstarted work to the queue.",
  "requeueDecision": "RETURN_TO_QUEUE",
  "createReplacementTask": false,
  "managerReviewRequired": false
}

Cancel is different again: it ends work that has become obsolete — usually because the owning case resolved. Where the workflow required that task, cancelling blocks case progression or creates replacement work rather than quietly removing an obligation.

When it cannot be done

A worker who cannot finish the current step’s work has one honest thing to say, and saying it must not strand the case. So the release is treated as a request for recovery rather than as an ending.

The task is held: it leaves them, nobody else is offered it, and the step still owes the work. Exactly one recovery review is raised, deliberately sent somewhere other than the team that could not finish the job. No replacement is created, because a second copy of work nobody could do is not recovery.

The reviewer says The held work The case
Resume Back to its queue, unassigned Unchanged. The step still owes it.
Hand it on To a named worker or queue Unchanged
Skip the step Withdrawn as superseded Moves to a step this case’s own flow version already routes to, and that step’s entry effects run exactly as the engine would have run them
Close the case Withdrawn Closes through the ordinary guards
Close and continue by hand Withdrawn Closes, and a manual case opens in its place, linked back to it, carrying the supervisor’s checklist

Two properties make this safe to rely on. It is all or nothing: a closure guard that refuses, or a step the flow does not route to, leaves the review and the held work exactly as they were. And destinations are never arbitrary — being present in a definition does not make a step safe to enter from where the case is standing, so the console is handed the legal list up front.

If the world moves past held work, the engine withdraws it and takes its review with it. A review whose subject has moved on is a question nobody can answer.

Moving work to somebody else

Reassignment records source and destination, actor, reason, eligibility result, and service-level impact. GET /v1/servicing/tasks/{taskId}/reassignment-options gives the manager valid destinations first: eligible queues for the task, and under-capacity eligible workers in its current queue. The read requires the same reassign authority as the command, and terminal tasks return empty lists.

POST /v1/servicing/tasks/{taskId}/reassign then moves the work under REASSIGN_SERVICING_TASK:

{
  "targetType": "QUEUE",
  "targetRef": "HARDSHIP",
  "reason": "Specialist queue handling is required."
}
{
  "resourceId": 2001,
  "changes": { "queueCode": "HARDSHIP", "status": "AVAILABLE" }
}

The command revalidates the chosen target rather than trusting the option list — a stale option fails closed. Reassigning to a queue returns the task to AVAILABLE for ranking; it does not hand ownership to a worker who has not reserved it. Escalation is a case control that can create a higher-priority specialist task; it is not a way to bypass permissions or review requirements.

Promised callbacks

These behave differently enough to be worth their own section, and the difference starts with how the promise is understood.

A promise is a window, not an appointment. A borrower who agrees to “around eight tomorrow morning” has agreed to a half hour.

So the task is created immediately, in a scheduled state, with the window’s start as the moment it becomes actionable and the window’s end as the moment the promise is broken. It exists straight away so the case can show it, but it is held out of every pickup view and every capacity count until the window opens.

A window must be between five minutes and two hours, must be in the future, must be within the configured horizon, and requires the borrower’s own time zone — because a promise made without it is a promise made in somebody else’s morning.

A sweep activates due callbacks each minute, flips them to available, and hands them straight to the dispatcher, because the minutes between the window opening and somebody dialling are the borrower’s minutes. The sweep evaluates nothing else: compliance belongs at scheduling, where the proposed window is judged, and at dialling, where the actual moment is. A borrower who asks to be called in the next half hour does not wait for the next tick; that one activates inline.

When nobody can take it

Nothing new is created. The task stays where it is, and the reason nobody could take it is written onto it.

No second escalation task is created. Work nobody can take does not become better staffed by growing an item beside it, and the supervisor who needs to act on it needs the reason, not another row.

The reasons are ranked so that the one naming a staffing or configuration gap wins over the one that merely says people are busy, because that is the one somebody can act on.

Recorded reason What it means
No queue members A configuration defect. Nobody belongs to this queue at all.
Missing permission, or missing sensitive access Also a configuration gap: the people are there but not authorised.
All on a call Voice work, everyone occupied.
All at capacity A staffing decision, not a defect.
All holding an offer Everyone already has something unanswered.
None available Nobody is marked available right now.

It is visible in three places: the team backlog view, a queue coverage report that warns most-actionable-first, and the promise scorecard. The coverage view exists so an unstaffed specialist queue is visible before it quietly holds promises nobody will keep, rather than afterwards. A queue that nothing routes to and nothing sits in reads as unused rather than unstaffed.

Specialist work never falls back to a general queue when its own queue is unstaffed. Falling back would place the work somewhere it would be answered badly.

Escalation is a separate, deliberate act rather than an automatic consequence of being unstaffed. It creates a review at high priority with the target queue as the strongest routing input, and it refuses a queue target that does not exist, is disabled, is the compliance queue, or has nobody eligible in it.

What to watch

Time-to-first-action, deadline misses, reassignments, expired reservations, workload by worker, AI/human fall-through, ranking drift, and subgroup outcomes. Throughput alone rises when the easiest work is taken first, so a queue can look healthier in the same week it starts missing the regulated deadlines that carry real consequences.

Queue position is transient. The lasting proof is the task lifecycle, the decisions, the actions and the case outcome — not a screenshot of a ranked list.

Capacity, reservation windows and offer deadlines come from one platform-wide settings row rather than per-queue switches. A per-queue limit would let one queue quietly opt out of being staffed, which is the failure the whole mechanism exists to prevent.
Unified search across guides, recipes & the API referenceEsc