> ## Documentation Index
> Fetch the complete documentation index at: https://parse-docs.pantherpulse.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Batch Extract

> Upload bank statements for extraction and analysis

# Batch Extract

Upload PDF bank statements for processing. Parse will extract transactions, analyze patterns, detect anomalies, and return detailed financial insights.

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST https://parse.pantherpulse.ai/v1/extract/batch \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -F "file=@statement1.pdf" \
    -F "file=@statement2.pdf" \
    -F "user_id=ppu_YOUR_USER_ID" \
    -F "company_name=acme-corp"
  ```

  ```python Python theme={null}
  import requests

  api_key = "YOUR_API_KEY"
  user_id = "ppu_YOUR_USER_ID"

  with open("statement.pdf", "rb") as f:
      files = [("file", f)]
      data = {
          "user_id": user_id,
          "company_name": "acme-corp"
      }
      headers = {"Authorization": f"Bearer {api_key}"}
      
      response = requests.post(
          "https://parse.pantherpulse.ai/v1/extract/batch",
          files=files,
          data=data,
          headers=headers
      )
      print(response.json())
  ```

  ```javascript JavaScript theme={null}
  const axios = require('axios');
  const FormData = require('form-data');
  const fs = require('fs');

  const form = new FormData();
  form.append('file', fs.createReadStream('statement.pdf'));
  form.append('user_id', 'ppu_YOUR_USER_ID');
  form.append('company_name', 'acme-corp');

  const headers = {
    ...form.getHeaders(),
    'Authorization': 'Bearer YOUR_API_KEY'
  };

  axios.post(
    'https://parse.pantherpulse.ai/v1/extract/batch',
    form,
    { headers }
  ).then(res => console.log(res.data));
  ```
</RequestExample>

## Request

### Path

`POST /v1/extract/batch`

### Headers

| Header        | Type   | Required | Description                         |
| ------------- | ------ | -------- | ----------------------------------- |
| Authorization | string | Yes      | Bearer token: `Bearer YOUR_API_KEY` |
| Content-Type  | string | Yes      | `multipart/form-data`               |

### Body

| Field         | Type    | Required | Description                                   |
| ------------- | ------- | -------- | --------------------------------------------- |
| file          | file(s) | Yes      | PDF files (1-20 per request, max 4.5MB total) |
| user\_id      | string  | Yes      | Your Pantherpulse user ID                     |
| company\_name | string  | Yes      | Company name for organization                 |

### Limits

* **Max files per request**: 20
* **Max total size**: 4.5MB
* **File format**: PDF only
* **Pages consumed**: One per page in PDF (tracked against your quota)

## Response

<ResponseExample>
  ```json Success - Processing Started theme={null}
  {
    "client": "ppu_abc123",
    "total_files": 2,
    "jobs": [
      {
        "job_id": "job_20251022_143022_a1b2c3",
        "company": "acme-corp",
        "filename": "statement1.pdf",
        "status": "processing"
      },
      {
        "job_id": "job_20251022_143022_d4e5f6",
        "company": "acme-corp",
        "filename": "statement2.pdf",
        "status": "processing"
      }
    ]
  }
  ```

  ```json Error - Invalid File theme={null}
  {
    "error": {
      "code": "invalid_content_type",
      "message": "Content-Type must be multipart/form-data"
    }
  }
  ```

  ```json Error - No Files theme={null}
  {
    "error": {
      "code": "no_files",
      "message": "No files provided"
    }
  }
  ```

  ```json Error - Quota Exceeded theme={null}
  {
    "error": {
      "code": "limit_exceeded",
      "message": "Monthly limit of 250 pages exceeded. Upgrade your plan."
    }
  }
  ```
</ResponseExample>

### Success Response (200)

| Field            | Type   | Description                    |
| ---------------- | ------ | ------------------------------ |
| client           | string | Your user ID                   |
| total\_files     | number | Number of files uploaded       |
| jobs             | array  | Array of job objects           |
| jobs\[].job\_id  | string | Unique identifier for this job |
| jobs\[].company  | string | Company name from request      |
| jobs\[].filename | string | Original filename              |
| jobs\[].status   | string | Always `processing` on upload  |

### Processing Results

Once processing completes, results are stored and can be retrieved. The processed data includes:

```json theme={null}
{
  "status": "auto_analyzed",
  "data": {
    "bank_name": "UOB",
    "account_number_last_4": "5678",
    "statement_start_date": "2025-10-01",
    "statement_end_date": "2025-10-31",
    "opening_balance": 15000.00,
    "end_month_balance": 18500.00,
    "total_deposits": 8500.00,
    "total_withdrawals": 5000.00,
    "daily_average_balance": 17250.00,
    "deposit_count": 12,
    "withdrawal_count": 8,
    "transaction_count": 20,
    "balance_equation_valid": true,
    "balance_equation_variance": 0.00,
    "is_multi_month": false,
    "months_covered": ["2025-10"],
    "negative_balance_count": 0,
    "negative_balance_dates": [],
    "recurring_debits": [
      {
        "creditor": "SUBSCRIPTION SERVICE",
        "count": 4,
        "total_amount": 200.00,
        "individual_amounts": [50.00, 50.00, 50.00, 50.00],
        "transaction_dates": ["2025-10-05", "2025-10-12", "2025-10-19", "2025-10-26"]
      }
    ],
    "large_transactions": [
      {
        "date": "2025-10-15",
        "type": "deposit",
        "amount": 75000.00,
        "description": "WIRE TRANSFER",
        "reason": "Large deposit"
      }
    ],
    "loans_detected": false,
    "loan_transactions": [],
    "loan_commitments": [],
    "intra_company_transactions": []
  }
}
```

## Analysis Features

### Transaction Extraction

* All transactions parsed with date, amount, description, and balance
* Handles deposits, withdrawals, and balance calculations
* Multi-page statements processed in parallel

### Financial Summary

* Opening and closing balances
* Total deposits and withdrawals
* Daily average balance calculation
* Deposit and withdrawal counts
* Balance equation validation (opening + deposits - withdrawals = closing)

### Pattern Detection

* **Recurring debits**: Identifies recurring payments and subscriptions
* **Large transactions**: Flags deposits >50K or >1.5x monthly average
* **Negative balances**: Detects overdraft dates
* **Multi-month statements**: Identifies statements spanning multiple months

### Risk & Compliance

* **Loan detection**: Identifies loan disbursements and payments
* **Intra-company transfers**: Detects internal transfers and group transactions
* **Anomalies**: Flags unusual transaction patterns

## Error Codes

| Code                   | Status | Meaning                                  |
| ---------------------- | ------ | ---------------------------------------- |
| invalid\_api\_key      | 401    | Invalid or missing API key               |
| invalid\_content\_type | 400    | Content-Type must be multipart/form-data |
| no\_files              | 400    | No files provided in request             |
| too\_many\_files       | 400    | Exceeded max 20 files per request        |
| payload\_too\_large    | 400    | Total payload exceeds 4.5MB limit        |
| company\_mismatch      | 400    | Company names count doesn't match files  |
| limit\_exceeded        | 402    | Monthly quota exceeded                   |

## Page Usage

Each page of every uploaded PDF consumes 1 page from your monthly quota. For example:

* 1 × 5-page statement = 5 pages consumed
* 3 × 10-page statements = 30 pages consumed

Pages reset on the 1st of each month. Check your remaining quota with [GET /v1/usage](/api-reference/usage).

## Processing Time

Typical processing times:

* **1-3 pages**: 15-30 seconds
* **4-10 pages**: 30-60 seconds
* **11+ pages**: 60+ seconds (parallel processing)

Results are available via the job IDs returned in the response.
