API Documentation

AI-powered document processing API for developers

Version 1.0 REST API Async Processing Webhooks

Quick Start

1

Get Your API Key

Sign up for a paid plan and generate your API key in the settings page.

2

Submit Your Document

POST your document (base64 or file upload) to the documents endpoint.

3

Get Document ID

Receive a document ID immediately for tracking your submission.

4

Retrieve Results

Poll the status endpoint or use webhooks for completion notifications.

Requirements

  • Paid subscription plan
  • Valid API key
  • Documents in JPEG, PNG, or PDF format
  • Maximum file size: 100MB per document

Submit Document

curl -X POST "https://bankstatementflow.com/api/v1/documents" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "document": "iVBORw0KGgoAAAANSUhEUgAA...",
    "detection_type": "auto"
  }'

Response (Queued)

{
  "success": true,
  "data": {
    "document_id": "doc_abc123def456",
    "status": "queued",
    "estimated_pages": 5,
    "credits_reserved": 5
  }
}

Check Status & Get Results

curl "https://bankstatementflow.com/api/v1/documents/doc_abc123def456" \
  -H "Authorization: Bearer YOUR_API_KEY"

Authentication

The BankStatementFlow API uses API key authentication. Include your API key in the request headers using one of these methods:

Bearer Token (Recommended)

Authorization: Bearer YOUR_API_KEY

Custom Header

X-API-Key: YOUR_API_KEY

API Key Security

  • Keep your API key secure and never share it publicly
  • Use environment variables to store your API key
  • Regenerate your API key if you suspect it has been compromised

API Endpoints

POST /api/v1/documents

Submit a document for processing. Returns immediately with a document ID for tracking.

Request Body (JSON with base64)

Parameter Type Required Description
document string * Base64 encoded document (required if no file upload)
filename string Original filename (optional)
detection_type string * "auto", "custom"
custom_fields array ** Required if detection_type is "custom"
custom_ai_instructions string Additional instructions for AI processing (max 2000 chars)
process_all_pages boolean Process entire document (default: true)
page_start integer Start page (if not processing all pages)
page_end integer End page (if not processing all pages)
webhook_url string URL to receive completion notifications (HTTPS required in production)

Multipart Form-Data Upload

Alternatively, you can upload files using multipart form-data:

curl -X POST "https://bankstatementflow.com/api/v1/documents" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "file=@document.pdf" \
  -F "detection_type=auto" \
  -F "webhook_url=https://example.com/webhook"

Example with Custom Fields

{
  "document": "iVBORw0KGgoAAAANSUhEUgAA...",
  "detection_type": "custom",
  "custom_fields": [
    "invoice_number",
    "vendor_name",
    "total_amount",
    "tax_amount",
    "due_date"
  ],
  "custom_ai_instructions": "Focus on extracting line items from the invoice",
  "webhook_url": "https://example.com/webhook"
}

Response Codes

202 Document accepted and queued for processing
400 Invalid document format or page range
401 Invalid or missing API key
402 Insufficient credits
403 API access requires paid subscription
422 Validation failed
429 Rate limit exceeded
GET /api/v1/documents/{document_id}

Get document status and results

Response (Processing)

{
  "success": true,
  "data": {
    "document_id": "doc_abc123def456",
    "status": "processing",
    "filename": "statement.pdf",
    "detection_type": "auto",
    "created_at": "2025-01-20T10:30:00.000Z",
    "progress": {
      "pages_processed": 2,
      "pages_total": 5
    }
  }
}

Response (Completed)

{
  "success": true,
  "data": {
    "document_id": "doc_abc123def456",
    "status": "completed",
    "filename": "statement.pdf",
    "detection_type": "auto",
    "created_at": "2025-01-20T10:30:00.000Z",
    "result": {
      "extracted_fields": [
        {
          "Date": "10/02",
          "Description": "POS PURCHASE",
          "Debit": "4.23",
          "Credit": "",
          "Balance": "65.73"
        },
        {
          "Date": "10/03",
          "Description": "PREAUTHORIZED CREDIT",
          "Debit": "",
          "Credit": "763.01",
          "Balance": "828.74"
        }
      ],
      "detection_type": "auto",
      "pages_processed": 5
    },
    "usage": {
      "credits_used": 5
    }
  }
}

Document Statuses

queued

Document received and waiting to be processed

processing

Document is currently being processed

completed

Processing complete, results available

failed

Processing failed, credits refunded

GET /api/v1/documents

List your documents (paginated)

Query Parameters

Parameter Type Description
per_page integer Number of documents per page (default: 20, max: 100)
page integer Page number (default: 1)

Response

{
  "success": true,
  "data": [
    {
      "document_id": "doc_abc123def456",
      "filename": "statement.pdf",
      "status": "completed",
      "detection_type": "auto",
      "pages_processed": 5,
      "pages_total": 5,
      "created_at": "2025-01-20T10:30:00.000Z",
      "updated_at": "2025-01-20T10:31:00.000Z"
    },
    {
      "document_id": "doc_xyz789ghi012",
      "filename": "invoice.jpg",
      "status": "processing",
      "detection_type": "custom",
      "pages_processed": 0,
      "pages_total": 1,
      "created_at": "2025-01-20T10:35:00.000Z",
      "updated_at": "2025-01-20T10:35:00.000Z"
    }
  ],
  "pagination": {
    "current_page": 1,
    "total_pages": 3,
    "per_page": 20,
    "total": 45
  }
}
DELETE /api/v1/documents/{document_id}

Delete a document and its results

Response

{
  "success": true,
  "message": "Document deleted successfully"
}

Response Codes

200 Document deleted successfully
404 Document not found
409 Cannot delete document currently being processed

Webhooks

When you provide a webhook_url during document submission, we'll send a POST request to that URL when processing completes or fails.

Webhook Headers

Header Description
X-Webhook-Signature HMAC-SHA256 signature of the payload using your API key
X-Document-Id The document ID for this webhook
Content-Type application/json

Completion Webhook Payload

{
  "event": "document.completed",
  "document_id": "doc_abc123def456",
  "status": "completed",
  "timestamp": "2025-01-20T10:31:00.000Z",
  "result": {
    "extracted_fields": [...],
    "detection_type": "auto",
    "pages_processed": 5
  },
  "usage": {
    "credits_used": 5
  }
}

Failure Webhook Payload

{
  "event": "document.failed",
  "document_id": "doc_abc123def456",
  "status": "failed",
  "timestamp": "2025-01-20T10:31:00.000Z",
  "error": {
    "message": "Failed to process document: Invalid PDF format"
  }
}

Verifying Webhook Signatures

// PHP example
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'];

$expected = hash_hmac('sha256', $payload, $yourApiKey);

if (hash_equals($expected, $signature)) {
    // Signature valid - process webhook
} else {
    // Invalid signature - reject request
}
Webhook Retry Policy

Webhooks are retried up to 3 times with exponential backoff (10 seconds, 1 minute, 5 minutes) if your endpoint returns a 5xx error or times out.

Rate Limits

Per-Plan Limits

All Plans 1,000 requests/hour

Higher Limits Available

Need more than 1,000 requests per hour? Contact us for custom rate limits tailored to your business needs.

Rate Limit Headers

X-RateLimit-Limit

Your hourly rate limit

X-RateLimit-Remaining

Remaining requests this hour

X-RateLimit-Reset

When your limit resets (Unix timestamp)

Error Handling

All API responses include a success field. When an error occurs, the response will include additional error information:

{
  "success": false,
  "message": "Validation failed",
  "error_code": "VALIDATION_ERROR",
  "errors": {
    "document": ["The document field is required."],
    "detection_type": ["The detection type must be auto, custom"]
  }
}

Common Error Codes

  • MISSING_API_KEY - API key not provided
  • INVALID_API_KEY - Invalid API key
  • SUBSCRIPTION_REQUIRED - Paid plan required
  • INSUFFICIENT_CREDITS - Not enough credits
  • RATE_LIMIT_EXCEEDED - Too many requests
  • INVALID_DOCUMENT_FORMAT - Unsupported file format
  • DOCUMENT_NOT_FOUND - Document does not exist
  • INVALID_WEBHOOK_URL - Webhook URL must be HTTPS

Code Examples

JavaScript / Node.js

const fs = require('fs');

// Convert document to base64
const documentBuffer = fs.readFileSync('document.pdf');
const base64Document = documentBuffer.toString('base64');

// Submit document
const submitResponse = await fetch('https://bankstatementflow.com/api/v1/documents', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    document: base64Document,
    detection_type: 'auto',
    webhook_url: 'https://example.com/webhook'
  })
});

const { data } = await submitResponse.json();
console.log('Document ID:', data.document_id);

// Poll for results (or use webhooks)
const checkStatus = async (docId) => {
  const response = await fetch(
    `https://bankstatementflow.com/api/v1/documents/${docId}`,
    { headers: { 'Authorization': 'Bearer YOUR_API_KEY' } }
  );
  return response.json();
};

// Wait for completion
let result;
do {
  await new Promise(r => setTimeout(r, 2000));
  result = await checkStatus(data.document_id);
} while (['queued', 'processing'].includes(result.data.status));

console.log('Results:', result.data.result);

Python

import requests
import base64
import time

API_KEY = 'YOUR_API_KEY'
BASE_URL = 'https://bankstatementflow.com/api/v1'

# Convert document to base64
with open('document.pdf', 'rb') as f:
    document_data = base64.b64encode(f.read()).decode()

# Submit document
response = requests.post(
    f'{BASE_URL}/documents',
    headers={'Authorization': f'Bearer {API_KEY}'},
    json={
        'document': document_data,
        'detection_type': 'custom',
        'custom_fields': ['date', 'amount', 'description']
    }
)

document_id = response.json()['data']['document_id']
print(f'Document ID: {document_id}')

# Poll for results
while True:
    status = requests.get(
        f'{BASE_URL}/documents/{document_id}',
        headers={'Authorization': f'Bearer {API_KEY}'}
    ).json()

    if status['data']['status'] in ['completed', 'failed']:
        break
    time.sleep(2)

print('Results:', status['data'].get('result'))

PHP

$apiKey = 'YOUR_API_KEY';
$baseUrl = 'https://bankstatementflow.com/api/v1';

// Convert document to base64
$documentData = base64_encode(file_get_contents('document.pdf'));

// Submit document
$ch = curl_init("$baseUrl/documents");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer $apiKey",
        'Content-Type: application/json'
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'document' => $documentData,
        'detection_type' => 'auto'
    ])
]);

$response = json_decode(curl_exec($ch), true);
$documentId = $response['data']['document_id'];

// Poll for results
do {
    sleep(2);
    $ch = curl_init("$baseUrl/documents/$documentId");
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER => ["Authorization: Bearer $apiKey"]
    ]);
    $status = json_decode(curl_exec($ch), true);
} while (in_array($status['data']['status'], ['queued', 'processing']));

print_r($status['data']['result']);

cURL

# Submit document
DOCUMENT_BASE64=$(base64 -i document.pdf)

RESPONSE=$(curl -s -X POST "https://bankstatementflow.com/api/v1/documents" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{
    \"document\": \"$DOCUMENT_BASE64\",
    \"detection_type\": \"auto\"
  }")

DOC_ID=$(echo $RESPONSE | jq -r '.data.document_id')
echo "Document ID: $DOC_ID"

# Check status
curl "https://bankstatementflow.com/api/v1/documents/$DOC_ID" \
  -H "Authorization: Bearer YOUR_API_KEY"

Need Help?

Our team is here to help you integrate with our API successfully.

Get Support

Questions about API integration, troubleshooting, or custom solutions? We're here to help.

Contact Support