FinSheet AI API
Upload a bank statement PDF and get back clean, structured transaction data — in JSON, CSV, or Excel. Supports 50+ banks worldwide.
https://www.finsheetai.com/api/v1
Authentication
Two auth methods are used depending on the operation you're performing.
Use your fsk_live_… key for /convert and /usage. Pass it as the X-API-Key header or as Authorization: Bearer <key>.
Use your dashboard JWT for creating, listing and revoking API keys. Pass it as Authorization: Bearer <jwt>.
curl -X POST https://www.finsheetai.com/api/v1/convert \ -H "X-API-Key: fsk_live_your_key_here" \ -H "Accept: application/json" \ -F "[email protected]" \ -F "format=json"
import requests res = requests.post( "https://www.finsheetai.com/api/v1/convert", headers={"X-API-Key": "fsk_live_your_key_here"}, files={"file": open("statement.pdf", "rb")}, data={"format": "json"} ) transactions = res.json()["transactions"]
const FormData = require('form-data'); const fs = require('fs'), axios = require('axios'); const form = new FormData(); form.append('file', fs.createReadStream('statement.pdf')); form.append('format', 'json'); const { data } = await axios.post( 'https://www.finsheetai.com/api/v1/convert', form, { headers: { 'X-API-Key': 'fsk_live_your_key_here', ...form.getHeaders() } } );
$curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => 'https://www.finsheetai.com/api/v1/convert', CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_HTTPHEADER => ['X-API-Key: fsk_live_your_key_here'], CURLOPT_POSTFIELDS => [ 'file' => new CURLFile('statement.pdf'), 'format' => 'json', ], ]); $resp = json_decode(curl_exec($curl), true);
Plans & Limits
Counters reset on the 1st of each month. Exceeding your quota returns HTTP 429.
429 Too Many Requests until the counter resets.Convert PDF
The core endpoint. Upload a bank statement PDF and receive structured transaction data.
multipart/form-data. Auth via X-API-Key or Authorization: Bearer <api_key>.json (default), csv, or excel.chase, wells_fargo). Auto-detected if omitted.curl -X POST https://www.finsheetai.com/api/v1/convert \ -H "X-API-Key: fsk_live_your_key_here" \ -F "file=@chase_jan.pdf" \ -F "format=json"
res = requests.post( "https://www.finsheetai.com/api/v1/convert", headers={"X-API-Key": "fsk_live_your_key_here"}, files={"file": ("statement.pdf", open("statement.pdf","rb"), "application/pdf")}, data={"format": "json"} )
const form = new FormData(); form.append('file', fs.createReadStream('statement.pdf'), 'statement.pdf'); form.append('format', 'json'); const res = await fetch('https://www.finsheetai.com/api/v1/convert', { method:'POST', headers:{'X-API-Key':'fsk_live_your_key_here'}, body:form });
curl_setopt_array($curl, [ CURLOPT_URL => 'https://www.finsheetai.com/api/v1/convert', CURLOPT_POST => true, CURLOPT_HTTPHEADER => ['X-API-Key: fsk_live_your_key_here'], CURLOPT_POSTFIELDS => [ 'file' => new CURLFile('statement.pdf','application/pdf'), 'format' => 'json' ], ]);
{
"success": true,
"request_id": "a1b2c3d4",
"bank_name": "Chase Bank",
"account_holder": "John Doe",
"statement_period": { "from": "2024-01-01", "to": "2024-01-31" },
"currency": "USD",
"balances": { "opening": 5000.00, "closing": 4823.47 },
"summary": { "total_transactions": 42, "total_credits": 3500.00, "total_debits": 3676.53 },
"transactions": [
{
"date": "2024-01-03",
"description": "Amazon Prime",
"debit_amount": 14.99,
"credit_amount": null,
"balance": 4985.01
}
],
"processing_time_ms": 4230,
"api_usage": { "calls_this_month": 5, "monthly_limit": 1000 }
}
Manage API Keys
Create and manage API keys programmatically. All key management endpoints require your JWT token from the dashboard.
Authorization: Bearer <jwt>.curl https://www.finsheetai.com/api/v1/keys \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
res = requests.get( "https://www.finsheetai.com/api/v1/keys", headers={"Authorization": "Bearer YOUR_JWT_TOKEN"} ) keys = res.json()["keys"]
{ "keys": [{ "id": 1, "name": "My Integration", "key_prefix": "fsk_live_SP5x",
"plan": "pro", "monthly_limit": 1000, "calls_this_month": 47,
"calls_total": 312, "is_active": true, "created_at": "2024-01-15T10:30:00" }],
"total": 1, "active": 1 }
curl -X POST https://www.finsheetai.com/api/v1/keys \ -H "Authorization: Bearer YOUR_JWT_TOKEN" \ -H "Content-Type: application/json" \ -d '{"name":"Production Key"}'
res = requests.post( "https://www.finsheetai.com/api/v1/keys", headers={"Authorization": "Bearer YOUR_JWT_TOKEN"}, json={"name": "Production Key"} ) # Save api_key — won't be shown again! api_key = res.json()["api_key"]
{ "success": true, "api_key": "fsk_live_AbCdEfGhIjKlMn...",
"id": 2, "name": "Production Key", "plan": "pro",
"monthly_limit": 1000, "created_at": "2024-02-01T09:00:00" }
curl -X DELETE https://www.finsheetai.com/api/v1/keys/2 \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
curl -X PATCH https://www.finsheetai.com/api/v1/keys/2 \ -H "Authorization: Bearer YOUR_JWT_TOKEN" \ -H "Content-Type: application/json" \ -d '{"name":"Staging Key"}'
X-API-Key.curl https://www.finsheetai.com/api/v1/usage \
-H "X-API-Key: fsk_live_your_key_here"
{ "key_prefix": "fsk_live_SP5x", "plan": "pro",
"monthly_limit": 1000, "calls_this_month": 47,
"remaining_this_month": 953, "calls_total": 312,
"last_used_at": "2024-02-01T08:45:00", "resets_at": "2024-03-01" }
curl https://www.finsheetai.com/api/v1/health
{ "status": "ok", "version": "1.0" }Error Codes
All errors return a JSON body with an error field and a human-readable message.
{
"error": "rate_limit_exceeded",
"message": "Monthly limit of 1000 calls reached. Resets on the 1st of next month.",
"calls_this_month": 1000,
"monthly_limit": 1000
}
| HTTP | Error Code | Description |
|---|---|---|
| 400 | invalid_format | Unsupported output format. Use json, csv, or excel. |
| 400 | file_too_large | File exceeds the plan's max size limit. |
| 400 | key_limit_reached | Maximum of 10 active API keys already reached. |
| 401 | missing_api_key | No API key or JWT provided. |
| 401 | invalid_api_key | API key does not exist. |
| 401 | invalid_token | JWT is missing, expired, or invalid. |
| 403 | revoked_api_key | Key has been revoked and can no longer be used. |
| 404 | not_found | Requested resource not found. |
| 415 | invalid_file_type | Uploaded file is not a valid PDF. |
| 422 | validation_error | Request body failed schema validation. |
| 429 | rate_limit_exceeded | Monthly call limit reached. Resets on the 1st of next month. |
| 500 | conversion_failed | AI extraction failed. Retry or contact support. |