{
  "openapi": "3.1.0",
  "info": {
    "title": "Poqet Invoicing & PDF Automation API",
    "version": "1.2.0",
    "description": "B2B API for automated invoice generation, isolated test and live environments, virtual sub-accounts, PDF rendering, and optional live customer email delivery."
  },
  "servers": [{ "url": "https://api.poqet.app", "description": "Production API" }],
  "security": [{ "ApiKeyAuth": [] }, { "BearerAuth": [] }],
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": { "type": "apiKey", "in": "header", "name": "X-Poqet-Key" },
      "BearerAuth": { "type": "http", "scheme": "bearer", "bearerFormat": "pq_live_... or pq_test_..." }
    },
    "parameters": {
      "TenantAccountHeader": {
        "name": "X-Poqet-Account",
        "in": "header",
        "required": false,
        "description": "Public sub-account identifier. Data is isolated beneath the API-key owner.",
        "schema": { "type": "string", "pattern": "^[A-Za-z0-9._~-]{1,128}$" }
      },
      "IdempotencyHeader": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": false,
        "description": "URL-safe retry key retained for 24 hours. Reuse only with the identical request body.",
        "schema": { "type": "string", "pattern": "^[A-Za-z0-9._~-]{1,128}$" }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": ["error"],
        "properties": { "error": { "type": "string" } }
      },
      "BusinessInput": {
        "type": "object",
        "properties": {
          "name": { "type": "string", "maxLength": 200 },
          "businessName": { "type": "string", "maxLength": 200 },
          "email": { "type": "string", "format": "email" },
          "phone": { "type": "string", "maxLength": 50 },
          "address": { "type": "string", "maxLength": 1000 },
          "taxNumber": { "type": "string", "maxLength": 100 },
          "logoUrl": { "type": "string", "description": "Base64 data:image URL; remote URLs are rejected." },
          "invoicePrefix": { "type": "string", "maxLength": 32 },
          "invoicePadding": { "type": "integer", "minimum": 1, "maximum": 12 },
          "initialInvoiceNumber": { "type": "integer", "minimum": 1 }
        }
      },
      "CustomerInput": {
        "type": "object",
        "required": ["name"],
        "properties": {
          "name": { "type": "string" },
          "email": { "type": "string", "format": "email" },
          "phone": { "type": "string" },
          "address": { "type": "string" },
          "gstin": { "type": "string", "description": "Customer tax identifier." }
        }
      },
      "InvoiceItemInput": {
        "type": "object",
        "required": ["name", "unitPrice"],
        "properties": {
          "name": { "type": "string" },
          "description": { "type": "string" },
          "quantity": { "type": "number", "exclusiveMinimum": 0, "default": 1 },
          "unitPrice": { "type": "number", "minimum": 0 },
          "discount": { "type": "number", "minimum": 0, "maximum": 100 },
          "tax": { "type": "number", "minimum": 0, "maximum": 100 },
          "hsnSacCode": { "type": "string" }
        }
      },
      "PaymentDetailsInput": {
        "type": "object",
        "properties": {
          "accountHolderName": { "type": "string" },
          "accountNumber": { "type": "string" },
          "ifscCode": { "type": "string" },
          "bankName": { "type": "string" },
          "branchName": { "type": "string" },
          "upiId": { "type": "string" },
          "upiLinkedNumber": { "type": "string" },
          "iban": { "type": "string" },
          "swiftBic": { "type": "string" },
          "routingNumber": { "type": "string" },
          "accountType": { "type": "string" },
          "qrCodeDataUrl": { "type": "string" },
          "paymentLink": { "type": "string", "format": "uri" },
          "instructions": { "type": "string" }
        }
      },
      "CreateInvoiceRequest": {
        "type": "object",
        "properties": {
          "business": { "$ref": "#/components/schemas/BusinessInput" },
          "customer": { "$ref": "#/components/schemas/CustomerInput" },
          "items": { "type": "array", "minItems": 1, "maxItems": 500, "items": { "$ref": "#/components/schemas/InvoiceItemInput" } },
          "paymentDetails": { "$ref": "#/components/schemas/PaymentDetailsInput" },
          "date": { "type": "string", "format": "date" },
          "dueDate": { "type": "string", "format": "date" },
          "currency": { "type": "string", "pattern": "^[A-Z]{3}$", "default": "USD" },
          "templateId": { "type": "string", "enum": ["clean-minimal", "modern", "standard", "grid", "spreadsheet", "legacy-basic"] },
          "status": { "type": "string", "enum": ["PAID", "PENDING", "DRAFT"], "default": "PAID" },
          "notes": { "type": "string" },
          "terms": { "type": "string" },
          "discount": { "type": "number", "minimum": 0, "maximum": 100, "description": "Document-level percentage." },
          "tax": { "type": "number", "minimum": 0, "maximum": 100, "description": "Document-level percentage." },
          "deliveryCharge": { "type": "number", "minimum": 0 },
          "packagingCharge": { "type": "number", "minimum": 0 },
          "paymentMethod": { "type": "string" },
          "transactionReference": { "type": "string" },
          "autoEmail": { "type": "boolean", "default": false, "description": "Ignored in TEST mode and for DRAFT invoices." }
        },
        "allOf": [
          {
            "if": { "properties": { "status": { "const": "DRAFT" } }, "required": ["status"] },
            "then": {},
            "else": { "required": ["customer", "items"] }
          }
        ]
      },
      "InvoiceItemResponse": {
        "allOf": [
          { "$ref": "#/components/schemas/InvoiceItemInput" },
          { "type": "object", "properties": { "id": { "type": "string" }, "lineTotal": { "type": "number" } } }
        ]
      },
      "InvoiceApiResponse": {
        "type": "object",
        "required": ["id", "status", "currency", "amount", "mode"],
        "properties": {
          "id": { "type": "string" },
          "invoiceNumber": { "type": "string", "readOnly": true },
          "status": { "type": "string", "enum": ["PAID", "PENDING", "PARTIALLY PAID", "DRAFT", "VOID", "CANCELLED"] },
          "date": { "type": "string", "format": "date" },
          "dueDate": { "type": "string", "format": "date" },
          "currency": { "type": "string" },
          "subtotal": { "type": "number" },
          "discount": { "type": "number" },
          "tax": { "type": "number" },
          "deliveryCharge": { "type": "number" },
          "packagingCharge": { "type": "number" },
          "amount": { "type": "number" },
          "paidAmount": { "type": "number" },
          "balanceDue": { "type": "number" },
          "amountInWords": { "type": "string" },
          "notes": { "type": "string" },
          "terms": { "type": "string" },
          "templateId": { "type": "string" },
          "business": { "type": "object", "additionalProperties": true },
          "customer": { "type": "object", "additionalProperties": true },
          "items": { "type": "array", "items": { "$ref": "#/components/schemas/InvoiceItemResponse" } },
          "paymentDetails": { "type": "object", "additionalProperties": true },
          "hostedUrl": { "type": ["string", "null"], "format": "uri" },
          "pdfUrl": { "type": "string", "format": "uri" },
          "emailed": { "type": "boolean" },
          "mode": { "type": "string", "enum": ["LIVE", "TEST"] },
          "createdAt": { "type": "string", "format": "date-time" }
        }
      },
      "InvoicePage": {
        "type": "object",
        "required": ["items", "limit", "total", "hasMore"],
        "properties": {
          "items": { "type": "array", "items": { "$ref": "#/components/schemas/InvoiceApiResponse" } },
          "limit": { "type": "integer" },
          "offset": { "type": "integer", "description": "Present for offset-based requests." },
          "total": { "type": "integer" },
          "hasMore": { "type": "boolean" },
          "nextCursor": { "type": "string", "description": "Pass as cursor on the next request. Omitted on the final page." }
        }
      },
      "CreateSubAccountRequest": {
        "type": "object",
        "properties": {
          "name": { "type": "string", "maxLength": 200 },
          "businessName": { "type": "string", "maxLength": 200 },
          "email": { "type": "string", "format": "email" },
          "phone": { "type": "string", "maxLength": 50 },
          "taxNumber": { "type": "string", "maxLength": 100 },
          "businessAddress": { "type": "string", "maxLength": 1000 },
          "businessLogoUrl": { "type": "string", "description": "Base64 data:image URL." },
          "currency": { "type": "string", "pattern": "^[A-Z]{3}$" },
          "defaultTemplateId": { "type": "string" },
          "invoiceNumberPrefix": { "type": "string", "maxLength": 32 },
          "invoiceNumberFormat": { "type": "string", "description": "Must contain {NUMBER}." },
          "invoiceNumberPadding": { "type": "integer", "minimum": 1, "maximum": 12 },
          "initialInvoiceNumber": { "type": "integer", "minimum": 1 }
        },
        "anyOf": [{ "required": ["name"] }, { "required": ["businessName"] }]
      },
      "UpdateSubAccountRequest": {
        "type": "object",
        "minProperties": 1,
        "properties": {
          "name": { "type": "string", "maxLength": 200 },
          "businessName": { "type": "string", "maxLength": 200 },
          "email": { "type": "string", "format": "email" },
          "phone": { "type": "string", "maxLength": 50 },
          "taxNumber": { "type": "string", "maxLength": 100 },
          "businessAddress": { "type": "string", "maxLength": 1000 },
          "businessLogoUrl": { "type": "string", "description": "Base64 data:image URL." },
          "currency": { "type": "string", "pattern": "^[A-Z]{3}$" },
          "defaultTemplateId": { "type": "string" },
          "invoiceNumberPrefix": { "type": "string", "maxLength": 32 },
          "invoiceNumberFormat": { "type": "string", "description": "Must contain {NUMBER}." },
          "invoiceNumberPadding": { "type": "integer", "minimum": 1, "maximum": 12 },
          "initialInvoiceNumber": { "type": "integer", "minimum": 1, "description": "May move the next sequence forward, but cannot rewind it." }
        }
      },
      "SubAccountResponse": {
        "allOf": [
          { "$ref": "#/components/schemas/CreateSubAccountRequest" },
          {
            "type": "object",
            "required": ["id", "active", "nextInvoiceNumber", "createdAt"],
            "properties": {
              "id": { "type": "string" },
              "active": { "type": "boolean" },
              "nextInvoiceNumber": { "type": "integer" },
              "createdAt": { "type": "string", "format": "date-time" },
              "updatedAt": { "type": "string", "format": "date-time" }
            }
          }
        ]
      }
    },
    "responses": {
      "BadRequest": { "description": "Invalid request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "Unauthorized": { "description": "Missing or invalid API key", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "Forbidden": { "description": "Insufficient scope or mode restriction", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "NotFound": { "description": "Resource not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
    }
  },
  "paths": {
    "/api/v1/invoices": {
      "post": {
        "summary": "Create an invoice",
        "parameters": [{ "$ref": "#/components/parameters/TenantAccountHeader" }, { "$ref": "#/components/parameters/IdempotencyHeader" }],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateInvoiceRequest" } } } },
        "responses": {
          "201": { "description": "Invoice created", "headers": { "X-Idempotent-Replayed": { "schema": { "type": "boolean" } } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/InvoiceApiResponse" } } } },
          "200": { "description": "Existing idempotent result replayed", "headers": { "X-Idempotent-Replayed": { "schema": { "type": "boolean", "const": true } } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/InvoiceApiResponse" } } } },
          "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }
        }
      },
      "get": {
        "summary": "List invoices",
        "parameters": [
          { "$ref": "#/components/parameters/TenantAccountHeader" },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 200, "default": 50 } },
          { "name": "offset", "in": "query", "description": "Compatibility pagination. Prefer cursor for large result sets.", "schema": { "type": "integer", "minimum": 0, "default": 0 } },
          { "name": "cursor", "in": "query", "description": "Opaque nextCursor from the previous response. When present, offset is ignored.", "schema": { "type": "string" } }
        ],
        "responses": { "200": { "description": "Paginated invoices", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/InvoicePage" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" } }
      }
    },
    "/api/v1/invoices/generate-pdf": {
      "post": {
        "summary": "Generate a PDF without persistence",
        "description": "Does not create invoice, customer, sequence, share, email, or sub-account records.",
        "parameters": [{ "$ref": "#/components/parameters/TenantAccountHeader" }],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateInvoiceRequest" } } } },
        "responses": { "200": { "description": "PDF bytes", "content": { "application/pdf": { "schema": { "type": "string", "contentEncoding": "base64" } } } }, "400": { "$ref": "#/components/responses/BadRequest" } }
      }
    },
    "/api/v1/invoices/{id}": {
      "get": {
        "summary": "Get an invoice",
        "parameters": [{ "$ref": "#/components/parameters/TenantAccountHeader" }, { "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": { "200": { "description": "Invoice", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/InvoiceApiResponse" } } } }, "404": { "$ref": "#/components/responses/NotFound" } }
      }
    },
    "/api/v1/invoices/{id}/pdf": {
      "get": {
        "summary": "Download an invoice PDF",
        "parameters": [{ "$ref": "#/components/parameters/TenantAccountHeader" }, { "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "template", "in": "query", "schema": { "type": "string" } }],
        "responses": { "200": { "description": "PDF bytes", "content": { "application/pdf": { "schema": { "type": "string", "contentEncoding": "base64" } } } }, "404": { "$ref": "#/components/responses/NotFound" } }
      }
    },
    "/api/v1/invoices/{id}/void": {
      "post": {
        "summary": "Void an invoice",
        "parameters": [{ "$ref": "#/components/parameters/TenantAccountHeader" }, { "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "reason", "in": "query", "schema": { "type": "string" } }],
        "responses": { "200": { "description": "Voided invoice", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/InvoiceApiResponse" } } } }, "404": { "$ref": "#/components/responses/NotFound" } }
      }
    },
    "/api/v1/sub-accounts": {
      "post": {
        "summary": "Provision a live sub-account",
        "description": "Available to live keys only.",
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateSubAccountRequest" } } } },
        "responses": { "201": { "description": "Sub-account created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SubAccountResponse" } } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "403": { "$ref": "#/components/responses/Forbidden" } }
      },
      "get": {
        "summary": "List active live sub-accounts",
        "responses": { "200": { "description": "Sub-accounts", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/SubAccountResponse" } } } } }, "403": { "$ref": "#/components/responses/Forbidden" } }
      }
    },
    "/api/v1/sub-accounts/{id}": {
      "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }],
      "get": { "summary": "Get a live sub-account", "responses": { "200": { "description": "Sub-account", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SubAccountResponse" } } } }, "404": { "$ref": "#/components/responses/NotFound" } } },
      "patch": { "summary": "Update a live sub-account", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateSubAccountRequest" } } } }, "responses": { "200": { "description": "Updated sub-account", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SubAccountResponse" } } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "404": { "$ref": "#/components/responses/NotFound" } } },
      "delete": { "summary": "Deactivate a live sub-account", "responses": { "200": { "description": "Deactivation confirmation", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string" }, "id": { "type": "string" } } } } } }, "404": { "$ref": "#/components/responses/NotFound" } } }
    }
  }
}
