Bankstatemently API V1 API
[Bankstatemently - PDF to CSV Bank Statement Converter](https://bankstatemently.com)
[Bankstatemently - PDF to CSV Bank Statement Converter](https://bankstatemently.com)
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/bankstatemently-com:bankstatemently-api-v1-api"
curl "https://apis.io/api/v1/apis?limit=25"
Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.
{"paths":{"/documents":{"post":{"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique key to ensure the request is processed at most once. Must be unique per request — use a UUID. Keys expire after 24 hours. If a duplicate key is detected, the original response is replayed with `X-Idempotency-Replayed: true`.","schema":{"type":"string"}},{"name":"X-Filename","in":"header","required":false,"description":"Original filename for the uploaded PDF. Used for display purposes only. Defaults to 'document.pdf' if not provided.","schema":{"type":"string"}},{"name":"X-Webhook-URL","in":"header","required":false,"description":"Webhook URL for processing completion notifications. Overrides the default webhook URL configured on the API key.","schema":{"type":"string","format":"uri"}},{"name":"X-Password","in":"header","required":false,"description":"Decryption password for encrypted PDFs. When provided, the PDF is decrypted and processed in a single request — no need for the two-step unlock flow. The password is used in memory only and never stored or logged.","schema":{"type":"string","maxLength":1000}},{"name":"retry","in":"query","required":false,"description":"Set to 'true' to reprocess a previously failed upload of the same file. Without this, re-uploading a failed file returns an already_processing error.","schema":{"type":"string","enum":["true"]}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"upload_id":{"type":"string","description":"An upload_id from POST /v1/upload-tokens, after PUTting the file to its upload_url. Converts the previously-uploaded file by reference instead of sending PDF bytes in this request."},"webhook_url":{"type":"string","format":"uri","description":"Webhook URL for processing completion notifications. Overrides the default webhook URL configured on the API key."}},"required":["upload_id"]}},"application/pdf":{"schema":{"type":"string","format":"binary","description":"The raw PDF bank statement bytes. Set Content-Type to application/pdf."}}}},"operationId":"uploadDocument","summary":"Upload a bank statement PDF","description":"Upload a PDF bank statement for conversion. The file is processed asynchronously. Poll the returned `id` via GET /v1/documents/{id} to check progress. Rate limit: 10 requests per minute. Alternatively, POST a JSON body `{ \"upload_id\": \"...\" }` referencing a token minted via POST /v1/upload-tokens, to convert a previously-PUT file by reference.","tags":["Documents"],"responses":{"202":{"description":"Upload accepted. Processing has started, or the PDF requires a password.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-API-Version":{"$ref":"#/components/headers/X-API-Version"},"X-Idempotency-Replayed":{"$ref":"#/components/headers/X-Idempotency-Replayed"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatementUploadResponse"},"examples":{"processing":{"summary":"Upload accepted — processing started","value":{"id":"d290f1ee-6c54-4b01-90e6-d701748f0851","status":"processing","contentHash":"a1b2c3d4e5f6","createdAt":"2026-02-27T10:30:00.000Z","statements":[],"links":{"self":"https://api.bankstatemently.com/v1/documents/d290f1ee-6c54-4b01-90e6-d701748f0851"}}},"encrypted_pdf":{"summary":"Password-protected PDF — requires unlock","value":{"id":"d290f1ee-6c54-4b01-90e6-d701748f0851","status":"password_required","contentHash":"a1b2c3d4e5f6","createdAt":"2026-02-27T10:30:00.000Z","statements":[],"links":{"self":"https://api.bankstatemently.com/v1/documents/d290f1ee-6c54-4b01-90e6-d701748f0851","unlock":"https://api.bankstatemently.com/v1/documents/d290f1ee-6c54-4b01-90e6-d701748f0851/unlock"}}}}}}},"400":{"description":"Invalid request (e.g., missing file, wrong content type, invalid file).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"missing_file":{"summary":"No file uploaded","value":{"error":{"type":"invalid_request_error","code":"missing_file","message":"No file provided. Send a PDF as multipart/form-data with field name \"file\".","request_id":"req_7yNm3kPqW2a4bZ1c"}}},"invalid_file_type":{"summary":"Unsupported file type","value":{"error":{"type":"invalid_request_error","code":"invalid_file_type","message":"Invalid file type. Only PDF files are supported.","request_id":"req_2bFh6jLnR0c4dE8g"}}},"invalid_pdf":{"summary":"Corrupted or unreadable PDF","value":{"error":{"type":"invalid_request_error","code":"invalid_pdf","message":"This file could not be read as a valid PDF. It may be corrupted.","request_id":"req_6fJl0nRtV4g8hI2k"}}},"invalid_parameters":{"summary":"Invalid webhook_url or other parameters","value":{"error":{"type":"invalid_request_error","code":"invalid_parameters","message":"Invalid webhook_url: Webhook URL must use HTTPS.","meta":{"fields":[{"field":"webhook_url","message":"Webhook URL must use HTTPS."}]},"request_id":"req_8hLn2pTvX6i0jK4m"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"description":"Quota exceeded (insufficient credits, page limit, or file size).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"insufficient_credits":{"summary":"Not enough credits to process file","value":{"error":{"type":"quota_exceeded","code":"insufficient_credits","message":"Insufficient credits. This file requires 3 credit(s) but you have 1 remaining. Purchase more at https://bankstatemently.com/pricing.","meta":{"credits_required":3,"credits_remaining":1},"request_id":"req_8zAb2cDe4fGh6iJk"}}},"page_limit_exceeded":{"summary":"PDF exceeds plan's page limit","value":{"error":{"type":"quota_exceeded","code":"page_limit_exceeded","message":"Page limit exceeded. This file has 25 pages but your plan allows 10. Upgrade at https://bankstatemently.com/pricing.","meta":{"page_count":25,"page_limit":10},"request_id":"req_0bDf4hJlN8c2eG6i"}}},"file_too_large":{"summary":"File exceeds plan's size limit","value":{"error":{"type":"quota_exceeded","code":"file_too_large","message":"File too large. Your plan allows files up to 10 MB. Upgrade at https://bankstatemently.com/pricing.","meta":{"max_size_mb":10},"request_id":"req_2dFh6jLnR0e4gI8k"}}}}}}},"409":{"description":"Document already exists or is being processed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"type":"invalid_request_error","code":"already_processing","message":"This document is already being processed. Poll GET /v1/documents/{id} for status updates.","request_id":"req_4fHj8lNpT2g6iK0m"}}}}},"422":{"description":"Wrong password. Only returned when X-Password header is provided for an encrypted PDF.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"type":"invalid_request_error","code":"wrong_password","message":"The password provided is incorrect. Please try again.","request_id":"req_3eGi7kMoS1f5hJ9l"}}}}},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}},"get":{"parameters":[{"name":"limit","in":"query","required":false,"description":"Maximum number of documents to return.","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"offset","in":"query","required":false,"description":"Number of documents to skip for pagination.","schema":{"type":"integer","minimum":0,"default":0}},{"name":"status","in":"query","required":false,"description":"Filter documents by processing status.","schema":{"$ref":"#/components/schemas/DocumentStatus"}}],"operationId":"listDocuments","summary":"List recent documents","description":"Retrieve a paginated list of your uploaded documents, ordered by creation date descending. Rate limit: 120 requests per minute.","tags":["Documents"],"responses":{"200":{"description":"Paginated list of documents.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-API-Version":{"$ref":"#/components/headers/X-API-Version"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatementListResponse"},"example":{"data":[{"id":"d290f1ee-6c54-4b01-90e6-d701748f0851","status":"completed","contentHash":"a1b2c3d4e5f6","filename":"statement-jan-2026.pdf","pageCount":3,"source":"api","createdAt":"2026-02-27T10:30:00.000Z","updatedAt":"2026-02-27T10:31:15.000Z","exports":{"json":"https://api.bankstatemently.com/v1/documents/d290f1ee-6c54-4b01-90e6-d701748f0851/export/json","csv":"https://api.bankstatemently.com/v1/documents/d290f1ee-6c54-4b01-90e6-d701748f0851/export/csv","xlsx":"https://api.bankstatemently.com/v1/documents/d290f1ee-6c54-4b01-90e6-d701748f0851/export/xlsx","qbo":"https://api.bankstatemently.com/v1/documents/d290f1ee-6c54-4b01-90e6-d701748f0851/export/qbo","xero":"https://api.bankstatemently.com/v1/documents/d290f1ee-6c54-4b01-90e6-d701748f0851/export/xero"}},{"id":"e3a1b2c3-7d54-4b01-90e6-f801849g1962","status":"processing","contentHash":"b2c3d4e5f6g7","filename":"statement-feb-2026.pdf","pageCount":null,"source":"api","createdAt":"2026-02-27T11:00:00.000Z","updatedAt":"2026-02-27T11:00:00.000Z"}],"pagination":{"total":42,"limit":20,"offset":0,"hasMore":true}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/upload-tokens":{"post":{"operationId":"mintUploadToken","summary":"Mint a single-use upload token","description":"Mints a single-use, expiring upload token for hosts with no direct byte-upload equivalent (e.g. an agent sandbox with outbound-only network access). PUT the PDF to the returned upload_url, then POST /v1/documents with `{ \"upload_id\": \"...\" }` to convert it by reference. Tokens expire after ~2 hours and are single-use — PUTting a second file overwrites the first, but converting consumes the token. No credit is deducted on mint; credits are charged only at conversion. Rate limit: 20 requests per minute.","tags":["Documents"],"responses":{"201":{"description":"Upload token minted.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"type":"object","required":["upload_id","upload_url","expires_at","max_bytes"],"properties":{"upload_id":{"type":"string","description":"Pass this to POST /v1/documents as { \"upload_id\": ... } to convert the uploaded file."},"upload_url":{"type":"string","format":"uri","description":"PUT the raw PDF bytes here, with Content-Type: application/pdf."},"expires_at":{"type":"string","format":"date-time","description":"When this token expires (~2 hours from mint)."},"max_bytes":{"type":"integer","description":"Maximum PDF size in bytes this token accepts, derived from the caller's plan."}}},"example":{"upload_id":"b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e","upload_url":"https://api.bankstatemently.com/uploads/7f3a...c9","expires_at":"2026-08-10T14:00:00.000Z","max_bytes":52428800}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/documents/{id}":{"get":{"parameters":[{"name":"id","in":"path","required":true,"description":"The document UUID returned from the upload endpoint.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"operationId":"getDocument","summary":"Get document processing status","description":"Poll the status of an uploaded document. When status is `completed`, the response includes statement metadata and export URLs. Rate limit: 120 requests per minute.","tags":["Documents"],"responses":{"200":{"description":"Document status and metadata.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-API-Version":{"$ref":"#/components/headers/X-API-Version"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatementDetailResponse"},"examples":{"processing":{"summary":"Document still processing","value":{"id":"d290f1ee-6c54-4b01-90e6-d701748f0851","status":"processing","contentHash":"a1b2c3d4e5f6","createdAt":"2026-02-27T10:30:00.000Z","updatedAt":"2026-02-27T10:30:00.000Z","statements":[],"links":{"self":"https://api.bankstatemently.com/v1/documents/d290f1ee-6c54-4b01-90e6-d701748f0851"}}},"completed":{"summary":"Document completed with statements","value":{"id":"d290f1ee-6c54-4b01-90e6-d701748f0851","status":"completed","contentHash":"a1b2c3d4e5f6","createdAt":"2026-02-27T10:30:00.000Z","updatedAt":"2026-02-27T10:31:15.000Z","document":{"bank":"DBS Bank","country":"SG","currency":"SGD","documentType":"bank-statement","pageCount":3,"transactionCount":78,"accountCount":1},"statements":[{"index":0,"statementPeriod":{"from":"2026-01-01","to":"2026-01-31"},"transactionCount":47},{"index":1,"statementPeriod":{"from":"2026-02-01","to":"2026-02-28"},"transactionCount":31}],"exports":{"json":"https://api.bankstatemently.com/v1/documents/d290f1ee-6c54-4b01-90e6-d701748f0851/export/json","csv":"https://api.bankstatemently.com/v1/documents/d290f1ee-6c54-4b01-90e6-d701748f0851/export/csv","xlsx":"https://api.bankstatemently.com/v1/documents/d290f1ee-6c54-4b01-90e6-d701748f0851/export/xlsx","qbo":"https://api.bankstatemently.com/v1/documents/d290f1ee-6c54-4b01-90e6-d701748f0851/export/qbo","xero":"https://api.bankstatemently.com/v1/documents/d290f1ee-6c54-4b01-90e6-d701748f0851/export/xero"},"links":{"self":"https://api.bankstatemently.com/v1/documents/d290f1ee-6c54-4b01-90e6-d701748f0851","data":"https://api.bankstatemently.com/v1/documents/d290f1ee-6c54-4b01-90e6-d701748f0851/data"}}},"password_required":{"summary":"Document requires a password","value":{"id":"d290f1ee-6c54-4b01-90e6-d701748f0851","status":"password_required","contentHash":"a1b2c3d4e5f6","createdAt":"2026-02-27T10:30:00.000Z","updatedAt":"2026-02-27T10:30:00.000Z","statements":[],"links":{"self":"https://api.bankstatemently.com/v1/documents/d290f1ee-6c54-4b01-90e6-d701748f0851","unlock":"https://api.bankstatemently.com/v1/documents/d290f1ee-6c54-4b01-90e6-d701748f0851/unlock"}}},"failed":{"summary":"Document processing failed","value":{"id":"d290f1ee-6c54-4b01-90e6-d701748f0851","status":"failed","contentHash":"a1b2c3d4e5f6","createdAt":"2026-02-27T10:30:00.000Z","updatedAt":"2026-02-27T10:30:45.000Z","statements":[],"error":"Unable to extract data from PDF. The file may be scanned or password-protected.","links":{"self":"https://api.bankstatemently.com/v1/documents/d290f1ee-6c54-4b01-90e6-d701748f0851"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Document not found or does not belong to the authenticated user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"type":"invalid_request_error","code":"document_not_found","message":"Document not found.","request_id":"req_9xQr5tVwY3b6dE2f"}}}}},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/documents/{id}/data":{"get":{"parameters":[{"name":"id","in":"path","required":true,"description":"The document UUID.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"raw","in":"query","required":false,"description":"Set to `true` to include `originalData` (raw pre-normalization cell values) on each transaction. When enabled, max limit is reduced to 500.","schema":{"type":"boolean","default":false}},{"name":"limit","in":"query","required":false,"description":"Maximum number of transactions per page.","schema":{"type":"integer","minimum":1,"maximum":2000,"default":500}},{"name":"offset","in":"query","required":false,"description":"Number of transactions to skip for pagination.","schema":{"type":"integer","minimum":0,"default":0}}],"operationId":"getDocumentData","summary":"Get structured document data","description":"Retrieve structured document data including accounts and transactions. Only available when document status is `completed`. Transactions are paginated. Rate limit: 60 requests per minute.","tags":["Documents"],"responses":{"200":{"description":"Structured document data. Primary shape: document.statements[].products[].accounts[].transactions[]. Legacy flat accounts[] and transactions[] retained for backward compatibility.","content":{"application/json":{"example":{"id":"d290f1ee-6c54-4b01-90e6-d701748f0851","contentHash":"a1b2c3d4e5f6","createdAt":"2026-02-27T10:30:00.000Z","updatedAt":"2026-02-27T10:31:15.000Z","processedAt":"2026-02-27T10:31:15.000Z","document":{"documentType":"bank-statement","bank":"DBS Bank","bankId":"dbs-bank-ltd","country":"SG","currency":"SGD","languages":["en"],"pageCount":3,"statementDate":"2026-01-31","statementPeriod":{"from":"2026-01-01","to":"2026-01-31"},"statements":[{"date":"2026-01-31","period":{"from":"2026-01-01","to":"2026-01-31"},"products":[{"productId":null,"productName":null,"currency":"SGD","declared":[{"payload":{"kind":"balance:closing","amount":4250.75,"direction":"credit","currency":"SGD"},"ownership":{"level":"product"}}],"categories":[],"accounts":[{"accountId":0,"accountNumber":"XXX-X-XX1234","accountHolderName":"John Doe","currency":"SGD","declared":[{"payload":{"kind":"balance:opening","amount":5000,"direction":"credit","currency":"SGD"},"ownership":{"level":"account"}},{"payload":{"kind":"balance:closing","amount":4250.75,"direction":"credit","currency":"SGD"},"ownership":{"level":"account"}},{"payload":{"kind":"total","amount":1200,"currency":"SGD"},"ownership":{"level":"account"},"slice":{"direction":"credit"}},{"payload":{"kind":"total","amount":1949.25,"currency":"SGD"},"ownership":{"level":"account"},"slice":{"direction":"debit"}}],"categories":[],"transactions":[{"sequence":0,"date":"2026-01-02","description":"SALARY CREDIT","amount":1200,"direction":"credit","currency":"SGD","balance":6200,"accountId":0,"accountNumber":"XXX-X-XX1234"}]}]}]}]},"accounts":[{"accountId":0,"accountNumber":"XXX-X-XX1234","accountHolderName":"John Doe","currency":"SGD","totals":{"openingBalance":5000,"closingBalance":4250.75,"totalCredits":1200,"totalDebits":1949.25},"declared":[{"payload":{"kind":"balance:opening","amount":5000,"direction":"credit","currency":"SGD"},"ownership":{"level":"account"}},{"payload":{"kind":"balance:closing","amount":4250.75,"direction":"credit","currency":"SGD"},"ownership":{"level":"account"}}],"categories":[]}],"transactions":[{"sequence":0,"date":"2026-01-02","description":"SALARY CREDIT","amount":1200,"direction":"credit","currency":"SGD","balance":6200,"accountId":0,"accountNumber":"XXX-X-XX1234"}],"pagination":{"total":47,"limit":500,"offset":0,"hasMore":false},"exports":{"json":"https://api.bankstatemently.com/v1/documents/d290f1ee-6c54-4b01-90e6-d701748f0851/export/json","csv":"https://api.bankstatemently.com/v1/documents/d290f1ee-6c54-4b01-90e6-d701748f0851/export/csv","xlsx":"https://api.bankstatemently.com/v1/documents/d290f1ee-6c54-4b01-90e6-d701748f0851/export/xlsx","qbo":"https://api.bankstatemently.com/v1/documents/d290f1ee-6c54-4b01-90e6-d701748f0851/export/qbo","xero":"https://api.bankstatemently.com/v1/documents/d290f1ee-6c54-4b01-90e6-d701748f0851/export/xero"}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Document not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"type":"invalid_request_error","code":"document_not_found","message":"Document not found.","request_id":"req_9xQr5tVwY3b6dE2f"}}}}},"409":{"description":"Document processing not yet completed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"type":"invalid_request_error","code":"document_not_ready","message":"Document is not ready (status: processing). Poll GET /v1/documents/{id} until status is \"completed\".","meta":{"status":"processing"},"request_id":"req_3cGi7jKlN1b5eF2g"}}}}},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/documents/{id}/export/{format}":{"get":{"parameters":[{"name":"id","in":"path","required":true,"description":"The document UUID.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"format","in":"path","required":true,"description":"The export format.","schema":{"$ref":"#/components/schemas/ExportFormat"}},{"name":"dataMode","in":"query","required":false,"description":"The data mode to export. `original` returns raw extracted data; `enhanced` (default) includes AI-enriched fields; `normalized` applies standardized formatting.","schema":{"$ref":"#/components/schemas/ExportDataMode"}},{"name":"dateFormat","in":"query","required":false,"description":"Date format string for Xero CSV exports (e.g., `DD/MM/YYYY`). Only applicable when format is `xero`.","schema":{"type":"string","enum":["DD/MM/YYYY","MM/DD/YYYY","YYYY/MM/DD"]}}],"operationId":"exportDocument","summary":"Download converted document","description":"Download the processed document in the specified format. The document must have status `completed`. Rate limit: 30 requests per minute.","tags":["Exports"],"responses":{"200":{"description":"The exported file. Content-Type varies by format.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-API-Version":{"$ref":"#/components/headers/X-API-Version"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"Content-Disposition":{"description":"Attachment filename for the exported file.","schema":{"type":"string"},"example":"attachment; filename=\"statement-jan-2026.csv\""}},"content":{"application/json":{"schema":{"type":"object","description":"Structured JSON export of the document."},"example":{"document":{"bank":"DBS Bank","country":"SG","currency":"SGD"},"statements":[{"period":{"from":"2026-01-01","to":"2026-01-31"},"transactions":[{"date":"2026-01-05","description":"GIRO PAYMENT","amount":-150,"balance":4850}]}]}},"text/csv":{"schema":{"type":"string","description":"CSV export of transactions."}},"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":{"schema":{"type":"string","format":"binary","description":"Excel XLSX export."}},"application/x-ofx":{"schema":{"type":"string","description":"QBO (QuickBooks Online) OFX export."}}}},"400":{"description":"Invalid request parameters (e.g., invalid dataMode).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"type":"invalid_request_error","code":"invalid_export_data_mode","message":"Invalid dataMode. Use \"original\", \"enhanced\", or \"normalized\".","request_id":"req_4kLm8nOpR1c5fG3h"}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Document or completed processing run not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"type":"invalid_request_error","code":"document_not_found","message":"Document not found.","request_id":"req_2bHj6kMnQ0a4cD9e"}}}}},"409":{"description":"Document processing not yet completed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"type":"invalid_request_error","code":"document_not_ready","message":"Document is not ready for export (status: processing). Poll GET /v1/documents/{id} until status is \"completed\".","meta":{"status":"processing"},"request_id":"req_5mNo9pQrS2d6gH4i"}}}}},"422":{"description":"Export generation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"type":"invalid_request_error","code":"export_failed","message":"Failed to generate CSV export: no transactions found.","request_id":"req_5eIk9lNoS2d7gH4i"}}}}},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/documents/{id}/unlock":{"post":{"parameters":[{"name":"id","in":"path","required":true,"description":"The document UUID returned from the upload endpoint.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"password":{"type":"string","minLength":1,"maxLength":1000,"description":"The password to unlock the PDF. Used in memory only for decryption and never stored."}},"required":["password"]},"example":{"password":"my-pdf-password"}}}},"operationId":"unlockDocument","summary":"Unlock a password-protected document","description":"Submit a password to unlock and process a password-protected PDF. The document must have status `password_required`. On success, the document transitions to `processing` status. Rate limit: 20 requests per minute.","tags":["Documents"],"responses":{"200":{"description":"Password accepted. Document is now processing.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"X-API-Version":{"$ref":"#/components/headers/X-API-Version"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatementUploadResponse"},"example":{"id":"d290f1ee-6c54-4b01-90e6-d701748f0851","status":"processing","contentHash":"a1b2c3d4e5f6","createdAt":"2026-02-27T10:30:00.000Z","statements":[],"links":{"self":"https://api.bankstatemently.com/v1/documents/d290f1ee-6c54-4b01-90e6-d701748f0851"}}}}},"400":{"description":"Invalid request (e.g., document is not in `password_required` status).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"type":"invalid_request_error","code":"invalid_status","message":"Document status is \"processing\", not \"password_required\".","request_id":"req_9aXc3eGi5kMo7qSu"}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Document not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"type":"invalid_request_error","code":"document_not_found","message":"Document not found.","request_id":"req_1bYd4fHj6lNp8rTv"}}}}},"422":{"description":"Wrong password.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"type":"invalid_request_error","code":"wrong_password","message":"The password provided is incorrect. Please try again.","meta":{"attempts_remaining":8},"request_id":"req_2cZe5gIk7mOq9sUw"}}}}},"429":{"description":"Rate limit exceeded or maximum unlock attempts reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"rate_limited":{"summary":"Too many requests","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Rate limit exceeded. Try again later.","request_id":"req_3dAf6hJl8nPr0tVx"}}},"attempts_exceeded":{"summary":"Maximum unlock attempts exceeded","value":{"error":{"type":"rate_limit_error","code":"unlock_attempts_exceeded","message":"Maximum unlock attempts (10) exceeded. Please re-upload the file to try again.","request_id":"req_4eBg7iKm9oQs1uWy"}}}}}}},"500":{"$ref":"#/components/responses/InternalError"}}}},"/documents/{id}/categorize":{"post":{"parameters":[{"name":"id","in":"path","required":true,"description":"Document UUID returned by the upload endpoint.","schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"operationId":"categorizeDocument","summary":"Categorize transactions","description":"Categorize a document's transactions using AI. Returns cached categories if already generated (no credit charge). Otherwise deducts 1 credit and runs LLM-based categorization. Rate limit: 20 requests per minute.","tags":["Documents"],"responses":{"200":{"description":"Categories returned (cached or freshly generated).","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Document UUID."},"contentHash":{"type":"string","description":"SHA-256 content hash of the original file."},"categories":{"type":"object","properties":{"metadata":{"type":"object","properties":{"categorizedAt":{"type":"string","format":"date-time","description":"When categorization was performed."},"model":{"type":"string","description":"AI model used for categorization."},"totalTransactions":{"type":"integer","description":"Number of transactions categorized."}}},"mappings":{"type":"object","additionalProperties":{"type":"string"},"description":"Map of transaction sequence number to category ID.","example":{"1":"groceries_personal","2":"meals_entertainment","3":"transfers","4":"utilities_telecom"}}}}}},"example":{"id":"d290f1ee-6c54-4b01-90e6-d701748f0851","contentHash":"a1b2c3d4e5f6...","categories":{"metadata":{"categorizedAt":"2026-03-04T12:00:00.000Z","model":"claude-haiku-4-5-20251001","totalTransactions":42},"mappings":{"1":"groceries_personal","2":"meals_entertainment","3":"transfers","4":"utilities_telecom","5":"supplies_equipment"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"description":"Insufficient credits.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"type":"quota_exceeded","code":"insufficient_credits","message":"Insufficient credits. Categorization requires 1 credit.","meta":{"credits_required":1,"credits_remaining":0},"request_id":"req_8zOn4lQrX3b5cA2d"}}}}},"404":{"description":"Document not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"type":"invalid_request_error","code":"document_not_found","message":"Document not found.","request_id":"req_9aPo5mRsY4c6dB3e"}}}}},"409":{"description":"Document not ready for categorization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"type":"invalid_request_error","code":"document_not_ready","message":"Document is not ready for categorization (status: processing). Poll GET /v1/documents/{id} until status is \"completed\".","meta":{"status":"processing"},"request_id":"req_0bQp6nStZ5d7eC4f"}}}}},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/credits":{"get":{"operationId":"getCredits","summary":"Get credit balance","description":"Returns the current credit balance for the authenticated user. Recommended: call this before large uploads to ensure sufficient credits. 1 credit = 1 page. Rate limit: 120 requests per minute.","tags":["Credits"],"responses":{"200":{"description":"Current credit balance.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"Cache-Control":{"description":"Caching directive. Response is cached for 5 seconds.","schema":{"type":"string"},"example":"private, max-age=5"}},"content":{"application/json":{"schema":{"type":"object","required":["balance","limit","planId","creditsExpireAt"],"properties":{"balance":{"type":"integer","description":"Current remaining credits. 1 credit = 1 page.","example":47},"limit":{"type":["integer","null"],"description":"Plan allowance. 10 for free, plan-
# --- truncated at 32 KB (64 KB total) ---
# Full source: https://artifacts.apis.io/bankstatemently-com/openapi/_original/bankstatemently-com-v1-openapi.json