{
  "openapi": "3.1.0",
  "info": {
    "title": "Finviva Autonomous Accounting API",
    "description": "Enterprise-grade REST API and Agentic Function Calling interface for Finviva — AI Financial Operating System for Multi-Entity Startups.",
    "version": "1.0.0",
    "x-api-version": "1.0",
    "x-deprecation-policy": "https://finvivaapp.com/docs/versioning",
    "contact": {
      "name": "Finviva Developer Support",
      "url": "https://finvivaapp.com/docs",
      "email": "support@finvivaapp.com"
    }
  },
  "servers": [
    {
      "url": "https://finvivaapp.com/api/v1",
      "description": "Production API Server (v1)"
    }
  ],
  "paths": {
    "/invoices": {
      "get": {
        "summary": "List all invoices",
        "description": "Retrieve customer invoices with payment status, overdue days, line items, and Stripe payment links.",
        "operationId": "listInvoices",
        "security": [
          {
            "oauth2": ["invoices:read"]
          },
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Filter by status: paid, pending, overdue, draft",
            "schema": {
              "type": "string",
              "enum": ["all", "paid", "pending", "overdue", "draft"]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A paginated list of invoices",
            "headers": {
              "RateLimit-Limit": {
                "schema": { "type": "integer" },
                "description": "The maximum number of requests allowed in the current window"
              },
              "RateLimit-Remaining": {
                "schema": { "type": "integer" },
                "description": "The number of remaining requests in the current window"
              },
              "RateLimit-Reset": {
                "schema": { "type": "integer" },
                "description": "The time in seconds until the current rate limit window resets"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvoiceListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedError"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      },
      "post": {
        "summary": "Create a new invoice",
        "description": "Issue an invoice with automated line items and generate a 1-click Stripe collection link.",
        "operationId": "createInvoice",
        "security": [
          {
            "oauth2": ["invoices:write"]
          },
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateInvoiceRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Invoice created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvoiceItem"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequestError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedError"
          }
        }
      }
    },
    "/accounting/reports/pnl": {
      "get": {
        "summary": "Get Profit & Loss Report",
        "description": "Retrieve real-time GAAP compliant P&L report for the selected LLC entity.",
        "operationId": "getPnLReport",
        "security": [
          {
            "oauth2": ["accounting:read"]
          },
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "startDate",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "format": "date" }
          },
          {
            "name": "endDate",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "format": "date" }
          }
        ],
        "responses": {
          "200": {
            "description": "Profit & Loss statement",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PnLReportResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedError"
          }
        }
      }
    },
    "/ocr/receipts": {
      "post": {
        "summary": "Scan receipt with Multimodal Vision OCR",
        "description": "Process receipt image or PDF in 1.2s and extract line items and Section 162 tax tags.",
        "operationId": "scanReceipt",
        "security": [
          {
            "oauth2": ["receipts:scan"]
          },
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReceiptScanRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Parsed receipt details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReceiptScanResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequestError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedError"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT"
      },
      "oauth2": {
        "type": "oauth2",
        "description": "OAuth 2.0 Authorization Code flow with scoped permissions",
        "flows": {
          "authorizationCode": {
            "authorizationUrl": "https://finvivaapp.com/oauth/authorize",
            "tokenUrl": "https://finvivaapp.com/api/oauth/token",
            "scopes": {
              "accounting:read": "Read-only access to general ledger, P&L, balance sheet, and trial balance",
              "accounting:write": "Write access to post double-entry journal transactions",
              "invoices:read": "Read-only access to invoices and customer payment statuses",
              "invoices:write": "Create, update, and trigger automated AR collection on invoices",
              "receipts:scan": "Submit receipt PDFs and images for automated multimodal OCR parsing"
            }
          }
        }
      }
    },
    "schemas": {
      "ProblemDetails": {
        "type": "object",
        "description": "RFC 9457 compliant error details",
        "required": ["type", "title", "status", "code", "message"],
        "properties": {
          "type": {
            "type": "string",
            "format": "uri",
            "example": "https://finvivaapp.com/docs/errors/UNAUTHORIZED"
          },
          "title": {
            "type": "string",
            "example": "Unauthorized Request"
          },
          "status": {
            "type": "integer",
            "example": 401
          },
          "code": {
            "type": "string",
            "example": "ERR_AUTH_INVALID_TOKEN"
          },
          "message": {
            "type": "string",
            "example": "Provided Bearer token has expired or is invalid."
          },
          "detail": {
            "type": "string",
            "example": "Please authenticate via https://finvivaapp.com/api/oauth/token to receive a new token."
          }
        }
      },
      "InvoiceItem": {
        "type": "object",
        "required": ["id", "invoiceNumber", "customerName", "amount", "status", "dueDate"],
        "properties": {
          "id": { "type": "string", "example": "inv_9981a" },
          "invoiceNumber": { "type": "string", "example": "INV-1089" },
          "customerName": { "type": "string", "example": "Acme Studio LLC" },
          "customerEmail": { "type": "string", "format": "email", "example": "billing@acme.com" },
          "amount": { "type": "number", "example": 4200.00 },
          "currency": { "type": "string", "example": "USD" },
          "status": { "type": "string", "enum": ["paid", "pending", "overdue", "draft"], "example": "overdue" },
          "dueDate": { "type": "string", "format": "date", "example": "2026-08-15" },
          "paymentLink": { "type": "string", "format": "uri", "example": "https://checkout.stripe.com/pay/cs_live_992a" }
        }
      },
      "InvoiceListResponse": {
        "type": "object",
        "required": ["success", "invoices", "totalCount"],
        "properties": {
          "success": { "type": "boolean", "example": true },
          "totalCount": { "type": "integer", "example": 18 },
          "invoices": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/InvoiceItem" }
          }
        }
      },
      "CreateInvoiceRequest": {
        "type": "object",
        "required": ["customerName", "customerEmail", "amount", "dueDate"],
        "properties": {
          "customerName": { "type": "string", "example": "Acme Studio LLC" },
          "customerEmail": { "type": "string", "format": "email", "example": "billing@acme.com" },
          "amount": { "type": "number", "example": 4200.00 },
          "currency": { "type": "string", "default": "USD" },
          "dueDate": { "type": "string", "format": "date", "example": "2026-09-01" },
          "notes": { "type": "string", "example": "August Product Design Services" }
        }
      },
      "PnLReportResponse": {
        "type": "object",
        "required": ["grossRevenue", "totalExpenses", "netIncome", "currency"],
        "properties": {
          "grossRevenue": { "type": "number", "example": 48500.00 },
          "costOfGoodsSold": { "type": "number", "example": 8200.00 },
          "operatingExpenses": { "type": "number", "example": 14300.00 },
          "totalExpenses": { "type": "number", "example": 22500.00 },
          "netIncome": { "type": "number", "example": 26000.00 },
          "currency": { "type": "string", "example": "USD" }
        }
      },
      "ReceiptScanRequest": {
        "type": "object",
        "required": ["fileUrl"],
        "properties": {
          "fileUrl": { "type": "string", "format": "uri", "example": "https://storage.finviva.com/receipts/aws_august.pdf" },
          "autoCategorize": { "type": "boolean", "default": true }
        }
      },
      "ReceiptScanResponse": {
        "type": "object",
        "required": ["vendorName", "totalAmount", "salesTax", "taxCategory", "verified"],
        "properties": {
          "vendorName": { "type": "string", "example": "Amazon Web Services" },
          "subtotal": { "type": "number", "example": 480.00 },
          "salesTax": { "type": "number", "example": 32.40 },
          "totalAmount": { "type": "number", "example": 512.40 },
          "taxCategory": { "type": "string", "example": "Line 18 (Utilities / Cloud Tech Stack)" },
          "verified": { "type": "boolean", "example": true }
        }
      }
    },
    "responses": {
      "BadRequestError": {
        "description": "Invalid payload or schema validation error",
        "content": {
          "application/problem+json": {
            "schema": { "$ref": "#/components/schemas/ProblemDetails" }
          }
        }
      },
      "UnauthorizedError": {
        "description": "Missing or invalid Bearer authentication token",
        "content": {
          "application/problem+json": {
            "schema": { "$ref": "#/components/schemas/ProblemDetails" }
          }
        }
      },
      "RateLimitedError": {
        "description": "Too many requests. Self-throttle using Retry-After header.",
        "headers": {
          "Retry-After": {
            "schema": { "type": "integer" },
            "description": "Seconds to wait before retrying"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": { "$ref": "#/components/schemas/ProblemDetails" }
          }
        }
      },
      "InternalServerError": {
        "description": "Internal server error",
        "content": {
          "application/problem+json": {
            "schema": { "$ref": "#/components/schemas/ProblemDetails" }
          }
        }
      }
    }
  }
}
