{
    "openapi": "3.1.0",
    "info": {
        "title": "BankSheet Pro Document Extraction API",
        "version": "1.0.0",
        "description": "Submit a bank statement or invoice PDF and receive structured JSON, including a machine-readable reconciliation verdict. Processing runs entirely on local libraries; documents are not sent to any third-party service.",
        "contact": {
            "url": "https://banksheet.pro/api-docs"
        }
    },
    "servers": [
        {
            "url": "https://banksheet.pro/api/v1"
        }
    ],
    "security": [
        {
            "bearerAuth": []
        }
    ],
    "components": {
        "securitySchemes": {
            "bearerAuth": {
                "type": "http",
                "scheme": "bearer",
                "description": "Your API key, e.g. sk_live_\u2026 Create one in Settings \u2192 API keys."
            }
        },
        "schemas": {
            "Error": {
                "type": "object",
                "properties": {
                    "error": {
                        "type": "object",
                        "required": [
                            "code",
                            "status",
                            "title"
                        ],
                        "properties": {
                            "code": {
                                "type": "string",
                                "enum": [
                                    "unauthorized",
                                    "invalid_api_key",
                                    "workspace_unavailable",
                                    "insufficient_scope",
                                    "trial_exhausted",
                                    "api_not_included",
                                    "quota_exceeded",
                                    "file_required",
                                    "invalid_file",
                                    "file_too_large",
                                    "too_many_pages",
                                    "unsupported_type",
                                    "invalid_url",
                                    "invalid_request",
                                    "no_text_found",
                                    "no_transactions_detected",
                                    "extraction_failed",
                                    "idempotency_conflict",
                                    "not_found",
                                    "result_expired",
                                    "rate_limited",
                                    "server_error",
                                    "service_unavailable"
                                ]
                            },
                            "status": {
                                "type": "integer"
                            },
                            "title": {
                                "type": "string"
                            },
                            "detail": {
                                "type": "string"
                            },
                            "doc_url": {
                                "type": "string",
                                "format": "uri"
                            }
                        }
                    }
                }
            },
            "Reconciliation": {
                "type": "object",
                "description": "Whether opening balance + credits \u2212 debits equals the closing balance.",
                "properties": {
                    "status": {
                        "type": "string",
                        "enum": [
                            "reconciled",
                            "partial",
                            "unreconciled",
                            "unknown"
                        ]
                    },
                    "statement_balanced": {
                        "type": "boolean"
                    },
                    "opening_balance": {
                        "type": [
                            "number",
                            "null"
                        ]
                    },
                    "closing_balance": {
                        "type": [
                            "number",
                            "null"
                        ]
                    },
                    "expected_net_change": {
                        "type": [
                            "number",
                            "null"
                        ]
                    },
                    "computed_net_change": {
                        "type": [
                            "number",
                            "null"
                        ]
                    },
                    "discrepancy": {
                        "type": [
                            "number",
                            "null"
                        ]
                    },
                    "rows_checked": {
                        "type": "integer"
                    },
                    "rows_matched": {
                        "type": "integer"
                    },
                    "rows_flagged": {
                        "type": "integer"
                    }
                }
            },
            "Transaction": {
                "type": "object",
                "properties": {
                    "row": {
                        "type": "integer"
                    },
                    "date": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date"
                    },
                    "value_date": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date"
                    },
                    "description": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "reference": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "debit": {
                        "type": [
                            "number",
                            "null"
                        ]
                    },
                    "credit": {
                        "type": [
                            "number",
                            "null"
                        ]
                    },
                    "amount": {
                        "type": [
                            "number",
                            "null"
                        ],
                        "description": "Signed: negative for debits."
                    },
                    "balance": {
                        "type": [
                            "number",
                            "null"
                        ]
                    },
                    "currency": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "counterparty": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "category": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "page": {
                        "type": "integer"
                    },
                    "confidence": {
                        "type": "string",
                        "enum": [
                            "certain",
                            "high",
                            "medium",
                            "low"
                        ]
                    },
                    "needs_review": {
                        "type": "boolean",
                        "description": "Below the confidence threshold. Surfaced, never filtered \u2014 you choose the threshold."
                    },
                    "warnings": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        }
                    }
                }
            },
            "Document": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string"
                    },
                    "object": {
                        "type": "string"
                    },
                    "type": {
                        "type": "string",
                        "enum": [
                            "bank_statement",
                            "invoice"
                        ]
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "queued",
                            "processing",
                            "succeeded",
                            "failed"
                        ]
                    },
                    "filename": {
                        "type": "string"
                    },
                    "engine": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "pages": {
                        "type": "integer"
                    },
                    "confidence": {
                        "type": "string",
                        "enum": [
                            "certain",
                            "high",
                            "medium",
                            "low"
                        ]
                    },
                    "document": {
                        "type": "object",
                        "properties": {
                            "bank_name": {
                                "type": "object",
                                "description": "Always present. value is null when the field could not be read.",
                                "properties": {
                                    "value": {
                                        "type": [
                                            "string",
                                            "null"
                                        ]
                                    },
                                    "confidence": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "enum": [
                                            "certain",
                                            "high",
                                            "medium",
                                            "low",
                                            null
                                        ]
                                    }
                                }
                            },
                            "account_holder": {
                                "type": "object",
                                "description": "Always present. value is null when the field could not be read.",
                                "properties": {
                                    "value": {
                                        "type": [
                                            "string",
                                            "null"
                                        ]
                                    },
                                    "confidence": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "enum": [
                                            "certain",
                                            "high",
                                            "medium",
                                            "low",
                                            null
                                        ]
                                    }
                                }
                            },
                            "account_number": {
                                "type": "object",
                                "description": "Always present. value is null when the field could not be read.",
                                "properties": {
                                    "value": {
                                        "type": [
                                            "string",
                                            "null"
                                        ]
                                    },
                                    "confidence": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "enum": [
                                            "certain",
                                            "high",
                                            "medium",
                                            "low",
                                            null
                                        ]
                                    }
                                }
                            },
                            "iban": {
                                "type": "object",
                                "description": "Always present. value is null when the field could not be read.",
                                "properties": {
                                    "value": {
                                        "type": [
                                            "string",
                                            "null"
                                        ]
                                    },
                                    "confidence": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "enum": [
                                            "certain",
                                            "high",
                                            "medium",
                                            "low",
                                            null
                                        ]
                                    }
                                }
                            },
                            "bic": {
                                "type": "object",
                                "description": "Always present. value is null when the field could not be read.",
                                "properties": {
                                    "value": {
                                        "type": [
                                            "string",
                                            "null"
                                        ]
                                    },
                                    "confidence": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "enum": [
                                            "certain",
                                            "high",
                                            "medium",
                                            "low",
                                            null
                                        ]
                                    }
                                }
                            },
                            "currency": {
                                "type": "object",
                                "description": "Always present. value is null when the field could not be read.",
                                "properties": {
                                    "value": {
                                        "type": [
                                            "string",
                                            "null"
                                        ]
                                    },
                                    "confidence": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "enum": [
                                            "certain",
                                            "high",
                                            "medium",
                                            "low",
                                            null
                                        ]
                                    }
                                }
                            },
                            "period_start": {
                                "type": "object",
                                "description": "Always present. value is null when the field could not be read.",
                                "properties": {
                                    "value": {
                                        "type": [
                                            "string",
                                            "null"
                                        ]
                                    },
                                    "confidence": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "enum": [
                                            "certain",
                                            "high",
                                            "medium",
                                            "low",
                                            null
                                        ]
                                    }
                                }
                            },
                            "period_end": {
                                "type": "object",
                                "description": "Always present. value is null when the field could not be read.",
                                "properties": {
                                    "value": {
                                        "type": [
                                            "string",
                                            "null"
                                        ]
                                    },
                                    "confidence": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "enum": [
                                            "certain",
                                            "high",
                                            "medium",
                                            "low",
                                            null
                                        ]
                                    }
                                }
                            },
                            "opening_balance": {
                                "type": "object",
                                "description": "Always present. value is null when the field could not be read.",
                                "properties": {
                                    "value": {
                                        "type": [
                                            "number",
                                            "null"
                                        ]
                                    },
                                    "confidence": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "enum": [
                                            "certain",
                                            "high",
                                            "medium",
                                            "low",
                                            null
                                        ]
                                    }
                                }
                            },
                            "closing_balance": {
                                "type": "object",
                                "description": "Always present. value is null when the field could not be read.",
                                "properties": {
                                    "value": {
                                        "type": [
                                            "number",
                                            "null"
                                        ]
                                    },
                                    "confidence": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "enum": [
                                            "certain",
                                            "high",
                                            "medium",
                                            "low",
                                            null
                                        ]
                                    }
                                }
                            }
                        }
                    },
                    "reconciliation": {
                        "$ref": "#/components/schemas/Reconciliation"
                    },
                    "totals": {
                        "type": "object",
                        "properties": {
                            "transaction_count": {
                                "type": "integer"
                            },
                            "total_debits": {
                                "type": [
                                    "number",
                                    "null"
                                ]
                            },
                            "total_credits": {
                                "type": [
                                    "number",
                                    "null"
                                ]
                            },
                            "net_change": {
                                "type": [
                                    "number",
                                    "null"
                                ]
                            }
                        }
                    },
                    "transactions": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/Transaction"
                        }
                    },
                    "warnings": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        }
                    }
                }
            }
        }
    },
    "paths": {
        "/documents": {
            "post": {
                "summary": "Submit a document for extraction",
                "description": "Returns 202 immediately with a job handle. Poll the polling_url or register a webhook. Send an Idempotency-Key so a client retry through a timeout replays the original job instead of billing twice.",
                "parameters": [
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "maxLength": 255
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "file": {
                                        "type": "string",
                                        "format": "binary"
                                    },
                                    "url": {
                                        "type": "string",
                                        "format": "uri",
                                        "description": "Public https URL to fetch instead of uploading."
                                    },
                                    "file_base64": {
                                        "type": "string"
                                    },
                                    "type": {
                                        "type": "string",
                                        "enum": [
                                            "bank_statement",
                                            "invoice"
                                        ],
                                        "default": "bank_statement"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "202": {
                        "description": "Accepted and queued",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Document"
                                }
                            }
                        }
                    },
                    "200": {
                        "description": "Idempotent replay of an earlier submission"
                    },
                    "402": {
                        "description": "Trial used or plan quota exhausted",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Idempotency key reused with different parameters"
                    },
                    "422": {
                        "description": "Invalid document",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limited"
                    }
                }
            },
            "get": {
                "summary": "List recent documents",
                "responses": {
                    "200": {
                        "description": "A list of documents"
                    }
                }
            }
        },
        "/documents/{id}": {
            "get": {
                "summary": "Fetch a job or its result",
                "description": "While processing, responds with status and a Retry-After header. Once succeeded, the body is immutable.",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Job status or final result",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Document"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "No such document for this workspace"
                    },
                    "410": {
                        "description": "Result expired and was deleted"
                    }
                }
            },
            "delete": {
                "summary": "Permanently delete a document and its result",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Deleted"
                    }
                }
            }
        },
        "/jobs/{id}": {
            "get": {
                "summary": "Alias of GET /documents/{id}",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Job status or final result"
                    }
                }
            }
        },
        "/usage": {
            "get": {
                "summary": "Remaining trial and plan allowance",
                "responses": {
                    "200": {
                        "description": "Usage snapshot"
                    }
                }
            }
        },
        "/webhooks": {
            "get": {
                "summary": "Show the registered callback",
                "responses": {
                    "200": {
                        "description": "Webhook configuration"
                    }
                }
            },
            "post": {
                "summary": "Register a callback URL",
                "description": "The signing secret is returned once. Every delivery carries X-BankSheet-Signature: t=<unix>,v1=<hmac_sha256 of \"t.body\">.",
                "responses": {
                    "201": {
                        "description": "Registered, with the signing secret"
                    }
                }
            },
            "delete": {
                "summary": "Remove the callback",
                "responses": {
                    "200": {
                        "description": "Deleted"
                    }
                }
            }
        }
    }
}