scheduleMode: "enroll" to the existing schedule-sync endpoint. Send one
application per request here. For a whole list, use batch enrollment. The company associated with your X-API-Key determines
which task types and cadences are available; contact your account manager to
confirm the supported modes.
Omitting scheduleMode, or setting it to "replace", retains the existing
Sync Customer Schedules behavior.
Enrollment does not cancel other calls, emails, or SMS. A different loanId
creates a separate application for the same customer, even when an older
application is still pending. Conflicts on the requested application and customer
contact restrictions still return 409 for review.
This guide covers enrollment only. For the shared request/response schema and API
playground, see Sync Customer Schedules.
For complete requests for each mode, see Origination Examples.
Supported task types
Origination enrollment (scheduleMode: "enroll") supports exactly two
taskType values. Use the case-sensitive values shown below.
Use List Task Types (GET /origination/task-types)
to retrieve these values programmatically.
The selected task type must be enabled for the company associated with your
X-API-Key. A supported task type that is not enabled for your company returns
400. Contact your account manager to confirm availability.
For a single returning-borrower call, use PendingLoanReturning with
oneOff: true; this is an option, not a separate task type. See
Cadences for scheduling behavior.
Example
Returning customers and new applications
id identifies the customer in your account; loanId identifies the application.
Keep the customer id stable when the same person applies again. Send the new
application’s distinct loanId with a new Idempotency-Key and the required
customer fields. This applies to both supported task types and batch enrollment.
PendingLoanNewLead describes the outreach mode; it does not require a customer
who has never existed in Finosu.
For example, customer
customer-1001 can have application-1001 still pending
and enroll application-1002 independently. Do not close the older application
merely to enroll the new one. Report its actual final outcome separately through
POST /originations/{id}/close, using that application’s reference.
Loan reference ownership is scoped to the loan portfolio’s company. Loans explicitly
marked as test loans do not reserve real application references and are excluded
from the close API. An existing test loan on the same
customer is never converted into a real application by submitting it again. The API
customer test flag remains a separate setting with its existing validation.
Customer data remains shared: creating a new application can update the existing
customer’s supplied profile/contact fields through normal enrollment. It does not
create another customer or remove contact restrictions. Each new cadence uses
its own submitted call-plan inputs; older scheduled tasks are not rebuilt.
Call eligibility and spacing continue to apply across the customer’s applications.
Separate enrollment does not grant permission for simultaneous calls or bypass
Do Not Call, calling hours, contact breaks, or capacity checks. A saved cadence
is not a guarantee of immediate dialing. Completing all call attempts does not
itself mark an application funded, withdrawn, or rejected.
Fields
Use strings for customer references, application references, ZIP codes, and SSN suffixes to preserve leading zeroes. Send birthdays asYYYY-MM-DD. Only the last
four SSN digits are needed; do not send a full SSN.
Omit optional values you do not have. Optional contact fields and the two
cadence-age fields accept
null; oneOff, isTest, and sync do not. Send the
age fields as JSON integers, not strings, fractions, or booleans. Unrecognized
fields are rejected rather than ignored.
Both supplied phone numbers must have 10 digits, or 11 digits beginning with
1; the API normalizes them to +1…. This validates format, not whether a number
is assigned or reachable. An invalid mobile number produces an error instead of
silently changing the call plan. sync: true and nonempty externalMetadata are
not supported in enrollment mode; send the explicit fields above.
Enrollment preserves existing contact restrictions. It cannot remove a Do Not
Call restriction through doNotCall: false; doNotCall: true is also rejected.
Cadences
A matching active cadence with a pending or in-progress call is returned as
already_scheduled without changing borrower data or resetting its progress.
The application reference, customer, company, and outreach mode must match;
switching between returning and one-off is not an update to an existing cadence.
For both New Lead and Returning Customer, a new idempotency key can restart
fully exhausted outreach only when both the loan and captured application are
still PENDING. Every previous call must be completed or failed, with no queued,
claimed, active, cancelled, or compliance-suppressed work. Call post-processing
must also be finished before a new cadence can start. Contact restrictions,
paused/cancelled cadences, unknown state, and inconsistent identity block restart.
FUNDED, WITHDRAWN, and REJECTED are never reopened, even if the other record
still says PENDING.
The restart creates a new schedule from step zero for the same application and
outreach mode, preserving previous calls and receipts. Returning cadences with
daysSincePaidOff start the complete configured cadence from the new start date;
the supplied payoff-age information remains unchanged. Returning without that
field and explicit oneOff retain their existing single-initial-call behavior.
A retry using the original key always replays its original receipt, even after
outreach has finished. CSV reuploads do not acquire this API restart behavior.
Use Update a Customer for supported
profile changes such as the primary phoneNumber, email, or timezone. That
operation does not update mobilePhone, cadence-age fields, or oneOff, and it
does not rebuild the call plan. Coordinate changes to those fields separately.
Retries
Idempotency-Key is required only for scheduleMode: "enroll". Use a stable,
non-sensitive identifier of 1–128 characters: letters, digits, ., _, :, or
-. Keep the same key and payload when retrying after a timeout or network error.
- The same company, key, and normalized payload return the saved enrollment receipt, even after the cadence finishes or is cancelled.
- Reusing a key with a different payload returns
409. - A different key for the same active application returns
already_scheduled. - An in-progress request returns
409withRetry-After; retry the original key. - Keys are scoped to the company associated with the API key.
Retry-After
on 429 and 503 responses and retry with exponential backoff and jitter.
Response
Responses use HTTP200. The top-level customer fields are built from the
normalized request, with two exceptions: phoneNumber falls back to mobilePhone
when no primary number is supplied, and doNotCall is always returned as false.
These fields are not a read of the current customer record. In particular,
already_scheduled does not persist submitted contact changes, and doNotCall
does not prove the customer is currently callable, including on a replay. Use
Retrieve a Customer for the customer fields that
operation exposes, and scheduled-call status for current scheduling state.
Enrollment also returns mobilePhone, middleName, the schedule counters, and
an origination receipt. Optional response fields can be null. The following
is the scheduling portion of the response, not the complete customer response:
Idempotency-Replayed: true identifies a replay. Its counters describe the
original enrollment, not newly created calls. A newly submitted key returning
already_scheduled has scheduleCreated: false and tasksCreated: 0.
scheduledCallCount is the total number of nondeleted calls in the saved cadence,
not the number of remaining attempts.
Location points to /scheduled-calls/{scheduledCallId}. Use the scheduled
call detail endpoint to
track current status; the enrollment receipt is a snapshot.
Errors
Enrollment validation, conflict, and quota errors have a structureddetail:
detail.code to distinguish request_in_progress from other 409 conflicts.
Authentication errors may instead contain a plain-string detail; do not assume
every error has the enrollment shape. Invalid fields return sanitized messages
without echoing the submitted identity values.