Bulk Ingest API
Upload multiple documents in a single request. The ingest endpoint handles file upload, automatic deal matching, document classification, and queues all files for processing through the analysis pipeline. Use batch status polling or callbacks to track completion.
Include an Idempotency-Key header to safely retry failed uploads without creating duplicate batches.
Bulk Ingest
Uploads one or more files and associates them with a deal. If the deal does not exist, it is created automatically based on the provided matching criteria. Each file is queued for OCR, classification, extraction, and analysis.
| Name | Type | Required | Description |
|---|---|---|---|
| files[] | file | Required | One or more PDF files to upload (multipart form field) |
| metadata | object | Required | JSON object with deal matching, callback config, and file labels |
| metadata.deal_matching | object | Required | Criteria for matching or creating a deal |
| metadata.deal_matching.business_name | string | Optional | Business name to match against existing deals |
| metadata.deal_matching.external_reference | string | Optional | External reference ID (e.g. CRM record ID) |
| metadata.deal_matching.ein | string | Optional | Employer Identification Number for matching |
| metadata.callback | object | Optional | Callback configuration for batch completion notification |
| metadata.callback.url | string | Optional | HTTPS URL to receive the completion callback |
| metadata.callback.secret | string | Optional | Secret for HMAC-SHA256 signature verification |
| metadata.labels | object | Optional | Map of filename to human-readable label |
| Idempotency-Key | string | Optional | Unique key to prevent duplicate batch creation (header) |
curl -X POST https://api.banklyze.com/v1/ingest \
-H "Authorization: Bearer bkz_live_abc123" \
-H "Idempotency-Key: batch-2025-11-01-acme" \
-F 'files[]=@acme_oct_2025.pdf' \
-F 'files[]=@acme_sep_2025.pdf' \
-F 'files[]=@acme_aug_2025.pdf' \
-F 'metadata={
"deal_matching": {
"business_name": "Acme Trucking LLC",
"external_reference": "CRM-4821"
},
"callback": {
"url": "https://yourapp.com/webhooks/banklyze",
"secret": "whsec_abc123def456"
},
"labels": {
"acme_oct_2025.pdf": "October 2025 Statement",
"acme_sep_2025.pdf": "September 2025 Statement",
"acme_aug_2025.pdf": "August 2025 Statement"
}
};type=application/json'{
"data": {
"batch_id": "batch_01JDKF9X2M3N4P5Q6R7S8T9U",
"deal_id": 42,
"deal_matched": true,
"match_method": "business_name",
"files": [
{
"filename": "acme_oct_2025.pdf",
"document_id": 187,
"label": "October 2025 Statement",
"status": "queued",
"size_bytes": 245120
},
{
"filename": "acme_sep_2025.pdf",
"document_id": 188,
"label": "September 2025 Statement",
"status": "queued",
"size_bytes": 198400
},
{
"filename": "acme_aug_2025.pdf",
"document_id": 189,
"label": "August 2025 Statement",
"status": "queued",
"size_bytes": 312576
}
],
"created_at": "2025-11-01T14:30:00Z"
}
}Metadata structure
The metadata JSON controls deal matching behavior and optional callback delivery. The deal is matched first by external_reference, then by ein, then by business_name. If no match is found, a new deal is created.
{
"deal_matching": {
"business_name": "Acme Trucking LLC",
"external_reference": "CRM-4821",
"ein": "123456789"
},
"callback": {
"url": "https://yourapp.com/webhooks/banklyze",
"secret": "whsec_abc123def456"
},
"labels": {
"acme_oct_2025.pdf": "October 2025 Statement",
"acme_sep_2025.pdf": "September 2025 Statement"
}
}Callback payload
When all documents in the batch finish processing, the callback URL receives a POST with the following payload. The request includes an X-Banklyze-Signature header for verification.
{
"event": "batch.completed",
"batch_id": "batch_01JDKF9X2M3N4P5Q6R7S8T9U",
"deal_id": 42,
"timestamp": "2025-11-01T14:32:45Z",
"data": {
"total_documents": 3,
"completed": 3,
"failed": 0,
"recommendation": {
"decision": "approved",
"health_score": 74.2,
"grade": "B",
"ruleset_id": 1,
"ruleset_name": "Standard MCA"
}
}
}Batch Status
Returns the current status of a batch, including per-document processing status and the underwriting recommendation summary when all documents have completed.
| Name | Type | Required | Description |
|---|---|---|---|
| batch_id | string | Required | The batch ID returned from the ingest endpoint |
curl https://api.banklyze.com/v1/ingest/batches/batch_01JDKF9X2M3N4P5Q6R7S8T9U \
-H "Authorization: Bearer bkz_live_abc123"{
"data": {
"batch_id": "batch_01JDKF9X2M3N4P5Q6R7S8T9U",
"deal_id": 42,
"status": "completed",
"created_at": "2025-11-01T14:30:00Z",
"completed_at": "2025-11-01T14:32:45Z",
"documents": [
{
"document_id": 187,
"filename": "acme_oct_2025.pdf",
"label": "October 2025 Statement",
"status": "completed",
"document_type": "bank_statement",
"period": "2025-10",
"transaction_count": 142
},
{
"document_id": 188,
"filename": "acme_sep_2025.pdf",
"label": "September 2025 Statement",
"status": "completed",
"document_type": "bank_statement",
"period": "2025-09",
"transaction_count": 128
},
{
"document_id": 189,
"filename": "acme_aug_2025.pdf",
"label": "August 2025 Statement",
"status": "completed",
"document_type": "bank_statement",
"period": "2025-08",
"transaction_count": 156
}
],
"recommendation": {
"decision": "approved",
"health_score": 74.2,
"grade": "B",
"ruleset_id": 1,
"ruleset_name": "Standard MCA",
"factor_scores": {
"revenue_stability": 82,
"average_daily_balance": 71,
"deposit_consistency": 76,
"nsf_frequency": 65,
"negative_days": 58,
"high_risk_transactions": 90
}
}
}
}