REST API v1

Developer API

Convert bank statement PDFs to structured CSV and JSON data programmatically. Built for accounting platforms, fintech apps, and data pipelines.

How It Works

1

Get an API Key

Create an account and generate an API key from the dashboard.

2

Upload PDF

Send your bank statement PDF via the upload endpoint.

3

Convert

Start conversion — AI extracts every transaction with high accuracy.

4

Download

Retrieve structured data as CSV or JSON.

Authentication

All API requests require an API key sent in the X-API-Key header.

Base URL

https://api.bank-statements.co/api/v1

Example Request

curl -H "X-API-Key: bsco_YOUR_API_KEY" \
  https://api.bank-statements.co/api/v1/balance

Key security: API keys are hashed with SHA-256 before storage. The full key is only shown once at creation. Keep it secret — anyone with your key can access your account.

API Endpoints

GET /balance

Returns your current credit balance with a per-purchase breakdown including expiry dates.

Example response
{
  "status": "success",
  "data": {
    "total_credits": 288,
    "records": [
      {
        "balance": 149,
        "purchase_date": "2024-06-14 14:17:06",
        "expiry_date": "2028-10-27 23:07:52"
      }
    ]
  }
}
GET /files

List all your uploaded files with their conversion status, page count, and output locations.

Example response
{
  "status": "success",
  "data": [
    {
      "filename": "user_abc123.pdf",
      "original_filename": "jan-2024-statement.pdf",
      "pages": 5,
      "uploaded_at": "2024-06-14 14:17:06",
      "is_converted": true,
      "csv_location": "csv/user_abc123.csv",
      "json_location": "json/user_abc123.json"
    }
  ]
}
POST /upload

Upload a PDF bank statement. Send as multipart/form-data with the file in the file field. Max 50MB.

Example
# Request
curl -X POST -H "X-API-Key: bsco_YOUR_KEY" \
  -F "file=@statement.pdf" \
  https://api.bank-statements.co/api/v1/upload

# Response
{
  "status": "success",
  "data": {
    "filename": "user_a1b2c3d4.pdf",
    "original_filename": "statement.pdf",
    "pages": 12
  }
}
POST /convert/{filename}

Start converting a PDF. Costs 1 credit per page. The conversion runs in the background — poll the status endpoint to check progress.

Example response
{
  "status": "success",
  "data": {
    "filename": "user_a1b2c3d4.pdf",
    "total_pages": 12,
    "credits_used": 12,
    "conversion_status": "processing"
  }
}
GET /convert/{filename}/status

Check conversion progress. Poll this endpoint every 3-5 seconds until conversion_status is completed or failed.

Example response
{
  "status": "success",
  "data": {
    "conversion_status": "processing",
    "current_page": 7,
    "total_pages": 12
  }
}
GET /download/{filename}?format=csv|json

Download a converted file. Returns a pre-signed download URL valid for 1 hour. Default format is csv.

Example response
{
  "status": "success",
  "data": {
    "download_url": "https://s3.amazonaws.com/...",
    "format": "csv",
    "expires_in": 3600
  }
}
DELETE /files/{filename}

Delete an uploaded file and all its conversions from S3 and the database. This action is irreversible.

Example response
{
  "status": "success",
  "data": {
    "filename": "user_a1b2c3d4.pdf",
    "deleted": true
  }
}

Error Handling

The API uses standard HTTP status codes. Errors return a JSON body with a detail field.

Status Meaning
200Success
400Bad request (invalid PDF, missing params)
401Invalid or missing API key
402Insufficient credits
404File not found
429Rate limit exceeded (60 req/min per key)
500Server error

Rate Limits & Quotas

Limit Value
API requests60 per minute per API key
Concurrent conversions3 per user
Max file size50 MB
Conversion timeout30 minutes
API keys per account5
Download URL expiry1 hour

Complete Example: Upload, Convert & Download

import requests
import time

API_KEY = "bsco_YOUR_API_KEY"
BASE_URL = "https://api.bank-statements.co/api/v1"
HEADERS = {"X-API-Key": API_KEY}

# 1. Check balance
balance = requests.get(f"{BASE_URL}/balance", headers=HEADERS).json()
print(f"Credits available: {balance['data']['total_credits']}")

# 2. Upload a PDF
with open("bank_statement.pdf", "rb") as f:
    upload = requests.post(
        f"{BASE_URL}/upload",
        headers=HEADERS,
        files={"file": ("statement.pdf", f, "application/pdf")}
    ).json()

filename = upload["data"]["filename"]
pages = upload["data"]["pages"]
print(f"Uploaded: {filename} ({pages} pages)")

# 3. Start conversion
convert = requests.post(
    f"{BASE_URL}/convert/{filename}",
    headers=HEADERS
).json()
print(f"Conversion started, using {convert['data']['credits_used']} credits")

# 4. Poll until complete
while True:
    status = requests.get(
        f"{BASE_URL}/convert/{filename}/status",
        headers=HEADERS
    ).json()

    progress = status["data"]
    print(f"  Progress: {progress['current_page']}/{progress['total_pages']}")

    if progress["conversion_status"] == "completed":
        print("Conversion complete!")
        break
    elif progress["conversion_status"] == "failed":
        print(f"Conversion failed: {progress.get('error', 'Unknown error')}")
        break

    time.sleep(3)

# 5. Download CSV
download = requests.get(
    f"{BASE_URL}/download/{filename}?format=csv",
    headers=HEADERS
).json()

csv_url = download["data"]["download_url"]
csv_data = requests.get(csv_url)

with open("output.csv", "wb") as f:
    f.write(csv_data.content)
print("Saved output.csv")

# 6. Download JSON
download_json = requests.get(
    f"{BASE_URL}/download/{filename}?format=json",
    headers=HEADERS
).json()

json_url = download_json["data"]["download_url"]
json_data = requests.get(json_url)

with open("output.json", "wb") as f:
    f.write(json_data.content)
print("Saved output.json")