Skip to main content
Send the list to POST /customers/batch with scheduleMode: "enroll". Finosu stores the upload, divides it into internal chunks, and enrolls each application using the same cadence and validation rules as individual enrollment. Your integration does not need to make one request per CSV row. Use one company API key per list. That key selects the company and its configured portfolio; body fields cannot select a different company or enable another cadence.

Send a list

Use a stable Idempotency-Key header for the whole list and a stable idempotencyKey in each row for that enrollment operation. These are different keys with different purposes. Keep customer and application references consistent with previous CSV uploads.
The example combines two modes. Each must be enabled for the authenticated company. Unsupported modes fail for the affected rows; they do not enable new portfolio capabilities. Returning borrowers without oneOff can include daysSincePaidOff for the existing returning cadence. Row fields follow the enrollment field contract, plus the required idempotencyKey. Row-level scheduleMode can be omitted; if present it must be "enroll". The outer scheduleMode is always required. Send isTest for test enrollments. The legacy test field is deprecated and removed on 25 October 2026, the same deadline as customer creation and single enrollment. Either spelling is accepted until then; conflicting values or explicit null flags fail only the affected row. Omitting both defaults to false.
Always send the outer scheduleMode: "enroll". The existing customer-create workflow uses this URL without a mode. Enrollment row keys without the outer mode are rejected to prevent accidental customer-create processing.
See Batch API reference for the shared request schema and playground.

Acceptance and progress

A successful submission returns HTTP 202, Location, and a job ID:
Poll the Location URL with the same company’s API key. Start with a few seconds between polls and increase the interval for longer-running jobs.
The batch status endpoint returns:
  • status: pending, processing, completed, failed, or cancelled.
  • processed: successfully handled rows, including saved receipt replays and applications that were already scheduled.
  • failed: rejected rows or rows that exhausted processing retries.
  • progressPercentage: handled rows divided by the submitted count.
  • results: outcomes ordered by the original zero-based index. Each includes customerId, loanId, status, replayed, and retryable. Successful rows include the origination receipt; failures include code and message.
  • failures: the failed rows with their original index, customer reference, and message, for compatibility with existing batch clients.
Results appear as rows finish. A terminal completed job can have failed rows when at least one row succeeded; always inspect failed and results. A job with no successful rows ends as failed. A failure before the source can be read may have empty customer/application references; its original index still identifies the row in your submitted list. A saved schedule does not mean a call has connected. Use the receipt’s scheduledCallId to inspect the current call status. Receipts are scheduling snapshots, not current borrower eligibility.

Retry without duplicate enrollments

  • Submission timeout or 503: retry the identical ordered list with the same header key. If accepted previously, the same job is returned with Idempotency-Replayed: true. A changed list under that key returns 409. JSON object-key order is ignored; array order and submitted values must match.
  • Worker interruption: Finosu resumes processing and skips committed row results. Enrollment and its result are committed together.
  • Retryable failed row: submit that row in a new list with a new header key, retaining its original row idempotencyKey and payload. Replaying a terminal list returns the existing job; it does not restart failed rows.
  • Invalid row: correct the data and submit a new list. A rejected validation does not consume an enrollment receipt. If a key has already produced a saved receipt, changing its enrollment payload returns a conflict.
  • Contact or application conflict: review the reason before resubmitting. Enrollment cannot clear DNC or restart a finished/paused cadence.
Row keys share the individual enrollment key namespace within the company. A row submitted through batch and the single-record endpoint with the same key and normalized enrollment fields returns the same enrollment receipt. Use a separate row key for each distinct enrollment operation; do not reuse it for unrelated customers or applications.

Limits and processing behavior

  • Up to 10,000 records per request and 10 MiB of serialized customer data. Split larger lists into multiple batches with separate header keys.
  • Up to 10 batch submissions per minute per company, including submission retries. Honor Retry-After on 429 and 503.
  • Finosu processes internal chunks of 25 records in the background. The single-record endpoint’s 60-request/minute quota does not apply per batch row.
  • Rows and chunks can finish out of order. The list is not one transaction: valid rows can succeed while others fail. Do not depend on list order to apply multiple changes to the same customer.
  • Invalid envelopes return 422 before queuing. Oversized customer data returns 413. Invalid enrollment fields, disabled modes and application conflicts are reported per row after acceptance.
  • The normal scheduler still enforces contact restrictions, calling hours, phone rotation and the configured transfer routing. Batch intake does not change those settings or imply immediate calls.
Batch enrollment does not replace the funded/stop workflow or enable LMS notes and flags. See funded applications.