Dispatch Nova on a call
Create a voice dispatch for one eligible task, watch the dial get authorized at the last possible moment, and map the closed disposition to typed servicing records.
Nova holds no standing dial permission. Every call starts as a dispatch for one eligible task, gets authorized immediately before dial, and ends as a closed, typed disposition — three contracts, in order.
Create the dispatch
One task, one callcurl -X POST "$BASE/v1/servicing/voice-dispatches" \
-H "Authorization: Bearer $TOKEN" \
-H "LendEasy-Tenant: demo-lender" \
-H "Idempotency-Key: dispatch-2001-2027-05-01" \
-H "Content-Type: application/json" \
-d '{ "taskId": 2001 }'{ "dispatchId": 6001, "taskId": 2001, "workerCode": "COLLECTIONS_VOICE_PRIMARY", "status": "CREATED" }The dispatch is refused outright if the task isn’t voice-eligible, the worker isn’t registered for the queue, or channel policy already rules the contact out. Creation assembles Nova’s signed work packet — destination, purpose, scripts, allowed facts, tools, autonomy ceiling, stop conditions — and binds a task token to this dispatch alone.
Authorize the dial — at the moment of dial
Connector contractcurl -X POST "$BASE/v1/servicing/voice-dispatches/6001/dial-authorization" \
-H "X-LendEasy-Voice-Task-Token: $DISPATCH_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "requestedAt": "2027-05-01T10:12:00-07:00" }'{
"decision": "ALLOWED",
"disclosureVersion": "collections-us-v4",
"scriptVersion": "first-party-cure-v8",
"expiresAt": "2027-05-01T17:14:00Z"
}This is a connector callback under the dispatch-bound token, not a bearer-token human API. Policy is evaluated against current facts — consent, local time, contact budget, restrictions, the particular debt — seconds before the provider is invoked. A block returns the decision with its reasons and no dial occurs; the authorization expires quickly so a stale one cannot be redeemed later.
Submit the closed disposition
Typed outcomescurl -X POST "$BASE/v1/servicing/voice-dispatches/6001/disposition" \
-H "X-LendEasy-Voice-Task-Token: $DISPATCH_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"outcomeCode": "PROMISE_TO_PAY",
"connectedAt": "2027-05-01T10:12:31-07:00",
"endedAt": "2027-05-01T10:19:05-07:00",
"commitments": [
{ "amount": { "amount": 260.00, "currency": "USD" }, "dueDate": "2027-05-08" },
{ "amount": { "amount": 257.14, "currency": "USD" }, "dueDate": "2027-05-22" }
],
"providerCallRef": "call-8f31c2"
}'{
"dispatchId": 6001,
"status": "DISPOSITIONED",
"effects": {
"interactionId": 3001,
"promiseProposalRef": "5001",
"followUpTaskId": 2003
}
}The disposition is a closed contract: it maps the conversation to interaction, case, task, consent, promise, payment, and handoff effects — it cannot invent arbitrary effect types or approval inputs, and replay under the same token is idempotent. The conversation itself authorized nothing; each resulting record runs its own guardrails.