Batch Import
Upload many leads at once, then follow processing by polling or webhook.
Batch import is the Direct integration for many leads at once. You upload a file or a JSON list, FincheckEngine queues it straight away, and each row is processed in the background exactly like a single lead.
See POST /api/v2/lead/batch in the API Reference →
Before you begin
- Each row uses the same fields and rules as Sending a Lead.
- A batch can hold up to 2,000 rows by default. Contact support if you need a different limit.
- You choose one intent for the whole batch.
1. Prepare the CSV
The first row holds the field names. Each following row is one applicant:
first_name,last_name,cell_phone_number,email,id_number,popi,gross_income,net_income,loan_amount_required
Thabo,Molefe,0821234567,thabo.molefe@example.com,8001015009087,true,25000,18000,5000
Lerato,Dlamini,0839876543,lerato.dlamini@example.com,9001014800089,true,32000,24000,8000
Use commas or semicolons as separators. XLSX and XLS files are also accepted, but CSV is the most portable. The sample at the bottom of this page has every supported heading.
2. Upload the file
curl -X POST "https://your-api-origin/api/v2/lead/batch" \
-H "Authorization: Bearer fce_your_key" \
-H "Accept: application/json" \
-F "leads=@lead-batch.csv;type=text/csv" \
-F "intent=Personal Loans"
Let your HTTP client set the multipart boundary. Do not set Content-Type: multipart/form-data yourself.
3. Store the batch id
An accepted upload returns HTTP 202:
{
"batch_id": 1842,
"status": "queued",
"total_rows": 2
}
4. Check the status
Poll with the same key that uploaded the batch:
curl "https://your-api-origin/api/v2/lead/batch/1842" \
-H "Authorization: Bearer fce_your_key" \
-H "Accept: application/json"
{
"batch_id": 1842,
"status": "completed",
"accepted": 1,
"rejected": 1,
"duplicate": 0,
"error_count": 0,
"processed": 2,
"total_rows": 2,
"webhook_status": "skipped",
"results": [
{ "row": 0, "status": "created", "id": "k3mN9pQx", "lead_state": "dispatched" },
{ "row": 1, "status": "rejected", "errors": { "id_number": "must be a valid RSA ID number" } }
]
}
Poll every 30 seconds or so, and stop when status is completed or failed.
Batch states
Row results
row is the zero-based position of the data row, so the first row after the headings is 0. results lists the first 500 rows. The counters always cover the whole batch.
Completion webhook
Add result_url to receive the final status instead of polling:
-F "result_url=https://your-server.example.com/webhooks/fincheck/batches"
When the batch finishes, FincheckEngine sends a POST with a JSON body identical to the status response above.
- Respond with any
2xxstatus within 10 seconds. Do the processing after you respond. - A failed delivery is retried twice in quick succession. After that,
webhook_statusisfailed. - The request is not signed. Treat it as a signal, and confirm the result by calling
GET /lead/batch/{id}.
webhook_status is pending, sent, failed, or skipped (no result_url). Polling always works, with or without a webhook.
JSON batches
You can send the batch as JSON instead of a file:
{
"intent": "Personal Loans",
"result_url": "https://your-server.example.com/webhooks/fincheck/batches",
"leads": [
{
"first_name": "Thabo",
"last_name": "Molefe",
"cell_phone_number": "0821234567",
"id_number": "8001015009087",
"popi": true
}
]
}
A batch-level partner_ids applies only to rows that do not have their own.
Troubleshooting
To check on a batch, poll its existing batch_id. Uploading the same file again only produces duplicate rows.