{
  "openapi": "3.0.3",
  "info": {
    "title": "StatementEasy API",
    "version": "1.1.0",
    "description": "Convert bank and credit card statements (PDF, scans, photos, CSV, Excel, OFX, QFX, QIF, MT940, CAMT.053) into JSON or into Excel, CSV, QuickBooks, Quicken, Xero, OFX, QIF, IIF, MT940 and CAMT.053 files. Free API keys at https://statementeasy.com/account. Docs: https://statementeasy.com/api"
  },
  "servers": [{ "url": "https://statementeasy.com/api" }],
  "security": [{ "bearer": [] }],
  "components": {
    "securitySchemes": { "bearer": { "type": "http", "scheme": "bearer", "description": "Your key, sg_live_…" } },
    "schemas": {
      "Error": { "type": "object", "properties": { "error": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" } } } } },
      "Transaction": {
        "type": "object",
        "properties": {
          "date": { "type": "string", "format": "date" },
          "value_date": { "type": "string", "format": "date", "nullable": true },
          "description": { "type": "string" },
          "payee": { "type": "string", "description": "Clean merchant name, or the payee from your rules" },
          "amount": { "type": "number", "description": "Money in positive, money out negative" },
          "money_in": { "type": "number", "nullable": true },
          "money_out": { "type": "number", "nullable": true },
          "balance": { "type": "number", "nullable": true },
          "category": { "type": "string", "description": "With categories=true, or rules that set a category" },
          "account": { "type": "string", "description": "For statements with several accounts" },
          "balance_check": { "type": "string", "enum": ["ok", "mismatch"], "nullable": true }
        }
      },
      "Result": {
        "type": "object",
        "properties": {
          "bank": { "type": "object", "nullable": true, "properties": { "slug": { "type": "string" }, "name": { "type": "string" } } },
          "pages": { "type": "integer" },
          "period": { "type": "object", "properties": { "from": { "type": "string", "format": "date" }, "to": { "type": "string", "format": "date" } } },
          "opening_balance": { "type": "number", "nullable": true },
          "closing_balance": { "type": "number", "nullable": true },
          "total_in": { "type": "number" },
          "total_out": { "type": "number" },
          "check": { "type": "object", "properties": { "status": { "type": "string", "enum": ["ok", "totals", "warn", "none"] }, "checked_rows": { "type": "integer" }, "mismatched_rows": { "type": "integer" }, "message": { "type": "string" } } },
          "count": { "type": "integer" },
          "transactions": { "type": "array", "items": { "$ref": "#/components/schemas/Transaction" } }
        }
      },
      "Job": { "type": "object", "properties": { "status": { "type": "string", "enum": ["queued", "processing"] }, "job": { "type": "string", "format": "uuid" }, "status_url": { "type": "string" }, "position": { "type": "integer" } } }
    }
  },
  "paths": {
    "/v1/convert": {
      "post": {
        "summary": "Convert a statement",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": ["file"],
                "properties": {
                  "file": { "type": "string", "format": "binary", "description": "Up to 25 MB" },
                  "format": { "type": "string", "enum": ["json", "xlsx", "csv", "qbo", "qfx", "ofx", "qif", "iif", "mt940", "camt", "xero", "qbocsv"], "default": "json" },
                  "pages": { "type": "string", "example": "2-5,8" },
                  "password": { "type": "string" },
                  "date_format": { "type": "string", "enum": ["iso", "dmy", "mdy"] },
                  "layout": { "type": "string", "enum": ["split", "signed"] },
                  "categories": { "type": "boolean" },
                  "payee": { "type": "boolean", "description": "Adds a Payee column to xlsx/csv (JSON always has payee)" },
                  "mask": { "type": "boolean", "description": "Hides account and card numbers, IBANs and emails" },
                  "insights": { "type": "boolean", "description": "Adds result.insights (months, categories, balances, income, large deposits, fees)" },
                  "document_check": { "type": "boolean", "description": "Adds result.document_check {verdict: clean|review|edited, reasons[]} for text PDFs" },
                  "rules": { "type": "string", "description": "JSON array of {match, payee, category, sign: in|out}; first match wins", "example": "[{\"match\":\"amazon\",\"payee\":\"Amazon\",\"category\":\"Shopping\"}]" },
                  "credit_card": { "type": "boolean" },
                  "date_order": { "type": "string", "enum": ["DMY", "MDY"] },
                  "bank": { "type": "string" },
                  "currency": { "type": "string", "example": "GBP" },
                  "ocr_language": { "type": "string", "enum": ["en", "fr", "ar", "es", "pt", "de"] },
                  "webhook_url": { "type": "string", "format": "uri", "description": "https URL called when an OCR job ends" }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Converted (JSON result, or the file for other formats)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Result" } }, "application/octet-stream": {} } },
          "202": { "description": "A scan or photo still being read; poll status_url", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Job" } } } },
          "401": { "description": "Missing or invalid key", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
          "413": { "description": "File too large" },
          "422": { "description": "Not readable (not_a_pdf, password_required, wrong_password, ocr_failed, no_table, no_movements, unreadable_file)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
          "429": { "description": "More than 60 requests a minute" },
          "503": { "description": "Busy, retry in a few seconds" }
        }
      }
    },
    "/v1/jobs/{id}": {
      "get": {
        "summary": "Result of a scan or photo sent to /v1/convert",
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
        "responses": {
          "200": { "description": "Same answer /v1/convert would have given" },
          "202": { "description": "Still running", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Job" } } } },
          "404": { "description": "Unknown job, or older than 30 minutes" },
          "422": { "description": "The scan could not be read" }
        }
      }
    },
    "/v1/me": { "get": { "summary": "Check a key", "responses": { "200": { "description": "Key and plan" }, "401": { "description": "Invalid key" } } } }
  }
}
