Overview

Welcome to the Statemint API. Use these endpoints to upload bank statements securely, convert them into normalized transaction data, and retrieve your remaining credits. All requests require an API key in the header.

Required Header
x-api-key: YOUR_API_KEY

Authentication

Authenticate each request with your secret API key via the x-api-key header. Never commit keys to source control - prefer environment variables/secrets managers.

JavaScript (fetch)
const res = await fetch("https://api.example.com/api/v1/health", {
  headers: { "x-api-key": process.env.MY_API_KEY! }
});
cURL
curl -s https://api.example.com/api/v1/health \
  -H "x-api-key: YOUR_API_KEY"

Upload Statements

POST /api/v1/uploads/presign

Request a short-lived, single-use URL to upload your PDF file directly to secure object storage. You'll receive an uploadUrl for the PUT request and a fileUrl to reference when converting.

Request
POST https://api.example.com/api/v1/uploads/presign
Headers:
  content-type: application/json
  x-api-key: YOUR_API_KEY
Body:
{
  "fileName": "jan-2025-bank-statement.pdf",
  "contentType": "application/pdf"
}
Response
200 OK
{
  "uploadUrl": "https://r2.example.com/..../signed-put-url",
  "fileUrl": "https://cdn.example.com/uploads/1700000000000-uuid-jan-2025-bank-statement.pdf",
  "expiresIn": 900,
  "conversionId": "conv_01JB6ABCD..."
}

Next, upload your file to the returned uploadUrl with a PUT request.

cURL (PUT to uploadUrl)
curl -X PUT "https://r2.example.com/..../signed-put-url" \
  -H "content-type: application/pdf" \
  --data-binary @./jan-2025-bank-statement.pdf
JavaScript (PUT to uploadUrl)
const file = await fs.promises.readFile("./jan-2025-bank-statement.pdf");
await fetch(uploadUrl, {
  method: "PUT",
  headers: { "content-type": "application/pdf" },
  body: file
});

Convert Statements

POST /api/v1/convert

Convert an uploaded PDF into normalized transactions. Pass the conversionId returned by the presign call. The server will securely generate a short-lived download URL and process the file server-to-server.

Request
POST https://api.example.com/api/v1/convert
Headers:
  content-type: application/json
  x-api-key: YOUR_API_KEY
Body:
{
  "conversionId": "conv_01JB6ABCD..."
}
Response
200 OK
{
  "id": "conv_01JB5ZKQ8...",
  "status": "SUCCESS",
  "features": {
    "canExportXLSX": true,
    "apiAccess": true,
    "plan": "SCALE"
  },
  "extraction": {
    "account": "Example Bank",
    "pageCount": 12,
    "transactions": [
      { "date": "2025-01-02", "description": "COFFEE SHOP", "amount": -4.50, "currency": "USD" },
      { "date": "2025-01-03", "description": "PAYROLL", "amount": 2500.00, "currency": "USD" }
    ]
  }
}
Note: For large files, you may first receive a response indicating processing is underway. If so, poll a job status endpoint if provided, or retry the request after a brief delay.

Get Remaining Credits

GET /api/v1/credits

Retrieve the number of pages or conversions available based on your current plan and usage.

Request
GET https://api.example.com/api/v1/credits
Headers:
  x-api-key: YOUR_API_KEY
Response
200 OK
{
  "credits": 487
}

Errors

The API returns conventional HTTP status codes. The response body includes a machine-readable error message.

Example Error
429 TOO MANY REQUESTS
{
  "error": "rate_limit_exceeded",
  "message": "Monthly page quota reached. Upgrade your plan or wait for the next cycle."
}

Rate Limits

Usage limits depend on your plan and may be enforced by monthly page quotas or daily conversion caps. Business and Scale plan users receive higher quotas. See your plan details for more.

API Docs | Statemint