API Documentation
Use this guide to integrate the Bank Statement Parser REST API into your application.
Quick Start
1. Create a free account and get your API key.
Start FreeAuthentication
Use one of the following methods in every request:
Bearer JWT
Authorization: Bearer <your_jwt_token>API Key
X-Api-Key: pex_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxExtract PDF
POST
/extractUpload a PDF and receive the transaction list as JSON or CSV. Accepts file upload or URL.
Form Fields
| Field | Type | Description |
|---|---|---|
| file | File | PDF file (max 10 MB) |
| url | string | PDF URL (alternative to file) |
| webhookUrl | string | URL called when processing completes |
| format | string | Output format: json (default) or csv |
cURL Example
curl -X POST https://api.bank-statement-parser.clkr.work/extract \ -H "X-Api-Key: pex_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \ -F "file=@statement.pdf"
200Success — known format
{
"requestId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"bankKey": "bank_v1",
"pageCount": 2,
"transactionCount": 45,
"transactions": [
{ "date": "2024-01-15", "description": "MARKET PAYMENT", "amount": -250.00, "balance": 4750.00 }
]
}202Queued — unknown format
{
"queueId": "a1b2c3d4-...",
"status": "queued",
"message": "Unknown PDF format. Queued for profile generation."
}Extract from OCR Text
Send raw text extracted by your own OCR engine. Parse transactions without uploading a PDF.
POST
/extract-textJSON Body
| Field | Type | Description |
|---|---|---|
| rawText * | string | Raw OCR-extracted text (max 500 KB) |
| fileName | string | Optional file name hint |
| webhookUrl | string | URL called when processing completes |
| format | string | json (default) or csv |
cURL Example
curl -X POST https://api.bank-statement-parser.clkr.work/extract-text \
-H "X-Api-Key: pex_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"rawText": "01.01.2024 Market -250,00 4.750,00\n..."}'Dispute / Page Refund
If a PDF was processed incorrectly, you can report it within 14 days. If approved, the used page credit is refunded.
POST
/api/refund/requestSubmit dispute — JWT required// Request body
{
"usageLogId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", // requestId from /extract
"reason": "Got 8 transactions instead of 15, page 2 was skipped"
}
// 200 OK
{ "message": "Bildiriminiz alındı." }GET
/api/refund/my-requestsMy dispute requests[
{
"id": "...",
"usageLogId": "3fa85f64-...",
"reason": "...",
"pageCount": 3,
"status": "Pending", // Pending | Approved | Rejected
"adminNote": null,
"createdAt": "2026-06-26T10:00:00Z"
}
]Rate Limits
| Rule | Limit |
|---|---|
| Demo (no API key) — per IP per day | 5 req/day |
| /api/auth/* | 5 req/min |
| /extract, /extract-text | 20 req/min |
| Other endpoints | 100 req/min |
Changelog
v3.1.02026-06-10
- + OCR text extraction endpoint (/extract-text)
- + JSON/CSV output format selection
- + Unified ApiResult wrapper (requestId, isSuccess, data)
- + Localized error messages (TR/EN)
- + Demo limit: 5 req/IP/day
- + Profiles now stored in PostgreSQL (DB primary, files as backup)
- + Central exception handling middleware
v3.0.02026-05-20
- + Auth system added (JWT + API key)
- + Usage tracking and logging
- + Rate limiting (auth/extract/global)
- + CORS security
v2.0.02026-05-01
- + Unknown format queue
- + Automatic profile learning
- + Webhook support